Search in sources :

Example 21 with FunctionReference

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

the class FopenBinaryUnsafeUsageInspector 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("fopen")) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length >= 2) {
                    /* verify if mode provided and has no 'b' already */
                    final StringLiteralExpression mode = ExpressionSemanticUtil.resolveAsStringLiteral(arguments[1]);
                    final String modeText = mode == null ? null : mode.getContents();
                    if (modeText != null && !modeText.isEmpty()) {
                        if (modeText.indexOf('b') != -1) {
                            final boolean isCorrectlyPlaced = modeText.endsWith("b") || modeText.endsWith("b+");
                            if (!isCorrectlyPlaced) {
                                holder.registerProblem(arguments[1], MessagesPresentationUtil.prefixWithEa(messageMisplacedBinaryMode), ProblemHighlightType.GENERIC_ERROR, new TheLocalFix(holder.getProject(), mode));
                            }
                        } else if (modeText.indexOf('t') != -1) {
                            if (ENFORCE_BINARY_MODIFIER_USAGE) {
                                holder.registerProblem(arguments[1], MessagesPresentationUtil.prefixWithEa(messageReplaceWithBinaryMode), new TheLocalFix(holder.getProject(), mode));
                            }
                        } else {
                            if (ENFORCE_BINARY_MODIFIER_USAGE) {
                                holder.registerProblem(arguments[1], MessagesPresentationUtil.prefixWithEa(messageUseBinaryMode), new TheLocalFix(holder.getProject(), mode));
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) 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 22 with FunctionReference

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

the class CaseInsensitiveStringFunctionsMissUseInspector 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 || !mapping.containsKey(functionName)) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if (arguments.length != 2 && arguments.length != 3) {
                return;
            }
            // resolve second parameter
            final StringLiteralExpression pattern = ExpressionSemanticUtil.resolveAsStringLiteral(arguments[1]);
            // might be not available - in another file (PhpStorm limitations)
            if (pattern == null || pattern.getContainingFile() != arguments[1].getContainingFile()) {
                return;
            }
            final String patternString = pattern.getContents();
            if (!StringUtils.isEmpty(patternString) && !patternString.matches(".*\\p{L}.*")) {
                final String replacementFunctionName = mapping.get(functionName);
                holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%f%", replacementFunctionName)), ProblemHighlightType.WEAK_WARNING, new TheLocalFix(replacementFunctionName));
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) 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 23 with FunctionReference

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

the class StrContainsCanBeUsedInspector method buildVisitor.

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

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            if (functionName != null && (functionName.equals("strpos") || functionName.equals("mb_strpos"))) {
                final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP800);
                if (isTargetVersion) {
                    final PsiElement[] arguments = reference.getParameters();
                    if (arguments.length == 2) {
                        final PsiElement context = reference.getParent();
                        if (context instanceof BinaryExpression) {
                            final BinaryExpression binary = (BinaryExpression) context;
                            final IElementType operation = binary.getOperationType();
                            final boolean isTarget = (operation == PhpTokenTypes.opNOT_IDENTICAL || operation == PhpTokenTypes.opIDENTICAL) && PhpLanguageUtil.isFalse(OpenapiElementsUtil.getSecondOperand(binary, reference));
                            if (isTarget) {
                                final String replacement = String.format("%s%sstr_contains(%s, %s)", operation == PhpTokenTypes.opIDENTICAL ? "! " : "", reference.getImmediateNamespaceName(), arguments[0].getText(), arguments[1].getText());
                                holder.registerProblem(binary, String.format(MessagesPresentationUtil.prefixWithEa(message), replacement), new UseStrContainsFix(replacement));
                            }
                        }
                    }
                }
            }
        }
    };
}
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 24 with FunctionReference

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

