From 73747f47062bcc9e306b1e103701d3076ec71c08 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 27 Apr 2012 16:04:55 +0400 Subject: [PATCH] IDEA-84488 control flow of try with some catches --- .../psi/controlFlow/ReturnInstruction.java | 5 +-- .../controlFlow/impl/ControlFlowBuilder.java | 16 ++++++--- .../groovy/lang/GroovyHighlightingTest.groovy | 4 +++ .../lang/controlFlow/ControlFlowTest.java | 2 ++ .../groovy/controlFlow/someCatches.test | 34 +++++++++++++++++++ .../testdata/groovy/controlFlow/try10.test | 22 ++++++++++++ .../testdata/groovy/controlFlow/try9.test | 2 +- .../testdata/highlighting/UsedInCatch.groovy | 15 ++++++++ 8 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/controlFlow/someCatches.test create mode 100644 plugins/groovy/testdata/groovy/controlFlow/try10.test create mode 100644 plugins/groovy/testdata/highlighting/UsedInCatch.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/ReturnInstruction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/ReturnInstruction.java index fd949a5cc238..e9e431892031 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/ReturnInstruction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/ReturnInstruction.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.lang.psi.controlFlow; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrFinallyClause; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl; import java.util.ArrayDeque; @@ -25,8 +26,8 @@ import java.util.Deque; * @author peter */ public class ReturnInstruction extends InstructionImpl { - public ReturnInstruction(int num) { - super(null, num); + public ReturnInstruction(GrFinallyClause finallyClause, int num) { + super(finallyClause, num); } public String toString() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java index 3f5b34956b79..12bb6627500b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java @@ -430,9 +430,8 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor { if (ControlFlowUtils.isIncOrDecOperand(refExpr) && !myAssertionsOnly) { final InstructionImpl i = new ReadWriteVariableInstruction(name, refExpr, myInstructionNumber++, READ); - addNode(i); + addNodeAndCheckPending(i); addNode(new ReadWriteVariableInstruction(name, refExpr, myInstructionNumber++, WRITE)); - checkPending(i); } else { boolean isWrite = !myAssertionsOnly && PsiUtil.isLValue(refExpr); @@ -818,25 +817,32 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor { } } + //save added postcalls into separate list because we don't want returnInstruction grabbed their pending edges + List> pendingPostCalls = myPending; + myPending = new ArrayList>(); + myHead = finallyInstruction; finallyClause.accept(this); - final ReturnInstruction returnInstruction = new ReturnInstruction(myInstructionNumber++); + final ReturnInstruction returnInstruction = new ReturnInstruction(finallyClause, myInstructionNumber++); for (AfterCallInstruction postCall : postCalls) { postCall.setReturnInstruction(returnInstruction); addEdge(returnInstruction, postCall); } - addNode(returnInstruction); + addNodeAndCheckPending(returnInstruction); interruptFlow(); finishNode(finallyInstruction); assert oldPending != null; - oldPending.addAll(myPending); + oldPending.addAll(pendingPostCalls); myPending = oldPending; } else { if (tryEnd != null) { addPendingEdge(tryCatchStatement, tryEnd); } + for (InstructionImpl catchEnd : catches) { + addPendingEdge(tryBlock, catchEnd); + } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy index d8fcb4f734ae..4aee007edec3 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy @@ -432,6 +432,10 @@ class A { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()) } + public void testUsedInCatch() { + doTest(new UnusedDefInspection()) + } + public void testStringAssignableToChar() { doTest(new GroovyAssignabilityCheckInspection()); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.java index ff34da2ea32e..eb95c8487c27 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.java @@ -49,6 +49,7 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase { public void testTry7() throws Throwable { doTest(); } public void testTry8() throws Throwable { doTest(); } public void testTry9() throws Throwable { doTest(); } + public void testTry10() throws Throwable { doTest(); } public void testWhile1() throws Throwable { doTest(); } public void testWhile2() throws Throwable { doTest(); } public void testWhileNonConstant() throws Throwable { doTest(); } @@ -57,6 +58,7 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase { public void testSwitchInTryWithThrows() {doTest();} public void testClosure() {doTest();} public void testAnonymous() {doTest();} + public void testSomeCatches() {doTest();} public void doTest() { final List input = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test"); diff --git a/plugins/groovy/testdata/groovy/controlFlow/someCatches.test b/plugins/groovy/testdata/groovy/controlFlow/someCatches.test new file mode 100644 index 000000000000..8b56579702da --- /dev/null +++ b/plugins/groovy/testdata/groovy/controlFlow/someCatches.test @@ -0,0 +1,34 @@ +String s = ''; +try { + print 2 +} +catch (UnsupportedOperationException ignored) { + s='' +} +catch (RuntimeException ignored) { + s = '' +} +catch (Exception ignored) { + s = '' +} +print s +----- +0(1) element: null +1(2) WRITE s +2(3) element: Open block +3(4) READ print +4(5,8,11,14) THROW. element: Call expression +5(6) element: Catch clause +6(7) WRITE ignored +7(14) WRITE s +8(9) element: Catch clause +9(10) WRITE ignored +10(14) WRITE s +11(12) element: Catch clause +12(13) WRITE ignored +13(14) WRITE s +14(15) READ print +15(16) READ s +16(17) ARGUMENT element: Reference expression +17(18) element: Call expression MAYBE_RETURN +18() element: null \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/controlFlow/try10.test b/plugins/groovy/testdata/groovy/controlFlow/try10.test new file mode 100644 index 000000000000..7a5c36c02b02 --- /dev/null +++ b/plugins/groovy/testdata/groovy/controlFlow/try10.test @@ -0,0 +1,22 @@ +try {} +finally { + for (;;){ + if (abc) break + } +} +cde +----- +0(1) element: null +1(3) element: Open block +2(5) element: Finally clause +3(2,4) CALL 2 +4(11) AFTER CALL 3 +5(6) element: For statement +6(7) element: Block statement +7(8,9) element: IF statement +8(10) READ abc +9(5) element: IF statement +10(4) RETURN +11(12) READ cde +12(13) element: Reference expression MAYBE_RETURN +13() element: null \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/controlFlow/try9.test b/plugins/groovy/testdata/groovy/controlFlow/try9.test index 398b63ba43e6..c191910cc374 100644 --- a/plugins/groovy/testdata/groovy/controlFlow/try9.test +++ b/plugins/groovy/testdata/groovy/controlFlow/try9.test @@ -21,7 +21,7 @@ finally { 6(13) AFTER CALL 5 7(8) element: Open block 8(9) READ i -9(10,13) THROW. element: Method call +9(10,12) THROW. element: Method call 10(11) element: Catch clause 11(12) WRITE ignored 12(6) RETURN diff --git a/plugins/groovy/testdata/highlighting/UsedInCatch.groovy b/plugins/groovy/testdata/highlighting/UsedInCatch.groovy new file mode 100644 index 000000000000..ca2688e840e6 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/UsedInCatch.groovy @@ -0,0 +1,15 @@ +String s = ''; +try { + print 2 +} +catch (UnsupportedOperationException ignored) { + s='' + s='' +} +catch (RuntimeException ignored) { + s = '' +} +catch (Exception ignored) { + s = '' +} +print s