Search in sources :

Example 1 with MethodProcessorSetupFailedException

use of com.intellij.psi.scope.MethodProcessorSetupFailedException in project intellij-community by JetBrains.

the class PsiScopesUtil method setupAndRunProcessor.

public static void setupAndRunProcessor(@NotNull MethodsProcessor processor, @NotNull PsiCallExpression call, boolean dummyImplicitConstructor) throws MethodProcessorSetupFailedException {
    if (call instanceof PsiMethodCallExpression) {
        final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) call;
        final PsiJavaCodeReferenceElement ref = methodCall.getMethodExpression();
        processor.setArgumentList(methodCall.getArgumentList());
        processor.obtainTypeArguments(methodCall);
        if (!ref.isQualified() || ref.getReferenceNameElement() instanceof PsiKeyword) {
            final PsiElement referenceNameElement = ref.getReferenceNameElement();
            if (referenceNameElement == null)
                return;
            if (referenceNameElement instanceof PsiKeyword) {
                final PsiKeyword keyword = (PsiKeyword) referenceNameElement;
                if (keyword.getTokenType() == JavaTokenType.THIS_KEYWORD) {
                    final PsiClass aClass = JavaResolveUtil.getContextClass(methodCall);
                    if (aClass == null) {
                        throw new MethodProcessorSetupFailedException("Can't resolve class for this expression");
                    }
                    processor.setIsConstructor(true);
                    processor.setAccessClass(aClass);
                    aClass.processDeclarations(processor, ResolveState.initial(), null, call);
                    if (dummyImplicitConstructor) {
                        processDummyConstructor(processor, aClass);
                    }
                } else if (keyword.getTokenType() == JavaTokenType.SUPER_KEYWORD) {
                    PsiClass aClass = JavaResolveUtil.getContextClass(methodCall);
                    if (aClass == null) {
                        throw new MethodProcessorSetupFailedException("Can't resolve class for super expression");
                    }
                    final PsiClass superClass = aClass.getSuperClass();
                    if (superClass != null) {
                        PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
                        PsiClass runSuper = superClass;
                        List<PsiSubstitutor> contextSubstitutors = new ArrayList<>();
                        do {
                            if (runSuper != null) {
                                PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(runSuper, aClass, PsiSubstitutor.EMPTY);
                                contextSubstitutors.add(superSubstitutor);
                            }
                            if (aClass.hasModifierProperty(PsiModifier.STATIC))
                                break;
                            aClass = JavaResolveUtil.getContextClass(aClass);
                            if (aClass != null)
                                runSuper = aClass.getSuperClass();
                        } while (aClass != null);
                        //apply substitutors in 'outer classes down to inner classes' order because inner class subst take precedence
                        for (int i = contextSubstitutors.size() - 1; i >= 0; i--) {
                            PsiSubstitutor contextSubstitutor = contextSubstitutors.get(i);
                            substitutor = substitutor.putAll(contextSubstitutor);
                        }
                        processor.setIsConstructor(true);
                        processor.setAccessClass(null);
                        final PsiMethod[] constructors = superClass.getConstructors();
                        ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
                        for (PsiMethod constructor : constructors) {
                            if (!processor.execute(constructor, state))
                                return;
                        }
                        if (dummyImplicitConstructor)
                            processDummyConstructor(processor, superClass);
                    }
                } else {
                    LOG.error("Unknown name element " + referenceNameElement + " in reference " + ref.getText() + "(" + ref + ")");
                }
            } else if (referenceNameElement instanceof PsiIdentifier) {
                processor.setIsConstructor(false);
                processor.setName(referenceNameElement.getText());
                processor.setAccessClass(null);
                resolveAndWalk(processor, ref, null);
            } else {
                LOG.error("Unknown name element " + referenceNameElement + " in reference " + ref.getText() + "(" + ref + ")");
            }
        } else {
            // Complex expression
            final PsiElement referenceName = methodCall.getMethodExpression().getReferenceNameElement();
            final PsiManager manager = call.getManager();
            final PsiElement qualifier = ref.getQualifier();
            if (referenceName == null) {
                // e.g. "manager.(beginTransaction)"
                throw new MethodProcessorSetupFailedException("Can't resolve method name for this expression");
            }
            if (referenceName instanceof PsiIdentifier && qualifier instanceof PsiExpression) {
                PsiType type = ((PsiExpression) qualifier).getType();
                if (type != null && qualifier instanceof PsiReferenceExpression) {
                    final PsiElement resolve = ((PsiReferenceExpression) qualifier).resolve();
                    if (resolve instanceof PsiEnumConstant) {
                        final PsiEnumConstantInitializer initializingClass = ((PsiEnumConstant) resolve).getInitializingClass();
                        if (hasDesiredMethod(methodCall, type, initializingClass)) {
                            processQualifierResult(new ClassCandidateInfo(initializingClass, PsiSubstitutor.EMPTY), processor, methodCall);
                            return;
                        }
                    } else if (resolve instanceof PsiVariable && ((PsiVariable) resolve).hasModifierProperty(PsiModifier.FINAL) && ((PsiVariable) resolve).hasInitializer()) {
                        final PsiExpression initializer = ((PsiVariable) resolve).getInitializer();
                        if (initializer instanceof PsiNewExpression) {
                            final PsiAnonymousClass anonymousClass = ((PsiNewExpression) initializer).getAnonymousClass();
                            if (hasDesiredMethod(methodCall, type, anonymousClass)) {
                                type = initializer.getType();
                            }
                        }
                    }
                }
                if (type == null) {
                    if (qualifier instanceof PsiJavaCodeReferenceElement) {
                        final JavaResolveResult result = ((PsiJavaCodeReferenceElement) qualifier).advancedResolve(false);
                        if (result.getElement() instanceof PsiClass) {
                            processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
                            processQualifierResult(result, processor, methodCall);
                        }
                    } else {
                        throw new MethodProcessorSetupFailedException("Cant determine qualifier type!");
                    }
                } else if (type instanceof PsiDisjunctionType) {
                    processQualifierType(((PsiDisjunctionType) type).getLeastUpperBound(), processor, manager, methodCall);
                } else if (type instanceof PsiCapturedWildcardType) {
                    final PsiType psiType = convertToTypeParameter((PsiCapturedWildcardType) type, methodCall);
                    if (psiType != null) {
                        processQualifierType(psiType, processor, manager, methodCall);
                    }
                } else {
                    processQualifierType(type, processor, manager, methodCall);
                }
            } else {
                LOG.error("ref: " + ref + " (" + ref.getClass() + ")," + " ref.getReferenceNameElement()=" + ref.getReferenceNameElement() + "; methodCall.getMethodExpression().getReferenceNameElement()=" + methodCall.getMethodExpression().getReferenceNameElement() + "; qualifier=" + qualifier);
            }
        }
    } else {
        LOG.assertTrue(call instanceof PsiNewExpression);
        PsiNewExpression newExpr = (PsiNewExpression) call;
        PsiJavaCodeReferenceElement classRef = newExpr.getClassOrAnonymousClassReference();
        if (classRef == null) {
            throw new MethodProcessorSetupFailedException("Cant get reference to class in new expression");
        }
        final JavaResolveResult result = classRef.advancedResolve(false);
        PsiClass aClass = (PsiClass) result.getElement();
        if (aClass == null) {
            throw new MethodProcessorSetupFailedException("Cant resolve class in new expression");
        }
        processor.setIsConstructor(true);
        processor.setAccessClass(aClass);
        processor.setArgumentList(newExpr.getArgumentList());
        processor.obtainTypeArguments(newExpr);
        aClass.processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, result.getSubstitutor()), null, call);
        if (dummyImplicitConstructor) {
            processDummyConstructor(processor, aClass);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) ClassCandidateInfo(com.intellij.psi.infos.ClassCandidateInfo) MethodProcessorSetupFailedException(com.intellij.psi.scope.MethodProcessorSetupFailedException)