the class IsCountableCanBeUsedInspector method buildVisitor.

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

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            if (functionName != null && functionName.equals("is_array")) {
                final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP740);
                if (isTargetVersion) {
                    final PsiElement[] arguments = reference.getParameters();
                    final PsiElement parent = reference.getParent();
                    if (parent instanceof BinaryExpression && arguments.length == 1) {
                        final BinaryExpression binary = (BinaryExpression) parent;
                        final IElementType operation = binary.getOperationType();
                        if (operation == PhpTokenTypes.opOR) {
                            /* find the high-level binary expression */
                            BinaryExpression context = binary;
                            while (context instanceof BinaryExpression) {
                                PsiElement up = context.getParent();
                                while (up instanceof ParenthesizedExpression) {
                                    up = up.getParent();
                                }
                                if (up instanceof BinaryExpression && ((BinaryExpression) up).getOperationType() == PhpTokenTypes.opOR) {
                                    context = (BinaryExpression) up;
                                } else {
                                    break;
                                }
                            }
                            /* check the pattern */
                            final List<PsiElement> fragments = this.extract(context, PhpTokenTypes.opOR);
                            if (!fragments.isEmpty()) {
                                if (fragments.size() > 1) {
                                    for (final PsiElement fragment : fragments) {
                                        if (fragment != reference && fragment instanceof BinaryExpression) {
                                            final BinaryExpression candidate = (BinaryExpression) fragment;
                                            if (candidate.getOperationType() == PhpTokenTypes.kwINSTANCEOF) {
                                                final PsiElement clazz = candidate.getRightOperand();
                                                if (clazz instanceof ClassReference && "Countable".equals(((ClassReference) clazz).getName())) {
                                                    final PsiElement subject = candidate.getLeftOperand();
                                                    if (subject != null && OpenapiEquivalenceUtil.areEqual(subject, arguments[0])) {
                                                        final String argument = subject.getText();
                                                        holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(message), argument, argument, argument));
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                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) 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) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ClassReference(com.jetbrains.php.lang.psi.elements.ClassReference) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable) NotNull(org.jetbrains.annotations.NotNull)

Example 25 with FunctionReference

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

the class IsIterableCanBeUsedInspector method buildVisitor.

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

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            if (functionName != null && functionName.equals("is_array")) {
                final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP710);
                if (isTargetVersion) {
                    final PsiElement[] arguments = reference.getParameters();
                    final PsiElement parent = reference.getParent();
                    if (parent instanceof BinaryExpression && arguments.length == 1) {
                        final BinaryExpression binary = (BinaryExpression) parent;
                        final IElementType operation = binary.getOperationType();
                        if (operation == PhpTokenTypes.opOR) {
                            /* find the high-level binary expression */
                            BinaryExpression context = binary;
                            while (context instanceof BinaryExpression) {
                                PsiElement up = context.getParent();
                                while (up instanceof ParenthesizedExpression) {
                                    up = up.getParent();
                                }
                                if (up instanceof BinaryExpression && ((BinaryExpression) up).getOperationType() == PhpTokenTypes.opOR) {
                                    context = (BinaryExpression) up;
                                } else {
                                    break;
                                }
                            }
                            /* check the pattern */
                            final List<PsiElement> fragments = this.extract(context, PhpTokenTypes.opOR);
                            if (!fragments.isEmpty()) {
                                if (fragments.size() > 1) {
                                    for (final PsiElement fragment : fragments) {
                                        if (fragment != reference && fragment instanceof BinaryExpression) {
                                            final BinaryExpression candidate = (BinaryExpression) fragment;
                                            if (candidate.getOperationType() == PhpTokenTypes.kwINSTANCEOF) {
                                                final PsiElement clazz = candidate.getRightOperand();
                                                if (clazz instanceof ClassReference && "Traversable".equals(((ClassReference) clazz).getName())) {
                                                    final PsiElement subject = candidate.getLeftOperand();
                                                    if (subject != null && OpenapiEquivalenceUtil.areEqual(subject, arguments[0])) {
                                                        final String argument = subject.getText();
                                                        holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(message), argument, argument, argument));
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                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) 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) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ClassReference(com.jetbrains.php.lang.psi.elements.ClassReference) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)58 PsiElement (com.intellij.psi.PsiElement)55 NotNull (org.jetbrains.annotations.NotNull)46 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)43 BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)16 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)15 IElementType (com.intellij.psi.tree.IElementType)11 PhpUnitAssertFixer (com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer)9 ArrayCreationExpression (com.jetbrains.php.lang.psi.elements.ArrayCreationExpression)6 UnaryExpression (com.jetbrains.php.lang.psi.elements.UnaryExpression)6 Function (com.jetbrains.php.lang.psi.elements.Function)5 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)5 ParameterList (com.jetbrains.php.lang.psi.elements.ParameterList)5 PhpLanguageLevel (com.jetbrains.php.config.PhpLanguageLevel)4 ArrayList (java.util.ArrayList)4 Nullable (org.jetbrains.annotations.Nullable)4 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)3 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)3 ArrayAccessExpression (com.jetbrains.php.lang.psi.elements.ArrayAccessExpression)3 HashSet (java.util.HashSet)3