Search in sources :

Example 61 with BasePhpElementVisitor

use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.

the class StaticLambdaBindingInspector method buildVisitor.

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

        @Override
        public void visitPhpFunction(@NotNull Function function) {
            final Project project = holder.getProject();
            if (PhpLanguageLevel.get(project).atLeast(PhpLanguageLevel.PHP540) && OpenapiTypesUtil.isLambda(function)) {
                final boolean isTarget = OpenapiTypesUtil.is(function.getFirstChild(), PhpTokenTypes.kwSTATIC);
                if (isTarget) {
                    final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
                    if (body != null) {
                        for (final PsiElement element : PsiTreeUtil.findChildrenOfAnyType(body, Variable.class, MethodReference.class)) {
                            if (element instanceof Variable) {
                                final Variable variable = (Variable) element;
                                if (variable.getName().equals("this") && function == ExpressionSemanticUtil.getScope(variable)) {
                                    holder.registerProblem(variable, MessagesPresentationUtil.prefixWithEa(messageThis), new TurnClosureIntoNonStaticFix(project, function.getFirstChild()));
                                    return;
                                }
                            } else {
                                final MethodReference reference = (MethodReference) element;
                                final PsiElement base = reference.getFirstChild();
                                if (base instanceof ClassReference && base.getText().equals("parent")) {
                                    final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
                                    if (resolved instanceof Method && !((Method) resolved).isStatic()) {
                                        holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageParent), new TurnClosureIntoNonStaticFix(project, function.getFirstChild()));
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Project(com.intellij.openapi.project.Project) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 62 with BasePhpElementVisitor

use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.

the class UnsupportedEmptyListAssignmentsInspector method buildVisitor.

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

        @Override
        public void visitPhpForeach(@NotNull ForeachStatement expression) {
            if (PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP700) && expression.getVariables().isEmpty()) {
                final PsiElement first = expression.getFirstChild();
                if (first != null) {
                    boolean reachedAsKeyword = false;
                    boolean isTarget = false;
                    PsiElement current = first.getNextSibling();
                    while (current != null) {
                        if (!reachedAsKeyword) {
                            reachedAsKeyword = OpenapiTypesUtil.is(current, PhpTokenTypes.kwAS);
                        } else {
                            isTarget = OpenapiTypesUtil.is(current, PhpTokenTypes.kwLIST) || OpenapiTypesUtil.is(current, PhpTokenTypes.chLBRACKET);
                            if (isTarget) {
                                break;
                            }
                        }
                        current = current.getNextSibling();
                    }
                    if (isTarget) {
                        holder.registerProblem(current, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.GENERIC_ERROR);
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) NotNull(org.jetbrains.annotations.NotNull) ForeachStatement(com.jetbrains.php.lang.psi.elements.ForeachStatement) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 63 with BasePhpElementVisitor

use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.

the class IssetArgumentExistenceInspector method buildVisitor.

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

        @Override
        public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
            final PsiElement candidate = expression.getLeftOperand();
            if (candidate instanceof Variable && PhpTokenTypes.opCOALESCE == expression.getOperationType()) {
                final Variable variable = (Variable) candidate;
                if (!this.getSuppliedVariables(expression).contains(variable.getName())) {
                    analyzeExistence(variable);
                }
            }
        }

        @Override
        public void visitPhpEmpty(@NotNull PhpEmpty expression) {
            this.analyzeArgumentsExistence(expression.getVariables());
        }

        @Override
        public void visitPhpIsset(@NotNull PhpIsset expression) {
            this.analyzeArgumentsExistence(expression.getVariables());
        }

        private void analyzeArgumentsExistence(@NotNull PhpExpression[] arguments) {
            if (arguments.length > 0) {
                final Set<String> parameters = this.getSuppliedVariables(arguments[0]);
                for (final PhpExpression argument : arguments) {
                    if (argument instanceof Variable && !parameters.contains(argument.getName())) {
                        this.analyzeExistence((Variable) argument);
                    }
                }
                parameters.clear();
            }
        }

        private void analyzeExistence(@NotNull Variable variable) {
            final String variableName = variable.getName();
            if (!variableName.isEmpty() && !specialVariables.contains(variableName)) {
                final Function scope = ExpressionSemanticUtil.getScope(variable);
                final GroupStatement body = scope == null ? null : ExpressionSemanticUtil.getGroupStatement(scope);
                if (body != null) {
                    for (final Variable reference : PsiTreeUtil.findChildrenOfType(body, Variable.class)) {
                        if (reference.getName().equals(variableName)) {
                            boolean report = reference == variable;
                            if (!report) {
                                final PsiElement parent = reference.getParent();
                                if (parent instanceof AssignmentExpression) {
                                    report = PsiTreeUtil.findCommonParent(reference, variable) == parent;
                                }
                            }
                            if (report) {
                                /* variable created dynamically in a loop: hacky stuff, but nevertheless */
                                PsiElement loopCandidate = reference.getParent();
                                while (loopCandidate != null && loopCandidate != scope) {
                                    if (OpenapiTypesUtil.isLoop(loopCandidate)) {
                                        report = PsiTreeUtil.findChildrenOfType(loopCandidate, AssignmentExpression.class).stream().noneMatch(assignment -> {
                                            final PsiElement container = assignment.getVariable();
                                            return container instanceof Variable && ((Variable) container).getName().equals(variableName);
                                        });
                                        break;
                                    }
                                    loopCandidate = loopCandidate.getParent();
                                }
                                if (report && (IGNORE_INCLUDES || !this.hasIncludes(scope)) && !this.hasGotos(scope)) {
                                    holder.registerProblem(variable, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), variableName), ProblemHighlightType.GENERIC_ERROR);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }

        @NotNull
        private Set<String> getSuppliedVariables(@NotNull PsiElement expression) {
            final Set<String> result = new HashSet<>();
            final Function scope = ExpressionSemanticUtil.getScope(expression);
            if (scope != null) {
                for (final Parameter parameter : scope.getParameters()) {
                    result.add(parameter.getName());
                }
                final List<Variable> used = ExpressionSemanticUtil.getUseListVariables(scope);
                if (used != null && !used.isEmpty()) {
                    used.forEach(v -> result.add(v.getName()));
                    used.clear();
                }
            }
            return result;
        }

        private boolean hasIncludes(@NotNull Function function) {
            final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
            if (body != null) {
                return PsiTreeUtil.findChildOfType(body, Include.class) != null;
            }
            return false;
        }

        private boolean hasGotos(@NotNull Function function) {
            final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
            if (body != null) {
                return PsiTreeUtil.findChildOfType(body, PhpGoto.class) != null;
            }
            return false;
        }
    };
}
Also used : BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) ExpressionSemanticUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.ExpressionSemanticUtil) com.jetbrains.php.lang.psi.elements(com.jetbrains.php.lang.psi.elements) PhpTokenTypes(com.jetbrains.php.lang.lexer.PhpTokenTypes) Set(java.util.Set) ExpressionCostEstimateUtil(com.kalessil.phpStorm.phpInspectionsEA.inspectors.ifs.utils.ExpressionCostEstimateUtil) OptionsComponent(com.kalessil.phpStorm.phpInspectionsEA.options.OptionsComponent) HashSet(java.util.HashSet) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) OpenapiTypesUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil) List(java.util.List) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) ProblemHighlightType(com.intellij.codeInspection.ProblemHighlightType) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) javax.swing(javax.swing) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PsiElement(com.intellij.psi.PsiElement) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 64 with BasePhpElementVisitor

use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.

the class UnknownInspectionInspector method buildVisitor.

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

        @Override
        public void visitPhpDocTag(@NotNull PhpDocTag tag) {
            if (tag.getName().equals("@noinspection")) {
                final String[] candidates = tag.getTagValue().replaceAll("[^\\p{L}\\p{Nd}]+", " ").trim().split("\\s+");
                if (candidates.length > 0) {
                    final List<String> unknown = Stream.of(candidates[0]).filter(c -> !inspections.contains(c) && !inspections.contains(c + "Inspection")).collect(Collectors.toList());
                    if (!unknown.isEmpty()) {
                        final PsiElement target = tag.getFirstChild();
                        if (target != null) {
                            holder.registerProblem(target, String.format(MessagesPresentationUtil.prefixWithEa(message), String.join(", ", unknown)));
                        }
                        unknown.clear();
                    }
                }
            }
        }
    };
}
Also used : PhpDocTag(com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag) Arrays(java.util.Arrays) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) LOCAL_INSPECTION(com.intellij.codeInspection.LocalInspectionEP.LOCAL_INSPECTION) Set(java.util.Set) InspectionEP(com.intellij.codeInspection.InspectionEP) Collectors(java.util.stream.Collectors) PhpDocTag(com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag) HashSet(java.util.HashSet) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) List(java.util.List) Stream(java.util.stream.Stream) GLOBAL_INSPECTION(com.intellij.codeInspection.InspectionEP.GLOBAL_INSPECTION) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) ApplicationManager(com.intellij.openapi.application.ApplicationManager) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 65 with BasePhpElementVisitor

