Search in sources :

Example 16 with BinaryExpression

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

the class IssetConstructsCanBeMergedInspector method buildVisitor.

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

        @Override
        public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
            final IElementType operator = expression.getOperationType();
            if (operator != null && (operator == PhpTokenTypes.opAND || operator == PhpTokenTypes.opOR)) {
                /* false-positives: part of another condition */
                final PsiElement parent = expression.getParent();
                final PsiElement context = parent instanceof ParenthesizedExpression ? parent.getParent() : parent;
                if (context instanceof BinaryExpression && ((BinaryExpression) context).getOperationType() == operator) {
                    return;
                }
                final List<PsiElement> fragments = this.extract(expression, operator);
                if (fragments.size() > 1) {
                    if (operator == PhpTokenTypes.opAND) {
                        /* handle isset && isset ... */
                        PsiElement firstHit = null;
                        int hitsCount = 0;
                        for (final PsiElement fragment : fragments) {
                            if (fragment instanceof PhpIsset) {
                                if (++hitsCount > 1 && firstHit != null) {
                                    fragments.remove(firstHit);
                                    fragments.remove(fragment);
                                    holder.registerProblem(fragment, MessagesPresentationUtil.prefixWithEa(messageIsset), new MergeConstructsFix(holder.getProject(), expression, fragments, (PhpIsset) firstHit, (PhpIsset) fragment, operator));
                                    break;
                                }
                                firstHit = firstHit == null ? fragment : firstHit;
                            }
                        }
                    } else {
                        /* handle !isset || !isset ... */
                        PsiElement firstHit = null;
                        int hitsCount = 0;
                        for (final PsiElement fragment : fragments) {
                            if (fragment instanceof UnaryExpression) {
                                final PsiElement candidate = ((UnaryExpression) fragment).getValue();
                                if (candidate instanceof PhpIsset) {
                                    if (++hitsCount > 1 && firstHit != null) {
                                        fragments.remove(firstHit.getParent());
                                        fragments.remove(fragment);
                                        holder.registerProblem(candidate, MessagesPresentationUtil.prefixWithEa(messageIvertedIsset), new MergeConstructsFix(holder.getProject(), expression, fragments, (PhpIsset) firstHit, (PhpIsset) candidate, operator));
                                        break;
                                    }
                                    firstHit = firstHit == null ? candidate : firstHit;
                                }
                            }
                        }
                    }
                }
                fragments.clear();
            }
        }

        @NotNull
        private List<PsiElement> extract(@NotNull BinaryExpression binary, @Nullable IElementType operator) {
            final List<PsiElement> result = new ArrayList<>();
            if (binary.getOperationType() == operator) {
                Stream.of(binary.getLeftOperand(), binary.getRightOperand()).filter(Objects::nonNull).map(ExpressionSemanticUtil::getExpressionTroughParenthesis).forEach(expression -> {
                    if (expression instanceof BinaryExpression) {
                        result.addAll(this.extract((BinaryExpression) expression, operator));
                    } else {
                        result.add(expression);
                    }
                });
            } else {
                result.add(binary);
            }
            return result;
        }
    };
}
Also used : ParenthesizedExpression(com.jetbrains.php.lang.psi.elements.ParenthesizedExpression) ArrayList(java.util.ArrayList) UnaryExpression(com.jetbrains.php.lang.psi.elements.UnaryExpression) NotNull(org.jetbrains.annotations.NotNull) IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) Objects(java.util.Objects) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable) PhpIsset(com.jetbrains.php.lang.psi.elements.PhpIsset) NotNull(org.jetbrains.annotations.NotNull)

Example 17 with BinaryExpression

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

the class GenerateAlternativeFromNullComparisonStrategy method generate.

@Nullable
public static String generate(@NotNull TernaryExpression expression) {
    /* verify condition structure */
    final PsiElement compareCandidate = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getCondition());
    final BinaryExpression compare = compareCandidate instanceof BinaryExpression ? (BinaryExpression) compareCandidate : null;
    final PsiElement left = null == compare ? null : compare.getLeftOperand();
    final PsiElement right = null == compare ? null : compare.getRightOperand();
    final IElementType operation = null == compare ? null : compare.getOperationType();
    if ((operation != PhpTokenTypes.opIDENTICAL && operation != PhpTokenTypes.opNOT_IDENTICAL) || (!PhpLanguageUtil.isNull(left) && !PhpLanguageUtil.isNull(right))) {
        return null;
    }
    /* verify general expression structure */
    final boolean isInverted = operation == PhpTokenTypes.opNOT_IDENTICAL;
    final PsiElement subject = PhpLanguageUtil.isNull(right) ? left : right;
    final PsiElement value = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getTrueVariant() : expression.getFalseVariant());
    final PsiElement alternative = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getFalseVariant() : expression.getTrueVariant());
    if (null == subject || null == value || null == alternative || !OpenapiEquivalenceUtil.areEqual(subject, value)) {
        return null;
    }
    return subject.getText() + " ?? " + alternative.getText();
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 18 with BinaryExpression

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

