Search in sources :

Example 16 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference 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(MessagesPresentationUtil.prefixWithEa(messageMisuse), replacement), new UseElementPushFix(replacement));
                    }
                }
            }
        }

        @Override
        public void visitPhpArrayAccessExpression(@NotNull ArrayAccessExpression expression) {
            if (REPORT_EXCESSIVE_COUNT_CALLS) {
                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 (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 && OpenapiEquivalenceUtil.areEqual(container, arguments[0])) {
                                            holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(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 17 with FunctionReference

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

the class StrtotimeUsageInspector 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("strtotime")) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if (arguments.length == 0 || arguments.length > 2) {
                return;
            }
            /* handle case: strtotime("now") -> time() */
            if (arguments.length == 1) {
                if (arguments[0] instanceof StringLiteralExpression) {
                    final StringLiteralExpression pattern = (StringLiteralExpression) arguments[0];
                    if (pattern.getContents().equalsIgnoreCase("now")) {
                        holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageUseTime), new UseTimeFunctionLocalFix());
                    }
                }
            } else /* handle case: strtotime(..., time()) -> date(...) */
            if (arguments.length == 2) {
                if (OpenapiTypesUtil.isFunctionReference(arguments[1])) {
                    final FunctionReference candidate = (FunctionReference) arguments[1];
                    final String candidateName = candidate.getName();
                    if (candidateName != null && candidateName.equals("time") && this.isFromRootNamespace(candidate)) {
                        final String replacement = "strtotime(%a%)".replace("%a%", arguments[0].getText());
                        holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageDropTime), ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DropTimeFunctionCallLocalFix(replacement));
                    }
                }
            }
        }
    };
}
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 18 with FunctionReference

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

