Search in sources :

Example 41 with BasePhpElementVisitor

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

the class AmbiguousMethodsCallsInArrayMappingInspector method buildVisitor.

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

        @Override
        public void visitPhpFor(@NotNull For loop) {
            final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(loop);
            if (body != null) {
                this.analyzeBody(body);
            }
        }

        @Override
        public void visitPhpForeach(@NotNull ForeachStatement loop) {
            final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(loop);
            if (body != null) {
                this.analyzeBody(body);
            }
        }

        private void analyzeBody(@NotNull GroupStatement body) {
            for (final PsiElement instruction : body.getStatements()) {
                final PsiElement candidate = instruction.getFirstChild();
                if (candidate instanceof AssignmentExpression) {
                    final AssignmentExpression assignment = (AssignmentExpression) candidate;
                    final PsiElement value = assignment.getValue();
                    final PsiElement container = assignment.getVariable();
                    if (value != null && container instanceof ArrayAccessExpression) {
                        this.analyzeStatement((ArrayAccessExpression) container, value);
                    }
                }
            }
        }

        private void analyzeStatement(@NotNull ArrayAccessExpression container, @NotNull PsiElement value) {
            final Collection<FunctionReference> left = PsiTreeUtil.findChildrenOfType(container, FunctionReference.class);
            if (!left.isEmpty()) {
                final Collection<FunctionReference> right = PsiTreeUtil.findChildrenOfType(value, FunctionReference.class);
                if (value instanceof FunctionReference) {
                    right.add((FunctionReference) value);
                }
                if (!right.isEmpty()) {
                    iterate: for (final FunctionReference current : right) {
                        final String currentName = current.getName();
                        for (final FunctionReference candidate : left) {
                            final String candidateName = candidate.getName();
                            if (currentName != null && currentName.equals(candidateName) && OpenapiEquivalenceUtil.areEqual(current, candidate)) {
                                holder.registerProblem(current, MessagesPresentationUtil.prefixWithEa(message));
                                break iterate;
                            }
                        }
                    }
                    right.clear();
                }
                left.clear();
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 42 with BasePhpElementVisitor

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

the class ComparisonOperandsOrderInspector method buildVisitor.

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

        @Override
        public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
            final IElementType operator = expression.getOperationType();
            if (operator != null && OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator)) {
                final PsiElement left = expression.getLeftOperand();
                final PsiElement right = expression.getRightOperand();
                if (left != null && right != null) {
                    final boolean isLeftConstant = left instanceof StringLiteralExpression || left instanceof ConstantReference || OpenapiTypesUtil.isNumber(left);
                    final boolean isRightConstant = right instanceof StringLiteralExpression || right instanceof ConstantReference || OpenapiTypesUtil.isNumber(right);
                    if (isLeftConstant != isRightConstant) {
                        final boolean isRegular = ComparisonStyle.isRegular();
                        if (isRightConstant && !isRegular) {
                            problemsHolder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(messageUseYoda), new TheLocalFix());
                        }
                        if (isLeftConstant && isRegular) {
                            problemsHolder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(messageUseRegular), new TheLocalFix());
                        }
                    }
                }
            }
        }
    };
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) ConstantReference(com.jetbrains.php.lang.psi.elements.ConstantReference) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 43 with BasePhpElementVisitor

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

