use of com.nvlad.yii2support.views.entities.ViewResolve in project yii2support by nvlad.
the class ViewUtil method resolveViewFromView.
@NotNull
private static ViewResolve resolveViewFromView(PsiElement element, String value) {
VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
if (virtualFile == null) {
virtualFile = element.getContainingFile().getOriginalFile().getVirtualFile();
}
ViewResolve result = resolveView(virtualFile, element.getProject());
if (result == null) {
throw new InvalidPathException(virtualFile.getPath(), "Not resolved");
}
result.from = ViewResolveFrom.View;
if (value.startsWith("/")) {
int viewsPathPartPosition = result.key.lastIndexOf("/views/");
if (viewsPathPartPosition == -1) {
throw new InvalidPathException(result.key, "Not found \"views\" directory");
}
result.key = result.key.substring(0, viewsPathPartPosition + 6) + value;
return result;
}
int lastSlashPosition = result.key.lastIndexOf('/');
result.key = normalizePath(result.key.substring(0, lastSlashPosition + 1) + value);
return result;
}
use of com.nvlad.yii2support.views.entities.ViewResolve in project yii2support by nvlad.
the class ViewUtil method resolveView.
@Nullable
public static ViewResolve resolveView(PsiElement element) {
String value = PhpUtil.getValue(element);
if (value.startsWith("@")) {
ViewResolve resolve = new ViewResolve(value);
resolve.application = YiiApplicationUtils.getApplicationName(element.getContainingFile());
return resolve;
}
if (value.startsWith("//")) {
ViewResolve resolve = new ViewResolve("@app/views" + value.substring(1));
resolve.application = YiiApplicationUtils.getApplicationName(element.getContainingFile());
return resolve;
}
final MethodReference method = PsiTreeUtil.getParentOfType(element, MethodReference.class);
if (method == null || method.getClassReference() == null) {
return null;
}
PhpClass callerClass = ClassUtils.getPhpClassByCallChain(method);
if (callerClass == null) {
return null;
}
final PhpIndex phpIndex = PhpIndex.getInstance(element.getProject());
final ViewResolve viewResolve;
try {
if (callerClass.getName().endsWith("Controller") && ClassUtils.isClassInheritsOrEqual(callerClass, "\\yii\\base\\Controller", phpIndex)) {
viewResolve = resolveViewFromController(callerClass, value);
} else if (ClassUtils.isClassInheritsOrEqual(callerClass, "\\yii\\base\\View", phpIndex)) {
viewResolve = resolveViewFromView(element, value);
} else if (ClassUtils.isClassInheritsOrEqual(callerClass, "\\yii\\base\\Widget", phpIndex)) {
viewResolve = resolveViewFromWidget(callerClass, value);
} else {
return null;
}
} catch (InvalidPathException e) {
return null;
}
viewResolve.application = YiiApplicationUtils.getApplicationName(element.getContainingFile());
return viewResolve;
}
use of com.nvlad.yii2support.views.entities.ViewResolve in project yii2support by nvlad.
the class ViewMissedPhpDocInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) {
return new PhpElementVisitor() {
@Override
public void visitPhpFile(PhpFile PhpFile) {
Project project = PhpFile.getProject();
ViewResolve resolve = ViewUtil.resolveView(PhpFile.getVirtualFile(), project);
if (resolve == null) {
return;
}
Map<String, String> params = getVariables(PhpFile);
Map<String, String> declaredVariables = new HashMap<>();
Collection<PhpDocVariable> variableCollection = PsiTreeUtil.findChildrenOfType(PhpFile, PhpDocVariable.class);
for (PhpDocVariable variable : variableCollection) {
declaredVariables.put(variable.getName(), variable.getType().toString());
}
Map<String, String> missedVariables = new HashMap<>();
for (String variableName : params.keySet()) {
if (!declaredVariables.containsKey(variableName)) {
missedVariables.put(variableName, params.get(variableName));
}
}
if (missedVariables.isEmpty()) {
return;
}
String problemDescription = "Missed View variable declaration.";
ViewMissedPhpDocLocalQuickFix quickFix = new ViewMissedPhpDocLocalQuickFix(PhpFile, missedVariables);
problemsHolder.registerProblem(PhpFile, problemDescription, quickFix);
}
private Map<String, String> getVariables(PhpFile phpFile) {
Collection<PsiReference> references = ReferencesSearch.search(phpFile).findAll();
Map<String, String> result = new HashMap<>();
Map<String, PhpType> viewArgumentCollection = new LinkedHashMap<>();
for (PsiReference reference : references) {
MethodReference methodReference = PsiTreeUtil.getParentOfType(reference.getElement(), MethodReference.class);
if (methodReference == null) {
continue;
}
Map<String, PhpType> params = RenderUtil.getViewArguments(methodReference);
for (Map.Entry<String, PhpType> entry : params.entrySet()) {
if (viewArgumentCollection.containsKey(entry.getKey())) {
PhpType.PhpTypeBuilder typeBuilder = new PhpType.PhpTypeBuilder();
typeBuilder.add(viewArgumentCollection.get(entry.getKey()));
typeBuilder.add(entry.getValue());
viewArgumentCollection.replace(entry.getKey(), typeBuilder.build());
} else {
viewArgumentCollection.put(entry.getKey(), entry.getValue());
}
}
}
for (String key : viewArgumentCollection.keySet()) {
result.put(key, viewArgumentCollection.get(key).toString());
}
return result;
}
};
}
use of com.nvlad.yii2support.views.entities.ViewResolve in project yii2support by nvlad.
the class PsiReferenceProvider method getReferencesByElement.
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) {
Set<PsiReference> references = new HashSet<>();
final ViewResolve resolve = ViewUtil.resolveView(psiElement);
if (resolve != null) {
Project project = psiElement.getProject();
String key = resolve.key;
if (Files.getFileExtension(key).isEmpty()) {
key = key + '.' + Yii2SupportSettings.getInstance(psiElement.getProject()).defaultViewExtension;
}
final Collection<ViewInfo> views = FileBasedIndex.getInstance().getValues(ViewFileIndex.identity, key, GlobalSearchScope.projectScope(project));
if (views.size() > 0) {
boolean localViewSearch = false;
if (resolve.from == ViewResolveFrom.View) {
final String value = PhpUtil.getValue(psiElement);
localViewSearch = !value.startsWith("@") && !value.startsWith("//");
}
for (ViewInfo view : views) {
if (!resolve.application.equals(view.application)) {
continue;
}
if (localViewSearch && !resolve.theme.equals(view.theme)) {
continue;
}
PsiFile file = PsiManager.getInstance(project).findFile(view.getVirtualFile());
if (file != null) {
references.add(new PsiReference(psiElement, file));
}
}
}
}
return references.toArray(new PsiReference[0]);
}
use of com.nvlad.yii2support.views.entities.ViewResolve in project yii2support by nvlad.
the class RequireParameterInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) {
return new PhpElementVisitor() {
@Override
public void visitPhpMethodReference(MethodReference reference) {
if (!ViewUtil.isValidRenderMethod(reference)) {
return;
}
final String name = reference.getName();
if (name == null || !ArrayUtil.contains(name, ViewUtil.renderMethods)) {
return;
}
final PsiElement[] renderParameters = reference.getParameters();
if (renderParameters.length == 0 || !(renderParameters[0] instanceof StringLiteralExpression)) {
return;
}
final ViewResolve resolve = ViewUtil.resolveView(renderParameters[0]);
if (resolve == null) {
return;
}
String key = resolve.key;
if (Files.getFileExtension(key).isEmpty()) {
key = key + '.' + Yii2SupportSettings.getInstance(reference.getProject()).defaultViewExtension;
}
final Project project = reference.getProject();
final Collection<ViewInfo> views = FileBasedIndex.getInstance().getValues(ViewFileIndex.identity, key, GlobalSearchScope.projectScope(project));
final String application = YiiApplicationUtils.getApplicationName(reference.getContainingFile());
views.removeIf(viewInfo -> !application.equals(viewInfo.application));
if (views.size() == 0) {
return;
}
final Collection<String> viewParameters = new HashSet<>();
for (ViewInfo view : views) {
viewParameters.addAll(view.parameters);
}
if (viewParameters.size() == 0) {
return;
}
final Collection<String> existKeys;
if (renderParameters.length > 1) {
if (renderParameters[1] instanceof ArrayCreationExpression) {
existKeys = PhpUtil.getArrayKeys((ArrayCreationExpression) renderParameters[1]);
} else if (renderParameters[1] instanceof FunctionReference) {
FunctionReference function = (FunctionReference) renderParameters[1];
if (function.getName() != null && function.getName().equals("compact")) {
existKeys = new HashSet<>();
for (PsiElement element : function.getParameters()) {
if (element instanceof StringLiteralExpression) {
existKeys.add(((StringLiteralExpression) element).getContents());
}
}
} else {
return;
}
} else {
return;
}
} else {
existKeys = new HashSet<>();
}
viewParameters.removeIf(existKeys::contains);
if (viewParameters.size() == 0) {
return;
}
String description = "View " + renderParameters[0].getText() + " require ";
final Iterator<String> parameterIterator = viewParameters.iterator();
if (!isOnTheFly) {
while (parameterIterator.hasNext()) {
final String parameter = parameterIterator.next();
final String problemDescription = description + "\"" + parameter + "\" parameter.";
problemsHolder.registerProblem(reference, problemDescription, new RequireParameterLocalQuickFix(parameter));
}
return;
}
final Collection<LocalQuickFix> fixes = new HashSet<>();
if (viewParameters.size() > 1) {
fixes.add(new RequireParameterLocalQuickFix(viewParameters.toArray(new String[0])));
StringBuilder parameterString = new StringBuilder();
String parameter = parameterIterator.next();
while (parameterIterator.hasNext()) {
if (parameterString.length() > 0) {
parameterString.append(", ");
}
parameterString.append("\"").append(parameter).append("\"");
fixes.add(new RequireParameterLocalQuickFix(parameter));
parameter = parameterIterator.next();
}
parameterString.append(" and \"").append(parameter).append("\" parameters.");
description += parameterString.toString();
fixes.add(new RequireParameterLocalQuickFix(parameter));
} else {
String parameter = parameterIterator.next();
description += "\"" + parameter + "\" parameter.";
fixes.add(new RequireParameterLocalQuickFix(parameter));
}
problemsHolder.registerProblem(reference, description, fixes.toArray(new LocalQuickFix[0]));
}
};
}
Aggregations