Search in sources :

Example 6 with ViewResolve

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;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) InvalidPathException(java.nio.file.InvalidPathException) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with ViewResolve

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;
}
Also used : ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) PhpIndex(com.jetbrains.php.PhpIndex) InvalidPathException(java.nio.file.InvalidPathException) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with 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;
        }
    };
}
Also used : PhpFile(com.jetbrains.php.lang.psi.PhpFile) PhpElementVisitor(com.jetbrains.php.lang.psi.visitors.PhpElementVisitor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) PsiReference(com.intellij.psi.PsiReference) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) LinkedHashMap(java.util.LinkedHashMap) Project(com.intellij.openapi.project.Project) PhpDocVariable(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with ViewResolve

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]);
}
Also used : Project(com.intellij.openapi.project.Project) ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) PsiFile(com.intellij.psi.PsiFile) HashSet(java.util.HashSet) ViewInfo(com.nvlad.yii2support.views.entities.ViewInfo) NotNull(org.jetbrains.annotations.NotNull)

Example 10 with ViewResolve

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]));
        }
    };
}
Also used : PhpElementVisitor(com.jetbrains.php.lang.psi.visitors.PhpElementVisitor) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) ArrayCreationExpression(com.jetbrains.php.lang.psi.elements.ArrayCreationExpression) ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) ViewInfo(com.nvlad.yii2support.views.entities.ViewInfo) Project(com.intellij.openapi.project.Project) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) PsiElement(com.intellij.psi.PsiElement) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ViewResolve (com.nvlad.yii2support.views.entities.ViewResolve)11 NotNull (org.jetbrains.annotations.NotNull)8 Project (com.intellij.openapi.project.Project)6 ViewInfo (com.nvlad.yii2support.views.entities.ViewInfo)5 PsiElement (com.intellij.psi.PsiElement)4 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)4 PhpElementVisitor (com.jetbrains.php.lang.psi.visitors.PhpElementVisitor)4 InvalidPathException (java.nio.file.InvalidPathException)4 HashSet (java.util.HashSet)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)2 PsiFile (com.intellij.psi.PsiFile)2 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)2 Nullable (org.jetbrains.annotations.Nullable)2 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)1 PsiManager (com.intellij.psi.PsiManager)1 PsiReference (com.intellij.psi.PsiReference)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 FileBasedIndex (com.intellij.util.indexing.FileBasedIndex)1 PhpIndex (com.jetbrains.php.PhpIndex)1 PhpDocVariable (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable)1