Search in sources :

Example 1 with AssignmentExpression

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

the class IsNullFunctionUsageInspector 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("is_null")) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if (arguments.length != 1) {
                return;
            }
            final PsiElement parent = reference.getParent();
            /* check the context */
            boolean checksIsNull = true;
            PsiElement target = reference;
            if (parent instanceof UnaryExpression) {
                if (OpenapiTypesUtil.is(((UnaryExpression) parent).getOperation(), PhpTokenTypes.opNOT)) {
                    checksIsNull = false;
                    target = parent;
                }
            } else if (parent instanceof BinaryExpression) {
                /* extract isnulls' expression parts */
                final BinaryExpression expression = (BinaryExpression) parent;
                final PsiElement secondOperand = OpenapiElementsUtil.getSecondOperand(expression, reference);
                if (PhpLanguageUtil.isBoolean(secondOperand)) {
                    final IElementType operation = expression.getOperationType();
                    if (PhpTokenTypes.opEQUAL == operation || PhpTokenTypes.opIDENTICAL == operation) {
                        target = parent;
                        checksIsNull = PhpLanguageUtil.isTrue(secondOperand);
                    } else if (operation == PhpTokenTypes.opNOT_EQUAL || operation == PhpTokenTypes.opNOT_IDENTICAL) {
                        target = parent;
                        checksIsNull = !PhpLanguageUtil.isTrue(secondOperand);
                    } else {
                        target = reference;
                    }
                }
            }
            /* report the issue */
            final boolean wrapArgument = PREFER_REGULAR_STYLE && arguments[0] instanceof AssignmentExpression;
            final String replacement = (PREFER_YODA_STYLE ? "null %o% %a%" : "%a% %o% null").replace("%o%", checksIsNull ? "===" : "!==").replace("%a%", wrapArgument ? "(%a%)" : "%a%").replace("%a%", arguments[0].getText());
            final String message = messagePattern.replace("%e%", replacement);
            holder.registerProblem(target, message, new CompareToNullFix(replacement));
        }
    };
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) UnaryExpression(com.jetbrains.php.lang.psi.elements.UnaryExpression) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with AssignmentExpression

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

