Search in sources :

Example 6 with Function

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

the class UnusedGotoLabelInspector method buildVisitor.

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

        @Override
        public void visitPhpGotoLabel(@NotNull PhpGotoLabel label) {
            final Function function = ExpressionSemanticUtil.getScope(label);
            final GroupStatement body = null == function ? null : ExpressionSemanticUtil.getGroupStatement(function);
            if (body != null && ExpressionSemanticUtil.countExpressionsInGroup(body) > 0) {
                /* process goto statements and drop used from existing */
                final Collection<PhpGoto> references = PsiTreeUtil.findChildrenOfType(body, PhpGoto.class);
                if (!references.isEmpty()) {
                    final String labelName = label.getName();
                    for (final PhpGoto gotoExpression : references) {
                        final String labelUsed = gotoExpression.getName();
                        if (null != labelUsed && labelUsed.equals(labelName)) {
                            references.clear();
                            return;
                        }
                    }
                    references.clear();
                }
                /* TODO: marks as unused instead, see https://youtrack.jetbrains.com/issue/WI-34508 */
                holder.registerProblem(label, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.LIKE_DEPRECATED, new TheLocalFix());
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) GroupStatement(com.jetbrains.php.lang.psi.elements.GroupStatement) NotNull(org.jetbrains.annotations.NotNull) PhpGotoLabel(com.jetbrains.php.lang.psi.elements.PhpGotoLabel) PhpGoto(com.jetbrains.php.lang.psi.elements.PhpGoto) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with Function

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

the class UselessUnsetInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
    /* foreach is also a case, but there is no way to get flow entry point in actual JB platform API */
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpMethod(@NotNull Method method) {
            this.inspectUsages(method.getParameters(), method);
        }

        @Override
        public void visitPhpFunction(@NotNull Function function) {
            this.inspectUsages(function.getParameters(), function);
        }

        private void inspectUsages(@NotNull Parameter[] parameters, @NotNull PhpScopeHolder scope) {
            if (parameters.length > 0) {
                final PhpEntryPointInstruction entry = scope.getControlFlow().getEntryPoint();
                for (final Parameter parameter : parameters) {
                    final String parameterName = parameter.getName();
                    if (!parameterName.isEmpty()) {
                        for (final PhpAccessVariableInstruction usage : OpenapiControlFlowUtil.getFollowingVariableAccessInstructions(entry, parameterName)) {
                            final PsiElement expression = usage.getAnchor();
                            final PsiElement parent = expression.getParent();
                            if (parent instanceof PhpUnset) {
                                int unsetParametersCount = ((PhpUnset) parent).getArguments().length;
                                final PsiElement target = (unsetParametersCount == 1 ? parent : expression);
                                holder.registerProblem(target, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) PhpAccessVariableInstruction(com.jetbrains.php.codeInsight.controlFlow.instructions.PhpAccessVariableInstruction) PhpEntryPointInstruction(com.jetbrains.php.codeInsight.controlFlow.instructions.PhpEntryPointInstruction) PhpScopeHolder(com.jetbrains.php.codeInsight.PhpScopeHolder) PhpUnset(com.jetbrains.php.lang.psi.elements.PhpUnset) Parameter(com.jetbrains.php.lang.psi.elements.Parameter) Method(com.jetbrains.php.lang.psi.elements.Method) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with Function

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

the class InconsistentQueryBuildInspector 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 function = reference.getName();
            if (function != null && function.equals("ksort")) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length == 1) {
                    /* pre-condition satisfied, now check if http_build_query used in the scope */
                    final Function scope = ExpressionSemanticUtil.getScope(reference);
                    if (scope != null) {
                        for (final FunctionReference call : PsiTreeUtil.findChildrenOfType(scope, FunctionReference.class)) {
                            /* skip inspected call and calls without arguments */
                            if (call == reference || !OpenapiTypesUtil.isFunctionReference(call)) {
                                continue;
                            }
                            /* skip non-target function */
                            final String callFunctionName = call.getName();
                            if (callFunctionName == null || !callFunctionName.equals("http_build_query")) {
                                continue;
                            }
                            final PsiElement[] callArguments = call.getParameters();
                            if (callArguments.length == 0) {
                                continue;
                            }
                            /* pattern match: ksort and http_build_query operating on the same expression */
                            if (OpeanapiEquivalenceUtil.areEqual(callArguments[0], arguments[0])) {
                                final String message = messagePattern.replace("%a%", arguments[0].getText());
                                holder.registerProblem(reference, message, new TheLocalFix());
                                break;
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with Function

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

the class ImplicitMagicMethodCallInspector method buildVisitor.

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

        @Override
        public void visitPhpMethodReference(@NotNull MethodReference reference) {
            final String methodName = reference.getName();
            if (methodName != null && methods.contains(methodName)) {
                /* Pattern 1: direct calls ob objects */
                final String referenceObject = reference.getFirstChild().getText().trim();
                if (!referenceObject.equals("$this") && !this.isTestContext(reference)) {
                    if (!(reference.getFirstChild() instanceof ClassReference) && !referenceObject.equals("parent")) {
                        /* __toString is a special case */
                        if (SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
                            final String message = patternStringCasting.replace("%o%", referenceObject);
                            holder.registerProblem(reference, message, new UseStringCastingLocalFix());
                            return;
                        }
                        /* allow calling __toString, as a developer don't want hints on this */
                        if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
                            return;
                        }
                        /* generally reported cases */
                        holder.registerProblem(reference, message);
                        return;
                    }
                    /* Pattern 2: internal calls inside class methods */
                    final Function method = ExpressionSemanticUtil.getScope(reference);
                    if (null != method && !method.getName().equals(methodName)) {
                        /* allow __construct inside unserialize */
                        if (methodName.equals("__construct") && method.getName().equals("unserialize")) {
                            return;
                        }
                        /* allow calling __toString, as a developer don't want hints on this */
                        if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
                            return;
                        }
                        holder.registerProblem(reference, message);
                    }
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) ClassReference(com.jetbrains.php.lang.psi.elements.ClassReference) NotNull(org.jetbrains.annotations.NotNull) NotNull(org.jetbrains.annotations.NotNull)

Example 10 with Function

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

the class CallableReferenceNameMismatchInspector method buildVisitor.

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

        @Override
        public void visitPhpMethodReference(@NotNull MethodReference reference) {
            final String methodName = reference.getName();
            if (methodName != null && !methodName.isEmpty()) {
                this.inspectCaseIdentity(reference, methodName, false);
            }
        }

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            if (functionName != null && !functionName.isEmpty() && !cache.containsKey(functionName)) {
                this.inspectCaseIdentity(reference, functionName, true);
            }
        }

        private void inspectCaseIdentity(@NotNull FunctionReference reference, @NotNull String referenceName, boolean useCache) {
            /* resolve callable and ensure the case matches */
            final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
            if (resolved instanceof Function) {
                final Function function = (Function) resolved;
                final String realName = function.getName();
                if (useCache && function.getFQN().equals('\\' + realName)) {
                    cache.putIfAbsent(realName, realName);
                }
                if (!realName.equals(referenceName) && realName.equalsIgnoreCase(referenceName)) {
                    holder.registerProblem(reference, messagePattern.replace("%n%", realName), new CallableReferenceNameMismatchQuickFix());
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

Function (com.jetbrains.php.lang.psi.elements.Function)11 NotNull (org.jetbrains.annotations.NotNull)9 PsiElement (com.intellij.psi.PsiElement)8 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)8 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)5 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)3 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)2 GroupStatement (com.jetbrains.php.lang.psi.elements.GroupStatement)2 Method (com.jetbrains.php.lang.psi.elements.Method)2 Parameter (com.jetbrains.php.lang.psi.elements.Parameter)2 PhpUnitAssertFixer (com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer)2 MessagesPresentationUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil)2 List (java.util.List)2 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)1 PhpIndex (com.jetbrains.php.PhpIndex)1 PhpScopeHolder (com.jetbrains.php.codeInsight.PhpScopeHolder)1 PhpAccessVariableInstruction (com.jetbrains.php.codeInsight.controlFlow.instructions.PhpAccessVariableInstruction)1 PhpEntryPointInstruction (com.jetbrains.php.codeInsight.controlFlow.instructions.PhpEntryPointInstruction)1 PhpFile (com.jetbrains.php.lang.psi.PhpFile)1 ClassReference (com.jetbrains.php.lang.psi.elements.ClassReference)1