Search in sources :

Example 1 with ConstantReference

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

the class IssetAndNullComparisonStrategy method apply.

public static boolean apply(@NotNull List<PsiElement> conditions, @NotNull ProblemsHolder holder) {
    /* first ensure that we have null identity checks at all */
    final Map<PsiElement, PsiElement> nullTestSubjects = new HashMap<>();
    for (final PsiElement oneCondition : conditions) {
        if (oneCondition instanceof BinaryExpression) {
            final BinaryExpression expression = (BinaryExpression) oneCondition;
            /* we need only !== and === operations */
            final IElementType operator = expression.getOperationType();
            if (operator != PhpTokenTypes.opIDENTICAL && operator != PhpTokenTypes.opNOT_IDENTICAL) {
                continue;
            }
            /* quickly check if any operands is a constant */
            final PsiElement left = expression.getLeftOperand();
            final PsiElement right = expression.getRightOperand();
            if (!(left instanceof ConstantReference) && !(right instanceof ConstantReference)) {
                continue;
            }
            /* store null test subjects */
            if (PhpLanguageUtil.isNull(right)) {
                if (null != left) {
                    nullTestSubjects.put(expression, left);
                }
                continue;
            }
            if (PhpLanguageUtil.isNull(left)) {
                if (null != right) {
                    nullTestSubjects.put(expression, right);
                }
            // continue;
            }
        }
    }
    if (0 == nullTestSubjects.size()) {
        return false;
    }
    boolean hasReportedExpressions = false;
    for (final PsiElement oneCondition : conditions) {
        /* do not process null identity checks */
        if (nullTestSubjects.containsKey(oneCondition)) {
            continue;
        }
        /* unwrap ! and () */
        PsiElement issetCandidate = oneCondition;
        if (issetCandidate instanceof UnaryExpression) {
            final PsiElement notOperatorCandidate = ((UnaryExpression) issetCandidate).getOperation();
            if (null != notOperatorCandidate && notOperatorCandidate.getNode().getElementType() == PhpTokenTypes.opNOT) {
                PsiElement invertedValue = ((UnaryExpression) issetCandidate).getValue();
                invertedValue = ExpressionSemanticUtil.getExpressionTroughParenthesis(invertedValue);
                if (null == invertedValue) {
                    continue;
                }
                issetCandidate = invertedValue;
            }
        }
        if (!(issetCandidate instanceof PhpIsset) || 0 == ((PhpIsset) issetCandidate).getVariables().length) {
            continue;
        }
        /* process isset constructions */
        for (final PsiElement issetArgument : ((PhpIsset) issetCandidate).getVariables()) {
            /* compare with know null identity checked subjects */
            for (final Map.Entry<PsiElement, PsiElement> nullTestPair : nullTestSubjects.entrySet()) {
                if (!OpeanapiEquivalenceUtil.areEqual(nullTestPair.getValue(), issetArgument)) {
                    continue;
                }
                hasReportedExpressions = true;
                final PsiElement nullTestExpression = nullTestPair.getKey();
                final String message = messagePattern.replace("%e%", nullTestExpression.getText());
                holder.registerProblem(nullTestExpression, message, ProblemHighlightType.WEAK_WARNING);
            }
        }
    }
    nullTestSubjects.clear();
    return hasReportedExpressions;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) ConstantReference(com.jetbrains.php.lang.psi.elements.ConstantReference) BinaryExpression(com.jetbrains.php.lang.psi.elements.BinaryExpression) HashMap(java.util.HashMap) UnaryExpression(com.jetbrains.php.lang.psi.elements.UnaryExpression) HashMap(java.util.HashMap) Map(java.util.Map) PsiElement(com.intellij.psi.PsiElement) PhpIsset(com.jetbrains.php.lang.psi.elements.PhpIsset)

Example 2 with ConstantReference

use of com.jetbrains.php.lang.psi.elements.ConstantReference in project idea-php-typo3-plugin by cedricziel.

the class ConstantMatcherInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) {
    return new PhpElementVisitor() {

        @Override
        public void visitPhpElement(PhpPsiElement element) {
            if (!PlatformPatterns.psiElement(PhpElementTypes.CONSTANT_REF).accepts(element)) {
                return;
            }
            ConstantReference constantReference = (ConstantReference) element;
            Set<String> constants = getRemovedConstantsFQNs(constantReference);
            if (constants.contains(constantReference.getFQN())) {
                problemsHolder.registerProblem(element, "Constant removed with TYPO3 9, consider using an alternative");
            }
        }
    };
}
Also used : ConstantReference(com.jetbrains.php.lang.psi.elements.ConstantReference) PhpElementVisitor(com.jetbrains.php.lang.psi.visitors.PhpElementVisitor) PhpPsiElement(com.jetbrains.php.lang.psi.elements.PhpPsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with ConstantReference

use of com.jetbrains.php.lang.psi.elements.ConstantReference 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 4 with ConstantReference

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

the class AssertConstantStrategy method apply.

public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
    boolean result = false;
    if (targetMapping.containsKey(methodName)) {
        final PsiElement[] arguments = reference.getParameters();
        if (arguments.length > 1) {
            for (final PsiElement argument : arguments) {
                if (argument instanceof ConstantReference) {
                    final String constantName = ((ConstantReference) argument).getName();
                    if (constantName != null) {
                        final String constantNameNormalized = constantName.toLowerCase();
                        if (targetConstants.contains(constantNameNormalized)) {
                            final String suggestedAssertion = String.format(targetMapping.get(methodName), StringUtils.capitalize(constantNameNormalized));
                            final String[] suggestedArguments = new String[arguments.length - 1];
                            suggestedArguments[0] = Arrays.stream(arguments).filter(a -> a != argument).findFirst().get().getText();
                            if (arguments.length > 2) {
                                suggestedArguments[1] = arguments[2].getText();
                            }
                            holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
                            result = true;
                            break;
                        }
                    }
                }
            }
        }
    }
    return result;
}
Also used : ConstantReference(com.jetbrains.php.lang.psi.elements.ConstantReference) PhpUnitAssertFixer(com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer) PsiElement(com.intellij.psi.PsiElement)

