Search in sources :

Example 6 with PhpFile

use of com.jetbrains.php.lang.psi.PhpFile in project phpinspectionsea by kalessil.

the class SwitchContinuationInLoopInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpContinue(@NotNull PhpContinue continueStatement) {
            /* check if continue already defined with desired level */
            if (null != continueStatement.getFirstPsiChild()) {
                return;
            }
            boolean isSwitch = false;
            PsiElement objParent = continueStatement.getParent();
            while (null != objParent) {
                /* reached file or callable */
                if (objParent instanceof PhpFile || objParent instanceof Function) {
                    return;
                }
                /* check if should operate on loop-switch-continue analysis */
                if (!isSwitch && objParent instanceof PhpSwitch) {
                    isSwitch = true;
                }
                /* when met a loop, complete analysis */
                if (OpenapiTypesUtil.isLoop(objParent)) {
                    if (isSwitch) {
                        holder.registerProblem(continueStatement, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.GENERIC_ERROR, new UseContinue2LocalFix());
                    }
                    return;
                }
                objParent = objParent.getParent();
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) PhpFile(com.jetbrains.php.lang.psi.PhpFile) PhpContinue(com.jetbrains.php.lang.psi.elements.PhpContinue) PhpSwitch(com.jetbrains.php.lang.psi.elements.PhpSwitch) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with PhpFile

use of com.jetbrains.php.lang.psi.PhpFile in project phpinspectionsea by kalessil.

the class ClassConstantUsageCorrectnessInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpClassConstantReference(@NotNull ClassConstantReference constantReference) {
            final String constantName = constantReference.getName();
            if (constantName != null && constantName.equals("class")) {
                final PsiElement reference = constantReference.getClassReference();
                if (reference instanceof ClassReference) {
                    final ClassReference clazz = (ClassReference) reference;
                    final String referencedQn = reference.getText();
                    final PsiElement resolved = validReferences.contains(referencedQn) ? null : OpenapiResolveUtil.resolveReference(clazz);
                    if (resolved instanceof PhpClass) {
                        /* the resolved class will accumulate case issue in its FQN */
                        final List<String> variants = this.getVariants(clazz, (PhpClass) resolved);
                        if (!variants.isEmpty()) {
                            if (variants.stream().noneMatch(referencedQn::equals)) {
                                holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(message));
                            }
                            variants.clear();
                        }
                    }
                }
            }
        }

        @NotNull
        private List<String> getVariants(@NotNull ClassReference reference, @NotNull PhpClass clazz) {
            final List<String> result = new ArrayList<>();
            final String referenceText = reference.getText();
            final String referenceTextLowercase = referenceText.toLowerCase();
            if (referenceText.startsWith("\\")) {
                /* FQN specified, resolve as we might have case issues there */
                final Project project = holder.getProject();
                final Collection<PhpClass> resolved = PhpIndex.getInstance(project).getClassesByFQN(referenceText);
                if (!resolved.isEmpty()) {
                    result.add(resolved.iterator().next().getFQN());
                }
            } else {
                PhpNamespace namespace = null;
                PsiElement current = reference.getParent();
                while (current != null && !(current instanceof PsiFile)) {
                    if (current instanceof PhpNamespace) {
                        namespace = (PhpNamespace) current;
                        break;
                    }
                    current = current.getParent();
                }
                final String classFqn = clazz.getFQN();
                if (referenceText.contains("\\")) {
                    /* RQN specified, check if resolved class in the same NS */
                    final String NsFqn = namespace == null ? null : namespace.getFQN();
                    if (NsFqn != null && !NsFqn.equals("\\")) {
                        final String classFqnLowercase = classFqn.toLowerCase();
                        if (classFqnLowercase.startsWith(NsFqn.toLowerCase()) || classFqnLowercase.endsWith('\\' + referenceTextLowercase)) {
                            result.add(classFqn.substring(classFqn.length() - referenceText.length()));
                        }
                    }
                    /* RQN specified, check if resolved class in aliased NS */
                    final List<PhpUse> uses = new ArrayList<>();
                    if (namespace != null) {
                        final GroupStatement body = namespace.getStatements();
                        if (body != null) {
                            Arrays.stream(body.getStatements()).filter(statement -> statement instanceof PhpUseList).forEach(statement -> Collections.addAll(uses, ((PhpUseList) statement).getDeclarations()));
                        }
                        for (final PhpUse use : uses) {
                            final String alias = use.getAliasName();
                            if (alias != null && referenceTextLowercase.startsWith(alias.toLowerCase())) {
                                final PhpReference targetReference = use.getTargetReference();
                                if (targetReference != null) {
                                    result.add(clazz.getFQN().replace(targetReference.getText(), alias).replaceAll("^\\\\", ""));
                                }
                            }
                        }
                    }
                    uses.clear();
                } else {
                    final List<PhpUse> uses = new ArrayList<>();
                    if (namespace != null) {
                        /* find imports inside know namespace */
                        final GroupStatement body = namespace.getStatements();
                        if (body != null) {
                            Arrays.stream(body.getStatements()).filter(statement -> statement instanceof PhpUseList).forEach(statement -> Collections.addAll(uses, ((PhpUseList) statement).getDeclarations()));
                        }
                    } else {
                        final PsiFile file = reference.getContainingFile();
                        if (file instanceof PhpFile) {
                            /* find imports inside a file without namespace */
                            ((PhpFile) file).getTopLevelDefs().values().stream().filter(definition -> definition instanceof PhpUse).forEach(definition -> uses.add((PhpUse) definition));
                        } else {
                            /* fallback, the most greedy strategy */
                            uses.addAll(PsiTreeUtil.findChildrenOfType(current, PhpUse.class));
                        }
                    }
                    /* imports (incl. aliases) */
                    for (final PhpUse use : uses) {
                        if (use.getFQN().equalsIgnoreCase(classFqn)) {
                            final String alias = use.getAliasName();
                            final PsiElement what = use.getFirstChild();
                            if (alias != null) {
                                /* alias as it is */
                                result.add(alias);
                            } else if (what instanceof ClassReference) {
                                /* resolve the imported class, as its the source for correct naming */
                                final PsiElement resolved = OpenapiResolveUtil.resolveReference((ClassReference) what);
                                if (resolved instanceof PhpClass) {
                                    final PhpClass resolvedImport = (PhpClass) resolved;
                                    final boolean importPrecise = resolvedImport.getFQN().endsWith(what.getText());
                                    if (!importPrecise || !resolvedImport.getName().equals(referenceText)) {
                                        result.add(resolvedImport.getFQN());
                                    }
                                }
                            }
                        } else {
                            final String alias = use.getAliasName();
                            if (alias != null && alias.equalsIgnoreCase(referenceText)) {
                                result.add(alias);
                            }
                        }
                    }
                    uses.clear();
                }
            }
            return result;
        }
    };
}
Also used : java.util(java.util) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) com.jetbrains.php.lang.psi.elements(com.jetbrains.php.lang.psi.elements) PhpIndex(com.jetbrains.php.PhpIndex) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PhpFile(com.jetbrains.php.lang.psi.PhpFile) OpenapiResolveUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) Project(com.intellij.openapi.project.Project) PsiFile(com.intellij.psi.PsiFile) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) PhpFile(com.jetbrains.php.lang.psi.PhpFile) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Project(com.intellij.openapi.project.Project) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with PhpFile

