From baecbfd6c82286bfe7ae3a06abfd76e7bcc18cc3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 6 Sep 2012 16:34:31 +0200 Subject: [PATCH] IDEA-90606 Smart completion misses exception from try-with-resources --- .../intellij/codeInsight/ExceptionUtil.java | 99 ++++++++++--------- .../TryWithResourcesThrowsException-out.java | 11 +++ .../TryWithResourcesThrowsException.java | 10 ++ .../completion/SmartType17CompletionTest.java | 2 + 4 files changed, 77 insertions(+), 45 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException.java diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 521508fb70c7..ed67e417757c 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -102,55 +102,64 @@ public class ExceptionUtil { return classTypes; } else if (element instanceof PsiTryStatement) { - PsiTryStatement tryStatement = (PsiTryStatement)element; - final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - List array = new ArrayList(); - if (tryBlock != null) { - List exceptions = getThrownExceptions(tryBlock); - array.addAll(exceptions); - } - - PsiParameter[] parameters = tryStatement.getCatchBlockParameters(); - for (PsiParameter parameter : parameters) { - PsiType exception = parameter.getType(); - for (int j = array.size() - 1; j >= 0; j--) { - PsiClassType exception1 = array.get(j); - if (exception.isAssignableFrom(exception1)) { - array.remove(exception1); - } - } - } - - PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); - for (PsiCodeBlock catchBlock : catchBlocks) { - addExceptions(array, getThrownExceptions(catchBlock)); - } - - PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); - if (finallyBlock != null) { - // if finally block completes normally, exception not caught - // if finally block completes abruptly, exception gets lost - try { - ControlFlow flow = ControlFlowFactory.getInstance(finallyBlock.getProject()).getControlFlow(finallyBlock, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false); - int completionReasons = ControlFlowUtil.getCompletionReasons(flow, 0, flow.getSize()); - List thrownExceptions = getThrownExceptions(finallyBlock); - if ((completionReasons & ControlFlowUtil.NORMAL_COMPLETION_REASON) == 0) { - array = new ArrayList(thrownExceptions); - } - else { - addExceptions(array, thrownExceptions); - } - } - catch (AnalysisCanceledException e) { - // incomplete code - } - } - - return array; + return getTryExceptions((PsiTryStatement)element); } return getThrownExceptions(element.getChildren()); } + private static List getTryExceptions(PsiTryStatement tryStatement) { + List array = new ArrayList(); + + PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList != null) { + for (PsiResourceVariable variable : resourceList.getResourceVariables()) { + array.addAll(getUnhandledCloserExceptions(variable, resourceList)); + } + } + + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (tryBlock != null) { + array.addAll(getThrownExceptions(tryBlock)); + } + + for (PsiParameter parameter : tryStatement.getCatchBlockParameters()) { + PsiType exception = parameter.getType(); + for (int j = array.size() - 1; j >= 0; j--) { + PsiClassType exception1 = array.get(j); + if (exception.isAssignableFrom(exception1)) { + array.remove(exception1); + } + } + } + + for (PsiCodeBlock catchBlock : tryStatement.getCatchBlocks()) { + addExceptions(array, getThrownExceptions(catchBlock)); + } + + PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + if (finallyBlock != null) { + // if finally block completes normally, exception not caught + // if finally block completes abruptly, exception gets lost + try { + ControlFlow flow = ControlFlowFactory + .getInstance(finallyBlock.getProject()).getControlFlow(finallyBlock, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false); + int completionReasons = ControlFlowUtil.getCompletionReasons(flow, 0, flow.getSize()); + List thrownExceptions = getThrownExceptions(finallyBlock); + if ((completionReasons & ControlFlowUtil.NORMAL_COMPLETION_REASON) == 0) { + array = new ArrayList(thrownExceptions); + } + else { + addExceptions(array, thrownExceptions); + } + } + catch (AnalysisCanceledException e) { + // incomplete code + } + } + + return array; + } + @NotNull private static List getExceptionsByMethodAndChildren(PsiElement element, JavaResolveResult resolveResult) { PsiMethod method = (PsiMethod)resolveResult.getElement(); diff --git a/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException-out.java b/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException-out.java new file mode 100644 index 000000000000..7b3547939539 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException-out.java @@ -0,0 +1,11 @@ +import java.io.FileInputStream; +import java.io.IOException; + +class Test { + void foo() { + try { + try (FileInputStream in = new FileInputStream("adsf")) { + } + } catch (IOException ) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException.java b/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException.java new file mode 100644 index 000000000000..3683c71337e5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/TryWithResourcesThrowsException.java @@ -0,0 +1,10 @@ +import java.io.FileInputStream; + +class Test { + void foo() { + try { + try (FileInputStream in = new FileInputStream("adsf")) { + } + } catch (IO) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java index cd531b3b91fa..548f5df1500a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java @@ -60,6 +60,8 @@ public class SmartType17CompletionTest extends LightFixtureCompletionTestCase { public void testTryWithResourcesNoSemicolon() { doTest(); } + public void testTryWithResourcesThrowsException() { doTest(); } + public void testDiamondPresentation() { configureByFile("/" + getTestName(false) + ".java"); LookupElementPresentation presentation = new LookupElementPresentation();