the class ParameterDefaultValueIsNotNullInspector method buildVisitor.

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

        @Override
        public void visitPhpMethod(@NotNull Method method) {
            this.analyze(method);
        }

        @Override
        public void visitPhpFunction(@NotNull Function function) {
            this.analyze(function);
        }

        private void analyze(@NotNull Function function) {
            final Parameter[] arguments = function.getParameters();
            if (arguments.length > 0) {
                /* collect violations */
                final List<Parameter> violations = new ArrayList<>();
                for (final Parameter argument : arguments) {
                    final PsiElement defaultValue = argument.getDefaultValue();
                    if (defaultValue != null && !PhpLanguageUtil.isNull(defaultValue)) {
                        /* false-positives: null can not be used due to implicit type hints */
                        final PhpType declared = OpenapiResolveUtil.resolveDeclaredType(argument);
                        if (declared.isEmpty() || declared.getTypes().stream().anyMatch(t -> Types.getType(t).equals(Types.strNull))) {
                            violations.add(argument);
                        }
                    }
                }
                if (!violations.isEmpty()) {
                    /* false-positives: methods overrides, so violation should be addressed in the parent */
                    if (function instanceof Method) {
                        final PhpClass clazz = ((Method) function).getContainingClass();
                        if (clazz != null) {
                            final PhpClass parent = OpenapiResolveUtil.resolveSuperClass(clazz);
                            if (parent != null) {
                                final Method parentMethod = OpenapiResolveUtil.resolveMethod(parent, function.getName());
                                if (parentMethod != null && !parentMethod.getAccess().isPrivate()) {
                                    violations.clear();
                                    return;
                                }
                            }
                        }
                    }
                    /* report violations */
                    violations.forEach(param -> holder.registerProblem(param, MessagesPresentationUtil.prefixWithEa(message)));
                    violations.clear();
                }
            }
        }
    };
}
Also used : PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) Types(com.kalessil.phpStorm.phpInspectionsEA.utils.Types) PhpLanguageUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.PhpLanguageUtil) Function(com.jetbrains.php.lang.psi.elements.Function) Method(com.jetbrains.php.lang.psi.elements.Method) ArrayList(java.util.ArrayList) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) List(java.util.List) OpenapiResolveUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) Parameter(com.jetbrains.php.lang.psi.elements.Parameter) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) ArrayList(java.util.ArrayList) Parameter(com.jetbrains.php.lang.psi.elements.Parameter) Method(com.jetbrains.php.lang.psi.elements.Method) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull)

Example 44 with BasePhpElementVisitor

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

the class EfferentObjectCouplingInspector method buildVisitor.

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

        @Override
        public void visitPhpClass(@NotNull PhpClass clazz) {
            final PsiElement nameIdentifier = NamedElementUtil.getNameIdentifier(clazz);
            if (nameIdentifier != null) {
                final Set<String> references = PsiTreeUtil.findChildrenOfType(clazz, ClassReference.class).stream().map(ClassReference::getFQN).collect(Collectors.toSet());
                final int count = references.size();
                if (count >= optionCouplingLimit) {
                    holder.registerProblem(nameIdentifier, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), count));
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) ClassReference(com.jetbrains.php.lang.psi.elements.ClassReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 45 with BasePhpElementVisitor

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

the class MissUsingParentKeywordInspector method buildVisitor.

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

        @Override
        public void visitPhpMethodReference(@NotNull MethodReference reference) {
            final PsiElement base = reference.getClassReference();
            if (base instanceof ClassReference && base.getText().equals("parent")) {
                final Function scope = ExpressionSemanticUtil.getScope(reference);
                if (scope instanceof Method) {
                    final Method context = (Method) scope;
                    final PhpClass clazz = context.getContainingClass();
                    if (clazz != null && !clazz.isTrait() && !context.isStatic()) {
                        final String methodName = scope.getName();
                        final String referenceName = reference.getName();
                        if (referenceName != null && !referenceName.equals(methodName)) {
                            final boolean isTarget = clazz.findOwnMethodByName(referenceName) == null && !this.isOverridden(clazz, referenceName);
                            if (isTarget) {
                                final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
                                if (resolved instanceof Method) {
                                    final PsiElement parameters = reference.getParameterList();
                                    final String replacement = String.format(((Method) resolved).isStatic() ? "self::%s(%s)" : "$this->%s(%s)", referenceName, parameters == null ? "" : parameters.getText());
                                    holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement), new NormalizeClassReferenceFix(replacement));
                                }
                            }
                        }
                    }
                }
            }
        }

        final boolean isOverridden(@NotNull PhpClass clazz, @NotNull String methodName) {
            if (!clazz.isFinal()) {
                final PhpIndex index = PhpIndex.getInstance(holder.getProject());
                final Collection<PhpClass> children = OpenapiResolveUtil.resolveChildClasses(clazz.getFQN(), index);
                return children.stream().anyMatch(c -> c.findOwnMethodByName(methodName) != null);
            }
            return false;
        }
    };
}
Also used : PhpIndex(com.jetbrains.php.PhpIndex) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PsiElement(com.intellij.psi.PsiElement) 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