mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-84488 control flow of try with some catches
This commit is contained in:
+3
-2
@@ -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() {
|
||||
|
||||
+11
-5
@@ -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<Pair<InstructionImpl, GroovyPsiElement>> pendingPostCalls = myPending;
|
||||
myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -432,6 +432,10 @@ class A {
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection())
|
||||
}
|
||||
|
||||
public void testUsedInCatch() {
|
||||
doTest(new UnusedDefInspection())
|
||||
}
|
||||
|
||||
public void testStringAssignableToChar() {
|
||||
doTest(new GroovyAssignabilityCheckInspection());
|
||||
}
|
||||
|
||||
@@ -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<String> input = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".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
|
||||
@@ -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
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
String s = '';
|
||||
try {
|
||||
print 2
|
||||
}
|
||||
catch (UnsupportedOperationException ignored) {
|
||||
<warning descr="Assignment is not used">s</warning>=''
|
||||
s=''
|
||||
}
|
||||
catch (RuntimeException ignored) {
|
||||
s = ''
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
s = ''
|
||||
}
|
||||
print s
|
||||
Reference in New Issue
Block a user