List<PsiClassType> (@NotNull final PsiCallExpression methodCall, @Nullable final PsiElement topElement, @NotNull Predicate<? super PsiCallExpression> skipCondition) { //exceptions only influence the invocation type after overload resolution is complete if (MethodCandidateInfo.isOverloadCheck()) { return Collections.emptyList(); } final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult(methodCall); final PsiElement element = result.getElement(); final PsiMethod method = element instanceof PsiMethod ? (PsiMethod)element : null; if (method == null) { return Collections.emptyList(); } if (skipCondition.test(methodCall)) { return Collections.emptyList(); } final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); if (thrownExceptions.length == 0) { return Collections.emptyList(); } if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { PsiFile containingFile = methodCall.getContainingFile(); MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); // Resolve other signatures in case of multiple interface inheritance // e.g. consider // interface X {void a() throws A;} interface Y{void a() throws B;} class Z extends X, Y {} // here normal resolve returns X.a(), but we should check throws clauses for both a() methods. // (see JLS 15.12.2.5) final List<Pair<PsiMethod, PsiSubstitutor>> candidates = ContainerUtil.mapNotNull( processor.getResults(), info -> { PsiElement element1 = info.getElement(); if (info instanceof MethodCandidateInfo && element1 != method && //don't check self MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element1) && !((PsiMethod)element1).hasModifierProperty(PsiModifier.PRIVATE) && !MethodSignatureUtil.isSuperMethod((PsiMethod)element1, method) && !(((MethodCandidateInfo)info).isToInferApplicability() && !((MethodCandidateInfo)info).isApplicable())) { return Pair.create((PsiMethod)element1, ((MethodCandidateInfo)info).getSubstitutor(false)); } return null; }); if (!candidates.isEmpty()) { GlobalSearchScope scope = methodCall.getResolveScope(); List<PsiClassType> ex = collectSubstituted(result.getSubstitutor(), thrownExceptions, scope); for (Pair<PsiMethod, PsiSubstitutor> pair : candidates) { final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); if (exceptions.length == 0) { return Collections.emptyList(); } retainExceptions(ex, collectSubstituted(pair.second, exceptions, scope)); } return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(PsiClassType.EMPTY_ARRAY)); } } catch (MethodProcessorSetupFailedException ignore) { return Collections.emptyList(); } } return getUnhandledExceptions(method, methodCall, topElement, result::getSubstitutor); }