Example 2 with MethodProcessorSetupFailedException

use of com.intellij.psi.scope.MethodProcessorSetupFailedException in project intellij-community by JetBrains.

the class PsiReferenceExpressionImpl method resolveToMethod.

@NotNull
private JavaResolveResult[] resolveToMethod(@NotNull PsiFile containingFile) {
    final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) getParent();
    final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall, containingFile);
    try {
        PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false);
    } catch (MethodProcessorSetupFailedException e) {
        return JavaResolveResult.EMPTY_ARRAY;
    }
    return processor.getResult();
}
Also used : MethodResolverProcessor(com.intellij.psi.scope.processor.MethodResolverProcessor) MethodProcessorSetupFailedException(com.intellij.psi.scope.MethodProcessorSetupFailedException) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with MethodProcessorSetupFailedException

use of com.intellij.psi.scope.MethodProcessorSetupFailedException in project intellij-community by JetBrains.

the class PsiResolveHelperImpl method getReferencedMethodCandidates.

@NotNull
@Override
public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor, final boolean checkVarargs) {
    PsiFile containingFile = expr.getContainingFile();
    final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile) {

        @Override
        protected boolean acceptVarargs() {
            return checkVarargs;
        }
    };
    try {
        PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor);
    } catch (MethodProcessorSetupFailedException e) {
        return CandidateInfo.EMPTY_ARRAY;
    }
    return processor.getCandidates();
}
Also used : MethodCandidatesProcessor(com.intellij.psi.scope.processor.MethodCandidatesProcessor) MethodProcessorSetupFailedException(com.intellij.psi.scope.MethodProcessorSetupFailedException) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with MethodProcessorSetupFailedException