use of com.jetbrains.php.lang.psi.PhpFile in project phpinspectionsea by kalessil.

the class SlowArrayOperationsInLoopInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            if (functionName != null && greedyFunctions.contains(functionName)) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length > 1 && !(arguments[0] instanceof ArrayAccessExpression)) {
                    PsiElement parent = reference.getParent();
                    if (parent instanceof AssignmentExpression) {
                        /* false-positives: return/break as last group statement expression */
                        boolean canLoop = true;
                        if (OpenapiTypesUtil.isStatementImpl(parent = parent.getParent())) {
                            final PsiElement grandParent = parent.getParent();
                            if (grandParent instanceof GroupStatement) {
                                final PsiElement last = ExpressionSemanticUtil.getLastStatement((GroupStatement) grandParent);
                                canLoop = !(last instanceof PhpBreak) && !(last instanceof PhpReturn);
                            }
                        }
                        while (canLoop && parent != null && !(parent instanceof PhpFile) && !(parent instanceof Function)) {
                            if (OpenapiTypesUtil.isLoop(parent)) {
                                final PsiElement container = ((AssignmentExpression) reference.getParent()).getVariable();
                                if (container != null) {
                                    for (final PsiElement argument : arguments) {
                                        if (OpenapiEquivalenceUtil.areEqual(container, argument)) {
                                            holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messageGreedyPattern), functionName));
                                            return;
                                        }
                                    }
                                }
                            }
                            parent = parent.getParent();
                        }
                    }
                }
            }
        }

        @Override
        public void visitPhpFor(@NotNull For forStatement) {
            final Set<FunctionReference> references = new HashSet<>();
            Arrays.stream(forStatement.getConditionalExpressions()).forEach(c -> {
                if (c instanceof BinaryExpression) {
                    final BinaryExpression binary = (BinaryExpression) c;
                    Stream.of(binary.getLeftOperand(), binary.getRightOperand()).filter(p -> p instanceof FunctionReference).forEach(p -> references.add((FunctionReference) p));
                }
            });
            references.stream().filter(OpenapiTypesUtil::isFunctionReference).forEach(r -> {
                final String functionName = r.getName();
                if (functionName != null && slowFunctions.contains(functionName)) {
                    final BinaryExpression condition = (BinaryExpression) r.getParent();
                    holder.registerProblem(condition, String.format(MessagesPresentationUtil.prefixWithEa(messageSlowPattern), functionName), ProblemHighlightType.GENERIC_ERROR, new ReduceRepetitiveCallsInForFix(holder.getProject(), forStatement, condition));
                }
            });
            references.clear();
        }
    };
}
Also used : Arrays(java.util.Arrays) com.jetbrains.php.lang.psi.elements(com.jetbrains.php.lang.psi.elements) PhpTokenTypes(com.jetbrains.php.lang.lexer.PhpTokenTypes) HashSet(java.util.HashSet) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) OpenapiTypesUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil) ProblemDescriptor(com.intellij.codeInspection.ProblemDescriptor) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) OpenapiEquivalenceUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiEquivalenceUtil) PsiElement(com.intellij.psi.PsiElement) Project(com.intellij.openapi.project.Project) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) PhpPsiElementFactory(com.jetbrains.php.lang.psi.PhpPsiElementFactory) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) ExpressionSemanticUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.ExpressionSemanticUtil) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) Set(java.util.Set) SmartPointerManager(com.intellij.psi.SmartPointerManager) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Stream(java.util.stream.Stream) PhpFile(com.jetbrains.php.lang.psi.PhpFile) SmartPsiElementPointer(com.intellij.psi.SmartPsiElementPointer) ProblemHighlightType(com.intellij.codeInspection.ProblemHighlightType) NotNull(org.jetbrains.annotations.NotNull) PhpFile(com.jetbrains.php.lang.psi.PhpFile) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PsiElement(com.intellij.psi.PsiElement) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with PhpFile