Example 5 with ConstantReference

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

the class JsonEncodingApiUsageInspector 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) {
                if (functionName.equals("json_decode") && this.isFromRootNamespace(reference)) {
                    final PsiElement[] arguments = reference.getParameters();
                    if (HARDEN_DECODING_RESULT_TYPE && arguments.length == 1) {
                        final String replacement = String.format("%sjson_decode(%s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), DECODE_AS_ARRAY ? "true" : "false");
                        holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageResultType), DECODE_AS_ARRAY ? new DecodeIntoArrayFix(replacement) : new DecodeIntoObjectFix(replacement));
                    }
                    if (HARDEN_ERRORS_HANDLING && arguments.length > 0 && PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP730)) {
                        final boolean hasFlag = arguments.length >= 4 && this.hasStricterHandlingFlags(arguments[3]);
                        if (!hasFlag) {
                            final String replacement = String.format("%sjson_decode(%s, %s, %s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), arguments.length > 1 ? arguments[1].getText() : (HARDEN_DECODING_RESULT_TYPE && DECODE_AS_ARRAY ? "true" : "false"), arguments.length > 2 ? arguments[2].getText() : "512", arguments.length > 3 ? "JSON_THROW_ON_ERROR | " + arguments[3].getText() : "JSON_THROW_ON_ERROR");
                            holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageErrorsHandling), new HardenErrorsHandlingFix(replacement));
                        }
                    }
                } else if (functionName.equals("json_encode") && this.isFromRootNamespace(reference)) {
                    if (HARDEN_ERRORS_HANDLING && PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP730)) {
                        final PsiElement[] arguments = reference.getParameters();
                        final boolean hasFlag = arguments.length >= 2 && this.hasStricterHandlingFlags(arguments[1]);
                        if (!hasFlag && arguments.length > 0) {
                            final String replacement;
                            if (arguments.length > 2) {
                                replacement = String.format("%sjson_encode(%s, %s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), "JSON_THROW_ON_ERROR | " + arguments[1].getText(), arguments[2].getText());
                            } else {
                                replacement = String.format("%sjson_encode(%s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), arguments.length > 1 ? "JSON_THROW_ON_ERROR | " + arguments[1].getText() : "JSON_THROW_ON_ERROR");
                            }
                            holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageErrorsHandling), new HardenErrorsHandlingFix(replacement));
                        }
                    }
                }
            }
        }

        private boolean hasStricterHandlingFlags(@NotNull PsiElement argument) {
            boolean hasFlag = false;
            final Set<PsiElement> options = argument instanceof ConstantReference ? new HashSet<>(Collections.singletonList(argument)) : PossibleValuesDiscoveryUtil.discover(argument);
            if (options.size() == 1) {
                final PsiElement option = options.iterator().next();
                if (OpenapiTypesUtil.isNumber(option)) {
                    /* properly resolved value */
                    hasFlag = strictHandlingFlags.containsValue(option.getText());
                } else if (option instanceof ConstantReference) {
                    /* constant value resolution fails for some reason */
                    hasFlag = strictHandlingFlags.containsKey(((ConstantReference) option).getName());
                } else {
                    /* a complex case like local variable or implicit flags combination */
                    hasFlag = PsiTreeUtil.findChildrenOfType(option, ConstantReference.class).stream().anyMatch(r -> strictHandlingFlags.containsKey(r.getName()));
                }
            }
            options.clear();
            return hasFlag;
        }
    };
}
Also used : ConstantReference(com.jetbrains.php.lang.psi.elements.ConstantReference) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ConstantReference (com.jetbrains.php.lang.psi.elements.ConstantReference)7 PsiElement (com.intellij.psi.PsiElement)6 NotNull (org.jetbrains.annotations.NotNull)4 IElementType (com.intellij.psi.tree.IElementType)2 BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)2 PhpPsiElement (com.jetbrains.php.lang.psi.elements.PhpPsiElement)2 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)2 PhpElementVisitor (com.jetbrains.php.lang.psi.visitors.PhpElementVisitor)2 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)2 GroupNames (com.intellij.codeInsight.daemon.GroupNames)1 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)1 PlatformPatterns (com.intellij.patterns.PlatformPatterns)1 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)1 PsiFile (com.intellij.psi.PsiFile)1 FilenameIndex (com.intellij.psi.search.FilenameIndex)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)1 PhpInspection (com.jetbrains.php.lang.inspections.PhpInspection)1 PhpElementTypes (com.jetbrains.php.lang.parser.PhpElementTypes)1 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)1