Search in sources :

Example 31 with BinaryExpression

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

the class ArraySearchUsedAsInArrayInspector 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 && functionName.equals("array_search")) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length >= 2) {
                    if (ExpressionSemanticUtil.isUsedAsLogicalOperand(reference)) {
                        /* case: used as (boolean) logical operand */
                        holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageUseInArray), new TheLocalFix());
                    } else {
                        /* case: implicit booleans comparison */
                        final PsiElement parent = reference.getParent();
                        if (parent instanceof BinaryExpression) {
                            final BinaryExpression binary = (BinaryExpression) parent;
                            final IElementType operation = binary.getOperationType();
                            if (operation == PhpTokenTypes.opIDENTICAL || operation == PhpTokenTypes.opNOT_IDENTICAL) {
                                final PsiElement secondOperand = OpenapiElementsUtil.getSecondOperand(binary, reference);
                                if (PhpLanguageUtil.isBoolean(secondOperand)) {
                                    if (PhpLanguageUtil.isTrue(secondOperand)) {
                                        holder.registerProblem(secondOperand, MessagesPresentationUtil.prefixWithEa(messageComparingWithTrue), ProblemHighlightType.GENERIC_ERROR);
                                    } else {
                                        holder.registerProblem(binary, MessagesPresentationUtil.prefixWithEa(messageUseInArray), new TheLocalFix());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 32 with BinaryExpression

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

the class GetTypeMissUseInspector 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 && functionName.equals("gettype")) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length == 1) {
                    final PsiElement parent = reference.getParent();
                    if (parent instanceof BinaryExpression) {
                        final BinaryExpression expression = (BinaryExpression) parent;
                        final IElementType operator = expression.getOperationType();
                        if (OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator)) {
                            final PsiElement candidate = OpenapiElementsUtil.getSecondOperand(expression, reference);
                            final StringLiteralExpression value = ExpressionSemanticUtil.resolveAsStringLiteral(candidate);
                            if (value != null) {
                                final String type = value.getContents();
                                if (!mapping.containsKey(type)) {
                                    /* edge case: compared string is wrong xD - bug */
                                    if (!type.equals("unknown type") && !type.equals("resource (closed)")) {
                                        holder.registerProblem(value, String.format(MessagesPresentationUtil.prefixWithEa(messageInvalidPattern), type), ProblemHighlightType.GENERIC_ERROR);
                                    }
                                } else {
                                    final boolean isInverted = operator == PhpTokenTypes.opNOT_EQUAL || operator == PhpTokenTypes.opNOT_IDENTICAL;
                                    final String replacement = String.format("%s%s(%s)", isInverted ? "!" : "", mapping.get(type), arguments[0].getText());
                                    holder.registerProblem(parent, String.format(MessagesPresentationUtil.prefixWithEa(messageUseFunctionPattern), replacement), new UseSuggestedFunctionFix(replacement));
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 33 with BinaryExpression

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

the class SummerTimeUnsafeTimeManipulationInspector method buildVisitor.

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

        @Override
        public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
            if (targetOperations.contains(expression.getOperationType())) {
                final PsiElement left = expression.getLeftOperand();
                final PsiElement right = expression.getRightOperand();
                if (right != null && this.isTargetMagicNumber(right) && this.isTargetContext(right)) {
                    if (!this.isTestContext(expression)) {
                        holder.registerProblem(expression, message);
                    }
                } else if (left != null && this.isTargetMagicNumber(left) && this.isTargetContext(left)) {
                    if (!this.isTestContext(expression)) {
                        holder.registerProblem(expression, message);
                    }
                }
            }
        }

        @Override
        public void visitPhpSelfAssignmentExpression(@NotNull SelfAssignmentExpression expression) {
            if (targetAssignments.contains(expression.getOperationType())) {
                final PsiElement value = expression.getValue();
                if (value != null && this.isTargetMagicNumber(value) && !this.isTestContext(expression)) {
                    holder.registerProblem(expression, message);
                }
            }
        }

        private boolean isTargetContext(@NotNull PsiElement magicNumber) {
            boolean result = magicNumber.textMatches("86400");
            if (!result) {
                PsiElement expression = magicNumber.getParent();
                while (expression instanceof ParenthesizedExpression || expression instanceof BinaryExpression) {
                    expression = expression.getParent();
                }
                result = PsiTreeUtil.findChildrenOfType(expression, PhpExpression.class).stream().filter(OpenapiTypesUtil::isNumber).anyMatch(candidate -> {
                    final String text = candidate.getText();
                    return text.equals("60") || text.endsWith("3600");
                });
            }
            return result;
        }

        private boolean isTargetMagicNumber(@NotNull PsiElement candidate) {
            boolean result = false;
            if (OpenapiTypesUtil.isNumber(candidate)) {
                result = candidate.textMatches("24") || candidate.textMatches("86400");
            }
            return result;
        }
    };
}
Also used : SelfAssignmentExpression(com.jetbrains.php.lang.psi.elements.SelfAssignmentExpression) ParenthesizedExpression(com.jetbrains.php.lang.psi.elements.ParenthesizedExpression) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) IElementType(com.intellij.psi.tree.IElementType) PhpTokenTypes(com.jetbrains.php.lang.lexer.PhpTokenTypes) Set(java.util.Set) SelfAssignmentExpression(com.jetbrains.php.lang.psi.elements.SelfAssignmentExpression) HashSet(java.util.HashSet) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) ParenthesizedExpression(com.jetbrains.php.lang.psi.elements.ParenthesizedExpression) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) OpenapiTypesUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) PhpExpression(com.jetbrains.php.lang.psi.elements.PhpExpression) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) OpenapiTypesUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 34 with BinaryExpression

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

