diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToExistingCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToExistingCatchFix.java index de7f4ef2b320..cb99997c219e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToExistingCatchFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToExistingCatchFix.java @@ -14,10 +14,10 @@ import com.intellij.openapi.util.Pass; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.IntroduceTargetChooser; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.SmartList; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,8 +28,6 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import static com.intellij.util.ObjectUtils.tryCast; - public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionAction { private final PsiElement myErrorElement; @@ -67,7 +65,7 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio }, section -> Objects.requireNonNull(section.getCatchType()).getPresentableText(), QuickFixBundle.message("add.exception.to.existing.catch.chooser.title"), - dom -> Objects.requireNonNull(((PsiCatchSection)dom).getParameter()).getTextRange() + catchSection -> Objects.requireNonNull(((PsiCatchSection)catchSection).getParameter()).getTextRange() ); } } @@ -135,13 +133,7 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio if (!element.isValid() || !PsiUtil.isLanguageLevel7OrHigher(element)) return null; List unhandledExceptions = new ArrayList<>(ExceptionUtil.getOwnUnhandledExceptions(element)); if (unhandledExceptions.isEmpty()) return null; - boolean containsInCatchOrFinally = containsInCatchOrFinally(element); - List tryStatements = - PsiTreeUtil.collectParents(element, PsiTryStatement.class, false, el -> - el instanceof PsiLambdaExpression || el instanceof PsiClass && !(el instanceof PsiAnonymousClass)); - if (containsInCatchOrFinally) { - tryStatements.remove(0); - } + List tryStatements = getTryStatements(element); List sections = tryStatements.stream() .flatMap(stmt -> Arrays.stream(stmt.getCatchSections())) @@ -155,23 +147,31 @@ public class AddExceptionToExistingCatchFix extends PsiElementBaseIntentionActio return new Context(sections, unhandledExceptions); } - private static boolean containsInCatchOrFinally(@NotNull PsiElement element) { + @NotNull + private static List getTryStatements(@NotNull PsiElement element) { + PsiElement current = element; PsiElement parent = element.getParent(); + List parents = new SmartList<>(); while (parent != null) { + if (parent instanceof PsiLambdaExpression || parent instanceof PsiMember) break; if (parent instanceof PsiTryStatement) { - return false; - } - if (parent instanceof PsiCatchSection) { - return true; - } - if (parent instanceof PsiCodeBlock) { - PsiKeyword keyword = tryCast(PsiTreeUtil.skipWhitespacesAndCommentsBackward(parent), PsiKeyword.class); - if (keyword != null && keyword.getText().equals(PsiKeyword.FINALLY)) { - return true; + PsiTryStatement tryStatement = (PsiTryStatement)parent; + if (tryStatement.getFinallyBlock() != current && !isInCatch(current, tryStatement)) { + parents.add((PsiTryStatement)parent); } } + current = parent; parent = parent.getParent(); } + return parents; + } + + private static boolean isInCatch(PsiElement current, PsiTryStatement tryStatement) { + for (PsiCatchSection block : tryStatement.getCatchSections()) { + if (block == current) { + return true; + } + } return false; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/afterInAnnonimousClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/afterInAnnonimousClass.java deleted file mode 100644 index e1c94f5728ab..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/afterInAnnonimousClass.java +++ /dev/null @@ -1,18 +0,0 @@ -// "Add exception to existing catch clause" "true" -import java.io.FileInputStream; -import java.io.FileNotFoundException; - -class Test { - void m() { - try { - new Runnable() { - @Override - public void run() { } - - InputStream in = new FileInputStream(""); - }; - } catch (RuntimeException | FileNotFoundException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInAnnonimousClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInAnnonimousClass.java index 6f57aecfe6e1..83eefb3b9277 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInAnnonimousClass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInAnnonimousClass.java @@ -1,4 +1,4 @@ -// "Add exception to existing catch clause" "true" +// "Add exception to existing catch clause" "false" import java.io.FileInputStream; class Test { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInDeepCatch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInDeepCatch.java new file mode 100644 index 000000000000..c71c1c1c2edd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addExceptionToExistingCatch/beforeInDeepCatch.java @@ -0,0 +1,14 @@ +// "Add exception to existing catch clause" "false" +import java.io.File; + +class Test { + void test() { + try { } + catch (Error ex) { + try { } + catch (RuntimeException ex2) { + Class.forName("xyz"); + } + } + } +} \ No newline at end of file