use of com.jetbrains.php.lang.psi.PhpFile 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 10 with PhpFile

use of com.jetbrains.php.lang.psi.PhpFile in project yii2support by nvlad.

the class ObjectFactoryCompletionProvider method addCompletions.

@Override
protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) {
    if (getArrayCreation(completionParameters) == null && !(completionParameters.getPosition().getParent().getParent().getParent().getParent() instanceof ArrayCreationExpression) && !(completionParameters.getPosition().getParent().getParent().getParent() instanceof ArrayAccessExpression)) {
        return;
    }
    ArrayCreationExpression arrayCreation = null;
    // access to key of variable declared elsewhere
    if (completionParameters.getPosition().getParent().getParent().getParent() instanceof ArrayAccessExpression) {
        ArrayAccessExpression arrayAccess = (ArrayAccessExpression) completionParameters.getPosition().getParent().getParent().getParent();
        PhpPsiElement value = arrayAccess.getValue();
        if (value instanceof Variable)
            arrayCreation = ObjectFactoryUtils.getArrayCreationByVarRef((Variable) value);
        if (value instanceof FieldReference)
            arrayCreation = ObjectFactoryUtils.getArrayCreationByFieldRef((FieldReference) value);
        if (arrayCreation == null)
            return;
    // get parent array creation from inside of array
    } else if (getArrayCreation(completionParameters) != null) {
        arrayCreation = getArrayCreation(completionParameters);
    } else if (completionParameters.getPosition().getParent().getParent().getParent().getParent() instanceof ArrayCreationExpression && completionParameters.getPosition().getParent().getParent().getParent() instanceof ArrayHashElement && completionParameters.getPosition().getParent().getParent().toString() != "Array value") {
        arrayCreation = (ArrayCreationExpression) completionParameters.getPosition().getParent().getParent().getParent().getParent();
    } else {
        return;
    }
    PhpClass phpClass = null;
    PhpFile file = (PhpFile) completionParameters.getOriginalFile();
    PsiDirectory dir = file.getContainingDirectory();
    phpClass = ObjectFactoryUtils.findClassByArrayCreation(arrayCreation, dir);
    Hashtable<String, Object> uniqTracker = new Hashtable<>();
    PhpExpression position = (PhpExpression) completionParameters.getPosition().getParent();
    if (phpClass != null) {
        for (Field field : ClassUtils.getWritableClassFields(phpClass)) {
            uniqTracker.put(field.getName(), field);
            LookupElementBuilder lookupBuilder = buildLookup(field, position);
            completionResultSet.addElement(lookupBuilder);
        }
        for (Method method : ClassUtils.getClassSetMethods(phpClass)) {
            if (uniqTracker.get(ClassUtils.getAsPropertyName(method)) == null) {
                LookupElementBuilder lookupBuilder = buildLookup(method, position);
                completionResultSet.addElement(lookupBuilder);
            }
        }
    }
}
Also used : PhpFile(com.jetbrains.php.lang.psi.PhpFile) Hashtable(java.util.Hashtable) PsiDirectory(com.intellij.psi.PsiDirectory) LookupElementBuilder(com.intellij.codeInsight.lookup.LookupElementBuilder)

Aggregations

PhpFile (com.jetbrains.php.lang.psi.PhpFile)11 PsiElement (com.intellij.psi.PsiElement)9 NotNull (org.jetbrains.annotations.NotNull)9 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)8 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)5 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)5 BasePhpInspection (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection)5 MessagesPresentationUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil)5 Project (com.intellij.openapi.project.Project)4 com.jetbrains.php.lang.psi.elements (com.jetbrains.php.lang.psi.elements)4 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)3 HashSet (java.util.HashSet)3 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)2 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)2 PsiFile (com.intellij.psi.PsiFile)2 PhpIndex (com.jetbrains.php.PhpIndex)2 PhpDocComment (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment)2 PhpTokenTypes (com.jetbrains.php.lang.lexer.PhpTokenTypes)2 PhpPsiElementFactory (com.jetbrains.php.lang.psi.PhpPsiElementFactory)2 OptionsComponent (com.kalessil.phpStorm.phpInspectionsEA.options.OptionsComponent)2