Search in sources :

Example 11 with MethodReference

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

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

the class UnnecessaryAssertionInspector method buildVisitor.

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

        @Override
        public void visitPhpMethodReference(@NotNull MethodReference reference) {
            final Project project = holder.getProject();
            final PhpLanguageLevel php = PhpProjectConfigurationFacade.getInstance(project).getLanguageLevel();
            if (!php.hasFeature(PhpLanguageFeature.RETURN_TYPES)) {
                return;
            }
            final String methodName = reference.getName();
            if (methodName != null && methodName.startsWith("assert") && targetPositions.containsKey(methodName)) {
                final int position = targetPositions.get(methodName);
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length >= position + 1 && arguments[position] instanceof FunctionReference) {
                    final FunctionReference call = (FunctionReference) arguments[position];
                    final PsiElement function = OpenapiResolveUtil.resolveReference(call);
                    if (function instanceof Function && OpenapiElementsUtil.getReturnType((Function) function) != null) {
                        final PhpType resolved = OpenapiResolveUtil.resolveType(call, project);
                        if (resolved != null && !resolved.hasUnknown() && resolved.size() == 1) {
                            final String expected = targetType.get(methodName);
                            if (expected == null || resolved.getTypes().stream().anyMatch(type -> Types.getType(type).equals(expected))) {
                                holder.registerProblem(reference, message);
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) Types(com.kalessil.phpStorm.phpInspectionsEA.utils.Types) PhpLanguageFeature(com.jetbrains.php.config.PhpLanguageFeature) Function(com.jetbrains.php.lang.psi.elements.Function) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) HashMap(java.util.HashMap) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) OpenapiElementsUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiElementsUtil) OpenapiResolveUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil) PhpLanguageLevel(com.jetbrains.php.config.PhpLanguageLevel) Map(java.util.Map) PsiElement(com.intellij.psi.PsiElement) Project(com.intellij.openapi.project.Project) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) PhpProjectConfigurationFacade(com.jetbrains.php.config.PhpProjectConfigurationFacade) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) NotNull(org.jetbrains.annotations.NotNull) PhpLanguageLevel(com.jetbrains.php.config.PhpLanguageLevel) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Project(com.intellij.openapi.project.Project) Function(com.jetbrains.php.lang.psi.elements.Function) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 13 with MethodReference

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

the class QueryUsageStrategy method apply.

public static void apply(@NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
    final String methodName = reference.getName();
    if (methodName == null || !methodName.equals("execute")) {
        return;
    }
    final PsiElement[] arguments = reference.getParameters();
    if (arguments.length > 0) {
        return;
    }
    /* inspect preceding and succeeding statement */
    final PsiElement parent = reference.getParent();
    PsiElement predecessor = null;
    if (OpenapiTypesUtil.isStatementImpl(parent)) {
        predecessor = ((Statement) parent).getPrevPsiSibling();
        while (predecessor instanceof PhpDocComment) {
            predecessor = ((PhpDocComment) predecessor).getPrevPsiSibling();
        }
    }
    if (null != predecessor && predecessor.getFirstChild() instanceof AssignmentExpression) {
        /* predecessor needs to be an assignment */
        final AssignmentExpression assignment = (AssignmentExpression) predecessor.getFirstChild();
        if (!(assignment.getValue() instanceof MethodReference)) {
            return;
        }
        final MethodReference precedingReference = (MethodReference) assignment.getValue();
        if (MethodIdentityUtil.isReferencingMethod(precedingReference, "\\PDO", "prepare")) {
            final PsiElement variableAssigned = assignment.getVariable();
            final PsiElement variableUsed = reference.getClassReference();
            if (variableAssigned != null && variableUsed != null && OpeanapiEquivalenceUtil.areEqual(variableAssigned, variableUsed)) {
                holder.registerProblem(reference, message, new UseQueryFix(precedingReference));
            }
        }
    }
}
Also used : PhpDocComment(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment) AssignmentExpression(com.jetbrains.php.lang.psi.elements.AssignmentExpression) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) PsiElement(com.intellij.psi.PsiElement)

Example 14 with MethodReference

use of com.jetbrains.php.lang.psi.elements.MethodReference 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)