the class SuspiciousTernaryOperatorInspector method buildVisitor.

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

        @Override
        public void visitPhpTernaryExpression(@NotNull TernaryExpression expression) {
            final PsiElement condition = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getCondition());
            final PsiElement trueVariant = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getTrueVariant());
            final PsiElement falseVariant = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getFalseVariant());
            /* Case 1: identical variants */
            if (trueVariant != null && falseVariant != null && OpeanapiEquivalenceUtil.areEqual(trueVariant, falseVariant)) {
                holder.registerProblem(expression, messageVariantsIdentical, ProblemHighlightType.GENERIC_ERROR);
            }
            /* Case 2: operations which might produce a value as not expected */
            if (condition instanceof BinaryExpression && !(expression.getCondition() instanceof ParenthesizedExpression)) {
                final IElementType operator = ((BinaryExpression) condition).getOperationType();
                if (operator != null && !safeOperations.contains(operator)) {
                    holder.registerProblem(condition, messagePriorities, ProblemHighlightType.GENERIC_ERROR);
                }
            }
            /* Case 3: literal operators priorities issue */
            final PsiElement parent = expression.getParent();
            if (parent instanceof BinaryExpression) {
                final BinaryExpression binary = (BinaryExpression) parent;
                if (binary.getRightOperand() == expression && PhpTokenTypes.tsLIT_OPS.contains(binary.getOperationType())) {
                    holder.registerProblem(binary, messagePriorities, ProblemHighlightType.GENERIC_ERROR);
                }
            }
        }
    };
}
Also used : ParenthesizedExpression(com.jetbrains.php.lang.psi.elements.ParenthesizedExpression) IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) TernaryExpression(com.jetbrains.php.lang.psi.elements.TernaryExpression) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 35 with BinaryExpression

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

the class PowerOperatorCanBeUsedInspector method buildVisitor.

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

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final PhpLanguageLevel php = PhpProjectConfigurationFacade.getInstance(holder.getProject()).getLanguageLevel();
            if (php.compareTo(PhpLanguageLevel.PHP560) >= 0) {
                final String functionName = reference.getName();
                if (functionName != null && functionName.equals("pow")) {
                    final PsiElement[] arguments = reference.getParameters();
                    if (arguments.length == 2) {
                        final String replacement = (reference.getParent() instanceof BinaryExpression ? "(%b% ** %p%)" : "%b% ** %p%").replace("%p%", arguments[1] instanceof BinaryExpression ? "(%p%)" : "%p%").replace("%b%", arguments[0] instanceof BinaryExpression ? "(%b%)" : "%b%").replace("%p%", arguments[1].getText()).replace("%b%", arguments[0].getText());
                        holder.registerProblem(reference, String.format(messagePattern, replacement), new UseTheOperatorFix(replacement));
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PhpLanguageLevel(com.jetbrains.php.config.PhpLanguageLevel) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)35 PsiElement (com.intellij.psi.PsiElement)34 IElementType (com.intellij.psi.tree.IElementType)26 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)25 NotNull (org.jetbrains.annotations.NotNull)25 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)16 UnaryExpression (com.jetbrains.php.lang.psi.elements.UnaryExpression)9 ParenthesizedExpression (com.jetbrains.php.lang.psi.elements.ParenthesizedExpression)6 PhpType (com.jetbrains.php.lang.psi.resolve.types.PhpType)5 Nullable (org.jetbrains.annotations.Nullable)5 PhpTypedElement (com.jetbrains.php.lang.psi.elements.PhpTypedElement)4 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)4 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)3 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)3 PhpTokenTypes (com.jetbrains.php.lang.lexer.PhpTokenTypes)3 TernaryExpression (com.jetbrains.php.lang.psi.elements.TernaryExpression)3 BasePhpInspection (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection)3 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 Objects (java.util.Objects)3