the class GetDebugTypeCanBeUsedInspector method buildVisitor.

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

        @Override
        public void visitPhpTernaryExpression(@NotNull TernaryExpression ternary) {
            if (!ternary.isShort()) {
                final PsiElement condition = ternary.getCondition();
                if (OpenapiTypesUtil.isFunctionReference(condition)) {
                    final FunctionReference reference = (FunctionReference) condition;
                    final String functionName = reference.getName();
                    if (functionName != null && functionName.equals("is_object")) {
                        final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP800);
                        if (isTargetVersion) {
                            final PsiElement[] arguments = reference.getParameters();
                            if (arguments.length == 1 && arguments[0] != null) {
                                final PsiElement positive = ternary.getTrueVariant();
                                final PsiElement negative = ternary.getFalseVariant();
                                if (positive != null && negative != null) {
                                    final boolean isTarget = this.is(positive, "get_class", arguments[0]) && this.is(negative, "gettype", arguments[0]);
                                    if (isTarget && this.isFromRootNamespace(reference)) {
                                        final String replacement = String.format("%sget_debug_type(%s)", reference.getImmediateNamespaceName(), arguments[0].getText());
                                        holder.registerProblem(ternary, String.format(MessagesPresentationUtil.prefixWithEa(message), replacement), new UseGetDebugTypeFix(replacement));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private boolean is(@NotNull PsiElement candidate, @NotNull String targetName, @NotNull PsiElement targetArgument) {
            if (OpenapiTypesUtil.isFunctionReference(candidate)) {
                final FunctionReference reference = (FunctionReference) candidate;
                final String functionName = reference.getName();
                if (functionName != null && functionName.equals(targetName)) {
                    final PsiElement[] arguments = reference.getParameters();
                    if (arguments.length == 1 && arguments[0] != null) {
                        return OpenapiEquivalenceUtil.areEqual(arguments[0], targetArgument) && this.isFromRootNamespace(reference);
                    }
                }
            }
            return false;
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) TernaryExpression(com.jetbrains.php.lang.psi.elements.TernaryExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 19 with FunctionReference

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

the class DynamicCallsToScopeIntrospectionInspector method buildVisitor.

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

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            if (PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP710)) {
                final String functionName = reference.getName();
                if (functionName != null) {
                    /* discover target element */
                    final PsiElement target;
                    if (functionName.isEmpty()) {
                        final PsiElement[] children = reference.getChildren();
                        target = children.length == 2 ? children[0] : null;
                    } else if (callbacksPositions.containsKey(functionName)) {
                        final int callbackPosition = callbacksPositions.get(functionName);
                        final PsiElement[] arguments = reference.getParameters();
                        target = arguments.length >= callbackPosition + 1 ? arguments[callbackPosition] : null;
                    } else {
                        target = null;
                    }
                    /* discover the target function */
                    if (target != null) {
                        final StringLiteralExpression literal = ExpressionSemanticUtil.resolveAsStringLiteral(target);
                        if (literal != null) {
                            final String raw = PhpStringUtil.unescapeText(literal.getContents(), literal.isSingleQuote());
                            final String callback = raw.startsWith("\\") ? raw.substring(1) : raw;
                            if (targetCalls.containsKey(callback)) {
                                holder.registerProblem(target, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), callback));
                            }
                        }
                    }
                }
            }
        }
    };
}
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 20 with FunctionReference

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

the class CascadingDirnameCallsInspector 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("dirname")) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if (arguments.length != 1 && arguments.length != 2) {
                return;
            }
            /* require PHP7+, where 2nd parameter has been added */
            if (PhpLanguageLevel.get(holder.getProject()).below(PhpLanguageLevel.PHP700)) {
                return;
            }
            /* don't report nested calls, we want to report the one on top level */
            final PsiElement parent = reference.getParent();
            if (parent instanceof ParameterList && parent.getParent() instanceof FunctionReference) {
                final FunctionReference parentReference = (FunctionReference) parent.getParent();
                final String parentName = parentReference.getName();
                if (parentName != null && parentName.equals("dirname")) {
                    final PsiElement[] parentArguments = parentReference.getParameters();
                    if (parentArguments.length == 1 || parentArguments.length == 2) {
                        return;
                    }
                }
            }
            int directoryLevel = 0;
            PsiElement argument = null;
            final List<PsiElement> levels = new ArrayList<>();
            FunctionReference current = reference;
            while (current instanceof FunctionReference) {
                final String currentName = current.getName();
                if (currentName == null || !currentName.equals("dirname")) {
                    break;
                }
                final PsiElement[] currentArguments = current.getParameters();
                if (currentArguments.length == 1) {
                    argument = currentArguments[0];
                    ++directoryLevel;
                } else if (currentArguments.length == 2) {
                    argument = currentArguments[0];
                    levels.add(currentArguments[1]);
                } else {
                    break;
                }
                if (!(currentArguments[0] instanceof FunctionReference)) {
                    break;
                }
                current = (FunctionReference) currentArguments[0];
            }
            /* if no nested dirname calls, stop analysis */
            if (current == reference) {
                levels.clear();
                return;
            }
            /* if we have 1+ nested call (top-level one is not considered) */
            if (argument != null && arguments[0] != argument) {
                /* process extracted level expressions: numbers to sum-up, expressions to stay */
                final List<String> reported = new ArrayList<>();
                for (PsiElement levelEntry : levels) {
                    try {
                        directoryLevel += Integer.parseInt(levelEntry.getText());
                    } catch (NumberFormatException fail) {
                        reported.add(levelEntry.getText());
                    }
                }
                levels.clear();
                /* do not report cases with one level extraction */
                if (1 == directoryLevel && reported.isEmpty()) {
                    return;
                }
                /* generate the replacement expression */
                reported.add(0, String.valueOf(directoryLevel));
                final String replacement = "dirname(%a%, %l%)".replace("%a%", argument.getText()).replace("%l%", String.join(" + ", reported));
                reported.clear();
                holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%e%", replacement)), new TheLocalFix(replacement));
            }
        }
    };
}
Also used : ArrayList(java.util.ArrayList) NotNull(org.jetbrains.annotations.NotNull) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ParameterList(com.jetbrains.php.lang.psi.elements.ParameterList) PsiElement(com.intellij.psi.PsiElement) 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