Example 15 with MethodReference

use of com.jetbrains.php.lang.psi.elements.MethodReference in project yii2support by nvlad.

the class ViewMissedPhpDocInspection method buildVisitor.

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

        @Override
        public void visitPhpFile(PhpFile PhpFile) {
            Project project = PhpFile.getProject();
            ViewResolve resolve = ViewUtil.resolveView(PhpFile.getVirtualFile(), project);
            if (resolve == null) {
                return;
            }
            Map<String, String> params = getVariables(PhpFile);
            Map<String, String> declaredVariables = new HashMap<>();
            Collection<PhpDocVariable> variableCollection = PsiTreeUtil.findChildrenOfType(PhpFile, PhpDocVariable.class);
            for (PhpDocVariable variable : variableCollection) {
                declaredVariables.put(variable.getName(), variable.getType().toString());
            }
            Map<String, String> missedVariables = new HashMap<>();
            for (String variableName : params.keySet()) {
                if (!declaredVariables.containsKey(variableName)) {
                    missedVariables.put(variableName, params.get(variableName));
                }
            }
            if (missedVariables.isEmpty()) {
                return;
            }
            String problemDescription = "Missed View variable declaration.";
            ViewMissedPhpDocLocalQuickFix quickFix = new ViewMissedPhpDocLocalQuickFix(PhpFile, missedVariables);
            problemsHolder.registerProblem(PhpFile, problemDescription, quickFix);
        }

        private Map<String, String> getVariables(PhpFile phpFile) {
            Collection<PsiReference> references = ReferencesSearch.search(phpFile).findAll();
            Map<String, String> result = new HashMap<>();
            Map<String, PhpType> viewArgumentCollection = new LinkedHashMap<>();
            for (PsiReference reference : references) {
                MethodReference methodReference = PsiTreeUtil.getParentOfType(reference.getElement(), MethodReference.class);
                if (methodReference == null) {
                    continue;
                }
                Map<String, PhpType> params = RenderUtil.getViewArguments(methodReference);
                for (Map.Entry<String, PhpType> entry : params.entrySet()) {
                    if (viewArgumentCollection.containsKey(entry.getKey())) {
                        PhpType.PhpTypeBuilder typeBuilder = new PhpType.PhpTypeBuilder();
                        typeBuilder.add(viewArgumentCollection.get(entry.getKey()));
                        typeBuilder.add(entry.getValue());
                        viewArgumentCollection.replace(entry.getKey(), typeBuilder.build());
                    } else {
                        viewArgumentCollection.put(entry.getKey(), entry.getValue());
                    }
                }
            }
            for (String key : viewArgumentCollection.keySet()) {
                result.put(key, viewArgumentCollection.get(key).toString());
            }
            return result;
        }
    };
}
Also used : PhpFile(com.jetbrains.php.lang.psi.PhpFile) PhpElementVisitor(com.jetbrains.php.lang.psi.visitors.PhpElementVisitor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ViewResolve(com.nvlad.yii2support.views.entities.ViewResolve) PsiReference(com.intellij.psi.PsiReference) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) LinkedHashMap(java.util.LinkedHashMap) Project(com.intellij.openapi.project.Project) PhpDocVariable(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)19 PsiElement (com.intellij.psi.PsiElement)15 NotNull (org.jetbrains.annotations.NotNull)9 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)7 PhpType (com.jetbrains.php.lang.psi.resolve.types.PhpType)7 Project (com.intellij.openapi.project.Project)5 ParameterList (com.jetbrains.php.lang.psi.elements.ParameterList)4 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)4 PhpElementVisitor (com.jetbrains.php.lang.psi.visitors.PhpElementVisitor)4 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)4 ViewResolve (com.nvlad.yii2support.views.entities.ViewResolve)4 Function (com.jetbrains.php.lang.psi.elements.Function)3 ViewInfo (com.nvlad.yii2support.views.entities.ViewInfo)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 Nullable (org.jetbrains.annotations.Nullable)3 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)2 ArrayCreationExpression (com.jetbrains.php.lang.psi.elements.ArrayCreationExpression)2 PhpReference (com.jetbrains.php.lang.psi.elements.PhpReference)2 HashSet (java.util.HashSet)2