the class PrintfScanfArgumentsInspector 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 || !functions.containsKey(functionName)) {
                return;
            }
            /* resolve needed parameter */
            final int neededPosition = functions.get(functionName);
            final int minimumArgumentsForAnalysis = neededPosition + 1;
            StringLiteralExpression pattern = null;
            final PsiElement[] params = reference.getParameters();
            if (params.length >= minimumArgumentsForAnalysis) {
                pattern = ExpressionSemanticUtil.resolveAsStringLiteral(params[neededPosition]);
            }
            /* not available */
            if (null == pattern) {
                return;
            }
            final String content = pattern.getContents().trim();
            if (!content.isEmpty()) {
                /* find valid placeholders and extract positions specifiers as well */
                int countWithoutPositionSpecifier = 0;
                int maxPositionSpecifier = 0;
                int countParsedAll = 0;
                /* do normalization: %%, inline variables */
                final String contentAdapted = content.replace("%%", "");
                final String contentNoVars = contentAdapted.replaceAll("\\$\\{?\\$?[a-zA-Z0-9]+\\}?", "");
                if (contentAdapted.length() != contentNoVars.length()) {
                    return;
                }
                final Matcher regexMatcher = regexPlaceHolders.matcher(contentAdapted);
                while (regexMatcher.find()) {
                    ++countParsedAll;
                    if (null != regexMatcher.group(2)) {
                        maxPositionSpecifier = Math.max(maxPositionSpecifier, Integer.parseInt(regexMatcher.group(2)));
                        continue;
                    }
                    ++countWithoutPositionSpecifier;
                }
                final int expectedParametersCount = minimumArgumentsForAnalysis + Math.max(countWithoutPositionSpecifier, maxPositionSpecifier);
                /* check for pattern validity */
                final int parametersInPattern = StringUtils.countMatches(content.replace("%%", ""), "%");
                if (countParsedAll != parametersInPattern) {
                    holder.registerProblem(params[neededPosition], messagePattern, ProblemHighlightType.GENERIC_ERROR);
                    return;
                }
                /* check for arguments matching */
                if (expectedParametersCount != params.length) {
                    /* fscanf/sscanf will also return parsed values as an array if no values containers provided */
                    if (2 == params.length) {
                        final boolean returnsArray = functionName.equals("fscanf") || functionName.equals("sscanf");
                        final PsiElement parent = returnsArray ? reference.getParent() : null;
                        final PsiElement grandParent = parent == null ? null : parent.getParent();
                        if (returnsArray && parent != null) {
                            /* false-positive: dispatching/deconstructing into containers */
                            if (parent instanceof AssignmentExpression || grandParent instanceof AssignmentExpression) {
                                return;
                            } else /* false-positive: dispatching into calls */
                            if (parent instanceof ParameterList && grandParent instanceof FunctionReference) {
                                return;
                            }
                        }
                    }
                    /* false-positives: variadic */
                    if (OpenapiTypesUtil.is(params[params.length - 1].getPrevSibling(), PhpTokenTypes.opVARIADIC)) {
                        return;
                    }
                    final String message = messageParameters.replace("%c%", String.valueOf(expectedParametersCount));
                    holder.registerProblem(reference, message, ProblemHighlightType.GENERIC_ERROR);
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) Matcher(java.util.regex.Matcher) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ParameterList(com.jetbrains.php.lang.psi.elements.ParameterList) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with AssignmentExpression

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

the class ArrayPushMissUseInspector 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_push")) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length == 2 && OpenapiTypesUtil.isStatementImpl(reference.getParent())) {
                    PsiElement variadicCandidate = arguments[1].getPrevSibling();
                    if (variadicCandidate instanceof PsiWhiteSpace) {
                        variadicCandidate = variadicCandidate.getPrevSibling();
                    }
                    if (!OpenapiTypesUtil.is(variadicCandidate, PhpTokenTypes.opVARIADIC)) {
                        final String replacement = String.format("%s[] = %s", arguments[0].getText(), arguments[1].getText());
                        holder.registerProblem(reference, String.format(messageMisuse, replacement), new UseElementPushFix(replacement));
                    }
                }
            }
        }

        @Override
        public void visitPhpArrayAccessExpression(@NotNull ArrayAccessExpression expression) {
            final PsiElement parent = expression.getParent();
            if (OpenapiTypesUtil.isAssignment(parent)) {
                final PsiElement value = ((AssignmentExpression) parent).getValue();
                if (value != expression) {
                    final ArrayIndex index = expression.getIndex();
                    if (index != null) {
                        final PsiElement candidate = index.getValue();
                        if (candidate != null && OpenapiTypesUtil.isFunctionReference(candidate)) {
                            final FunctionReference reference = (FunctionReference) candidate;
                            final String functionName = reference.getName();
                            if (functionName != null && functionName.equals("count")) {
                                final PsiElement[] arguments = reference.getParameters();
                                if (arguments.length == 1) {
                                    final PsiElement container = expression.getValue();
                                    if (container != null && OpeanapiEquivalenceUtil.areEqual(container, arguments[0])) {
                                        holder.registerProblem(reference, messageUnneeded, ProblemHighlightType.LIKE_UNUSED_SYMBOL);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) ArrayAccessExpression(com.jetbrains.php.lang.psi.elements.ArrayAccessExpression) ArrayIndex(com.jetbrains.php.lang.psi.elements.ArrayIndex) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with AssignmentExpression

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

the class UnclearOperationsPriorityStrategy method apply.

public static boolean apply(@NotNull BinaryExpression expression, @NotNull ProblemsHolder holder) {
    final IElementType operator = expression.getOperationType();
    final PsiElement parent = expression.getParent();
    if (operator == PhpTokenTypes.opAND || operator == PhpTokenTypes.opOR) {
        /* binary expressions, already wrapped into parenthesises can be skipped */
        if (parent instanceof BinaryExpression) {
            final IElementType parentOperator = ((BinaryExpression) parent).getOperationType();
            if (parentOperator != operator && (parentOperator == PhpTokenTypes.opAND || parentOperator == PhpTokenTypes.opOR)) {
                final String replacement = '(' + expression.getText() + ')';
                holder.registerProblem(expression, message, new WrapItAsItIsFix(replacement));
                return true;
            }
        } else /* assignment dramatically changing precedence */
        if (OpenapiTypesUtil.isAssignment(parent) && !OpenapiTypesUtil.isStatementImpl(parent.getParent())) {
            final String replacement = '(' + expression.getText() + ')';
            holder.registerProblem(expression, message, new WrapItAsItIsFix(replacement));
            return true;
        }
    } else if (PhpTokenTypes.tsCOMPARE_OPS.contains(operator)) {
        if (OpenapiTypesUtil.isAssignment(parent) && parent.getParent() instanceof If) {
            final AssignmentExpression assignment = (AssignmentExpression) parent;
            final PsiElement assignedValue = assignment.getValue();
            if (assignedValue != null) {
                final String value = assignedValue.getText();
                final String replacement = assignment.getText().replace(value, '(' + value + ')');
                holder.registerProblem(parent, message, new WrapItAsItIsFix(replacement));
                return true;
            }
        } else if (PhpTokenTypes.tsCOMPARE_ORDER_OPS.contains(operator)) {
            final PsiElement left = expression.getLeftOperand();
            if (left instanceof UnaryExpression) {
                final UnaryExpression candidate = (UnaryExpression) left;
                if (OpenapiTypesUtil.is(candidate.getOperation(), PhpTokenTypes.opNOT)) {
                    final String value = candidate.getText();
                    final String replacement = expression.getText().replace(value, '(' + value + ')');
                    holder.registerProblem(expression, message, new WrapItAsItIsFix(replacement));
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) UnaryExpression(com.jetbrains.php.lang.psi.elements.UnaryExpression) If(com.jetbrains.php.lang.psi.elements.If) PsiElement(com.intellij.psi.PsiElement)

Example 5 with AssignmentExpression

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

the class OpAssignShortSyntaxInspector method buildVisitor.

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

        public void visitPhpAssignmentExpression(AssignmentExpression assignmentExpression) {
            PsiElement value = ExpressionSemanticUtil.getExpressionTroughParenthesis(assignmentExpression.getValue());
            /* try reaching operator in binary expression, expected as value */
            if (value instanceof BinaryExpression) {
                final BinaryExpression valueExpression = (BinaryExpression) value;
                final PsiElement operator = valueExpression.getOperation();
                if (null != operator) {
                    final IElementType operation = operator.getNode().getElementType();
                    final PsiElement leftOperand = valueExpression.getLeftOperand();
                    final PsiElement rightOperand = valueExpression.getRightOperand();
                    final PsiElement variable = assignmentExpression.getVariable();
                    /* ensure that's an operation we are looking for and pattern recognized */
                    if (null != variable && null != leftOperand && null != rightOperand && mapping.containsKey(operation) && OpeanapiEquivalenceUtil.areEqual(variable, leftOperand)) {
                        final String replacement = "%v% %o%= %e%".replace("%e%", rightOperand.getText()).replace("%o%", operator.getText()).replace("%v%", leftOperand.getText());
                        final String message = messagePattern.replace("%r%", replacement);
                        holder.registerProblem(assignmentExpression, message, new UseShorthandOperatorFix(replacement));
                    }
                }
            }
        }
    };
}
Also used : IElementType(com.intellij.psi.tree.IElementType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PsiElement (com.intellij.psi.PsiElement)7 AssignmentExpression (com.jetbrains.php.lang.psi.elements.AssignmentExpression)7 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)5 NotNull (org.jetbrains.annotations.NotNull)5 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)4 IElementType (com.intellij.psi.tree.IElementType)3 BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)3 UnaryExpression (com.jetbrains.php.lang.psi.elements.UnaryExpression)2 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)1 PhpDocComment (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment)1 PhpFile (com.jetbrains.php.lang.psi.PhpFile)1 ArrayAccessExpression (com.jetbrains.php.lang.psi.elements.ArrayAccessExpression)1 ArrayIndex (com.jetbrains.php.lang.psi.elements.ArrayIndex)1 Function (com.jetbrains.php.lang.psi.elements.Function)1 If (com.jetbrains.php.lang.psi.elements.If)1 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)1 ParameterList (com.jetbrains.php.lang.psi.elements.ParameterList)1 PhpPsiElement (com.jetbrains.php.lang.psi.elements.PhpPsiElement)1 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)1 Matcher (java.util.regex.Matcher)1