HandlePlace (@Nullable PsiElement element, @NotNull PsiClassType exceptionType, @Nullable PsiElement topElement) { if (element == null || element == topElement) return HandlePlace.UNHANDLED; PsiElement parent = element.getParent(); if (parent == null || parent == topElement) return HandlePlace.UNHANDLED; for (CustomExceptionHandler exceptionHandler : CustomExceptionHandler.KEY.getExtensionList()) { if (exceptionHandler.isHandled(element, exceptionType, topElement)) return HandlePlace.UNKNOWN; } if (parent instanceof PsiMethod) { PsiMethod method = (PsiMethod)parent; return HandlePlace.fromBoolean(isHandledByMethodThrowsClause(method, exceptionType)); } else if (parent instanceof PsiClass) { // arguments to anon class constructor should be handled higher // like in void f() throws XXX { new AA(methodThrowingXXX()) { ... }; } if (!(parent instanceof PsiAnonymousClass)) return HandlePlace.UNHANDLED; return getHandlePlace(parent, exceptionType, topElement); } else if (parent instanceof PsiLambdaExpression || parent instanceof PsiMethodReferenceExpression && element == ((PsiMethodReferenceExpression)parent).getReferenceNameElement()) { final PsiType interfaceType = ((PsiFunctionalExpression)parent).getFunctionalInterfaceType(); return HandlePlace.fromBoolean(isDeclaredBySAMMethod(exceptionType, interfaceType)); } else if (parent instanceof PsiClassInitializer) { if (((PsiClassInitializer)parent).hasModifierProperty(PsiModifier.STATIC)) return HandlePlace.UNHANDLED; // anonymous class initializers can throw any exceptions if (!(parent.getParent() instanceof PsiAnonymousClass)) { // exception thrown from within class instance initializer must be handled in every class constructor // check each constructor throws exception or superclass (there must be at least one) final PsiClass aClass = ((PsiClassInitializer)parent).getContainingClass(); return HandlePlace.fromBoolean(areAllConstructorsThrow(aClass, exceptionType)); } } else if (parent instanceof PsiTryStatement) { PsiTryStatement tryStatement = (PsiTryStatement)parent; if (tryStatement.getTryBlock() == element) { HandlePlace place = getCaughtPlace(tryStatement, exceptionType); if (place != HandlePlace.UNHANDLED) { return place; } } if (tryStatement.getResourceList() == element) { HandlePlace place = getCaughtPlace(tryStatement, exceptionType); if (place != HandlePlace.UNHANDLED) { return place; } } PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (element instanceof PsiCatchSection && finallyBlock != null && blockCompletesAbruptly(finallyBlock)) { // exception swallowed return HandlePlace.UNKNOWN; } } else if (parent instanceof JavaCodeFragment) { JavaCodeFragment codeFragment = (JavaCodeFragment)parent; JavaCodeFragment.ExceptionHandler exceptionHandler = codeFragment.getExceptionHandler(); return HandlePlace.fromBoolean(exceptionHandler != null && exceptionHandler.isHandledException(exceptionType)); } else if (PsiImplUtil.isInServerPage(parent) && parent instanceof PsiFile) { return HandlePlace.UNKNOWN; } else if (parent instanceof PsiFile) { return HandlePlace.fromBoolean(false); } else if (parent instanceof PsiField && ((PsiField)parent).getInitializer() == element) { final PsiClass aClass = ((PsiField)parent).getContainingClass(); if (aClass != null && !(aClass instanceof PsiAnonymousClass) && !((PsiField)parent).hasModifierProperty(PsiModifier.STATIC)) { // exceptions thrown in field initializers should be thrown in all class constructors return HandlePlace.fromBoolean(areAllConstructorsThrow(aClass, exceptionType)); } } return getHandlePlace(parent, exceptionType, topElement); }