use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.

the class UnnecessaryIssetArgumentsInspector method buildVisitor.

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

        @Override
        public void visitPhpIsset(@NotNull PhpIsset issetExpression) {
            final PsiElement[] arguments = issetExpression.getVariables();
            if (arguments.length > 1) {
                final Set<PsiElement> reported = new HashSet<>();
                for (final PsiElement current : arguments) {
                    if (current instanceof ArrayAccessExpression && !reported.contains(current)) {
                        /* collect current element bases */
                        final List<PsiElement> bases = new ArrayList<>();
                        PsiElement base = current;
                        while (base instanceof ArrayAccessExpression) {
                            base = ((ArrayAccessExpression) base).getValue();
                            if (base != null) {
                                bases.add(base);
                            }
                        }
                        /* iterate arguments once more to match */
                        if (!bases.isEmpty()) {
                            for (final PsiElement discoveredBase : bases) {
                                for (final PsiElement match : arguments) {
                                    if (match != current && !reported.contains(match) && OpenapiEquivalenceUtil.areEqual(discoveredBase, match)) {
                                        holder.registerProblem(match, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DropArgumentFix());
                                        reported.add(match);
                                    }
                                }
                            }
                            bases.clear();
                        }
                    }
                }
                reported.clear();
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) ArrayList(java.util.ArrayList) NotNull(org.jetbrains.annotations.NotNull) ArrayAccessExpression(com.jetbrains.php.lang.psi.elements.ArrayAccessExpression) PsiElement(com.intellij.psi.PsiElement) PhpIsset(com.jetbrains.php.lang.psi.elements.PhpIsset) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)169 NotNull (org.jetbrains.annotations.NotNull)169 PsiElement (com.intellij.psi.PsiElement)157 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)43 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)40 BasePhpInspection (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection)39 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)37 PhpType (com.jetbrains.php.lang.psi.resolve.types.PhpType)33 IElementType (com.intellij.psi.tree.IElementType)32 com.jetbrains.php.lang.psi.elements (com.jetbrains.php.lang.psi.elements)29 Project (com.intellij.openapi.project.Project)25 BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)25 HashSet (java.util.HashSet)24 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)22 MessagesPresentationUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil)19 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)18 ArrayList (java.util.ArrayList)18 Set (java.util.Set)18 Nullable (org.jetbrains.annotations.Nullable)18 PhpTokenTypes (com.jetbrains.php.lang.lexer.PhpTokenTypes)17