use of com.intellij.psi.scope.MethodProcessorSetupFailedException in project intellij-community by JetBrains.

the class ExceptionUtil method getUnhandledExceptions.

@NotNull
public static List<PsiClassType> getUnhandledExceptions(@NotNull final PsiCallExpression methodCall, @Nullable final PsiElement topElement, final boolean includeSelfCalls) {
    //exceptions only influence the invocation type after overload resolution is complete
    if (MethodCandidateInfo.isOverloadCheck()) {
        return Collections.emptyList();
    }
    final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(methodCall.getArgumentList());
    final JavaResolveResult result = properties != null ? properties.getInfo() : InferenceSession.getResolveResult(methodCall);
    final PsiElement element = result.getElement();
    final PsiMethod method = element instanceof PsiMethod ? (PsiMethod) element : null;
    if (method == null) {
        return Collections.emptyList();
    }
    final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class);
    if (!includeSelfCalls && method == containingMethod) {
        return Collections.emptyList();
    }
    if (properties != null) {
        PsiUtilCore.ensureValid(method);
    }
    final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes();
    if (thrownExceptions.length == 0) {
        return Collections.emptyList();
    }
    final PsiSubstitutor substitutor = result.getSubstitutor();
    if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) {
        final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile();
        final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression) methodCall, containingFile);
        try {
            PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false);
            final List<Pair<PsiMethod, PsiSubstitutor>> candidates = ContainerUtil.mapNotNull(processor.getResults(), info -> {
                PsiElement element1 = info.getElement();
                if (info instanceof MethodCandidateInfo && MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod) element1) && !MethodSignatureUtil.isSuperMethod((PsiMethod) element1, method)) {
                    return Pair.create((PsiMethod) element1, ((MethodCandidateInfo) info).getSubstitutor(false));
                }
                return null;
            });
            if (candidates.size() > 1) {
                GlobalSearchScope scope = methodCall.getResolveScope();
                final List<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions, scope);
                for (Pair<PsiMethod, PsiSubstitutor> pair : candidates) {
                    final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes();
                    if (exceptions.length == 0) {
                        return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY);
                    }
                    retainExceptions(ex, collectSubstituted(pair.second, exceptions, scope));
                }
                return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()]));
            }
        } catch (MethodProcessorSetupFailedException ignore) {
            return Collections.emptyList();
        }
    }
    return getUnhandledExceptions(method, methodCall, topElement, substitutor);
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) MethodResolverProcessor(com.intellij.psi.scope.processor.MethodResolverProcessor) MethodProcessorSetupFailedException(com.intellij.psi.scope.MethodProcessorSetupFailedException) Pair(com.intellij.openapi.util.Pair) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with MethodProcessorSetupFailedException

use of com.intellij.psi.scope.MethodProcessorSetupFailedException in project intellij-community by JetBrains.

the class MethodParameterInfoHandler method getCandidates.

private static CandidateInfo[] getCandidates(PsiCallExpression call) {
    final MethodCandidatesProcessor processor = new MethodResolverProcessor(call, call.getContainingFile(), new PsiConflictResolver[0]) {

        @Override
        protected boolean acceptVarargs() {
            return false;
        }
    };
    try {
        PsiScopesUtil.setupAndRunProcessor(processor, call, true);
    } catch (MethodProcessorSetupFailedException e) {
        return CandidateInfo.EMPTY_ARRAY;
    }
    final List<CandidateInfo> results = processor.getResults();
    return results.toArray(new CandidateInfo[results.size()]);
}
Also used : MethodCandidatesProcessor(com.intellij.psi.scope.processor.MethodCandidatesProcessor) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) MethodResolverProcessor(com.intellij.psi.scope.processor.MethodResolverProcessor) MethodProcessorSetupFailedException(com.intellij.psi.scope.MethodProcessorSetupFailedException)

Aggregations

MethodProcessorSetupFailedException (com.intellij.psi.scope.MethodProcessorSetupFailedException)5 MethodResolverProcessor (com.intellij.psi.scope.processor.MethodResolverProcessor)3 NotNull (org.jetbrains.annotations.NotNull)3 MethodCandidateInfo (com.intellij.psi.infos.MethodCandidateInfo)2 MethodCandidatesProcessor (com.intellij.psi.scope.processor.MethodCandidatesProcessor)2 Pair (com.intellij.openapi.util.Pair)1 CandidateInfo (com.intellij.psi.infos.CandidateInfo)1 ClassCandidateInfo (com.intellij.psi.infos.ClassCandidateInfo)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1