the class AndOrWordsUsageStrategy method apply.

public static void apply(PsiElement condition, @NotNull ProblemsHolder holder) {
    final Collection<BinaryExpression> expressions = PsiTreeUtil.findChildrenOfType(condition, BinaryExpression.class);
    /* don't forget to inspect top-level condition ;) */
    if (condition instanceof BinaryExpression) {
        expressions.add((BinaryExpression) condition);
    }
    if (!expressions.isEmpty()) {
        for (BinaryExpression expression : expressions) {
            final PsiElement operation = expression.getOperation();
            if (null == operation) {
                continue;
            }
            final String operator = operation.getText().trim();
            if (operator.equalsIgnoreCase("and")) {
                holder.registerProblem(operation, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%o%", "&&")), ProblemHighlightType.WEAK_WARNING);
                continue;
            }
            if (operator.equalsIgnoreCase("or")) {
                holder.registerProblem(operation, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%o%", "||")), ProblemHighlightType.WEAK_WARNING);
            // continue;
            }
        }
        expressions.clear();
    }
}
Also used : BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) PsiElement(com.intellij.psi.PsiElement)

Example 19 with BinaryExpression

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

the class SelfAssignmentStrategy method apply.

public static void apply(@NotNull SelfAssignmentExpression expression, @NotNull ProblemsHolder holder) {
    /* verify self-assignment operator */
    final IElementType assignOperator = expression.getOperationType();
    if (!mapping.containsKey(assignOperator)) {
        return;
    }
    /* verify if the expression is complete and has needed structure */
    final PsiElement variable = expression.getVariable();
    final PsiElement value = expression.getValue();
    if (variable == null || !(value instanceof BinaryExpression)) {
        return;
    }
    final BinaryExpression valueExpression = (BinaryExpression) value;
    /* check if assignment value is complete */
    final PsiElement valueOperation = valueExpression.getOperation();
    final PsiElement valueLeftPart = valueExpression.getLeftOperand();
    if (null == valueOperation || null == valueLeftPart) {
        return;
    }
    /* now analysis itself */
    if (OpenapiTypesUtil.is(valueOperation, mapping.get(assignOperator)) && OpenapiEquivalenceUtil.areEqual(variable, valueLeftPart)) {
        holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(message));
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) PsiElement(com.intellij.psi.PsiElement)

Example 20 with BinaryExpression

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

the class SenselessTernaryOperatorInspector 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());
            if (condition instanceof BinaryExpression) {
                final BinaryExpression binary = (BinaryExpression) condition;
                final IElementType operationType = binary.getOperationType();
                if (operationType == PhpTokenTypes.opIDENTICAL || operationType == PhpTokenTypes.opNOT_IDENTICAL) {
                    final boolean isInverted = operationType == PhpTokenTypes.opNOT_IDENTICAL;
                    final PsiElement trueVariant = isInverted ? expression.getFalseVariant() : expression.getTrueVariant();
                    final PsiElement falseVariant = isInverted ? expression.getTrueVariant() : expression.getFalseVariant();
                    if (trueVariant != null && falseVariant != null) {
                        final PsiElement value = binary.getRightOperand();
                        final PsiElement subject = binary.getLeftOperand();
                        if (value != null && subject != null) {
                            final boolean isLeftPartReturned = OpenapiEquivalenceUtil.areEqual(value, trueVariant) || OpenapiEquivalenceUtil.areEqual(value, falseVariant);
                            if (isLeftPartReturned) {
                                final boolean isRightPartReturned = OpenapiEquivalenceUtil.areEqual(subject, falseVariant) || OpenapiEquivalenceUtil.areEqual(subject, trueVariant);
                                if (isRightPartReturned) {
                                    final String replacement = falseVariant.getText();
                                    holder.registerProblem(expression, String.format(MessagesPresentationUtil.prefixWithEa(patternUseOperands), replacement), new SimplifyFix(replacement));
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : 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)

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