diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java index dc9b64d39227..f421e8941f61 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java @@ -244,13 +244,21 @@ final class ControlFlowAnalyzer extends JavaElementVisitor { } } // optimization: reduce number of instructions - boolean isGeneratingStatement = element instanceof PsiStatement && !(element instanceof PsiSwitchLabelStatement); - boolean isGeneratingCodeBlock = element instanceof PsiCodeBlock && !(element.getParent() instanceof PsiSwitchStatement); - if (isGeneratingStatement || isGeneratingCodeBlock) { + boolean isGeneratingStatement = element instanceof PsiStatement && !(element instanceof PsiSwitchLabelStatement) && + !isAbruptStatement(element); + PsiElement parent = element.getParent(); + boolean isGeneratingCodeBlock = element instanceof PsiCodeBlock && !(parent instanceof PsiSwitchStatement); + boolean isGeneratingExpression = element instanceof PsiExpression && !(element instanceof PsiSwitchExpression) && + isAbruptStatement(parent); + if (isGeneratingStatement || isGeneratingCodeBlock || isGeneratingExpression) { generateUncheckedExceptionJumps(element, atStart); } } + private static boolean isAbruptStatement(@NotNull PsiElement element) { + return element instanceof PsiReturnStatement || element instanceof PsiYieldStatement || element instanceof PsiThrowStatement; + } + private void finishElement(@NotNull PsiElement element) { generateUncheckedExceptionJumpsIfNeeded(element, false); @@ -877,7 +885,7 @@ final class ControlFlowAnalyzer extends JavaElementVisitor { @Override public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) { startElement(statement); - generateCaseValueInstructions(statement.getCaseValues()); + generateCaseValueInstructions(statement.getCaseLabelElementList()); finishElement(statement); } @@ -885,7 +893,7 @@ final class ControlFlowAnalyzer extends JavaElementVisitor { public void visitSwitchLabeledRuleStatement(PsiSwitchLabeledRuleStatement statement) { startElement(statement); - generateCaseValueInstructions(statement.getCaseValues()); + generateCaseValueInstructions(statement.getCaseLabelElementList()); PsiStatement body = statement.getBody(); if (body != null) { @@ -903,11 +911,13 @@ final class ControlFlowAnalyzer extends JavaElementVisitor { finishElement(statement); } - private void generateCaseValueInstructions(@Nullable PsiExpressionList values) { + private void generateCaseValueInstructions(@Nullable PsiCaseLabelElementList values) { if (values != null) { - for (PsiExpression caseValue : values.getExpressions()) { + for (PsiCaseLabelElement caseValue : values.getElements()) { ProgressManager.checkCanceled(); - generateExpressionInstructions(caseValue); + if (caseValue instanceof PsiExpression) { + generateExpressionInstructions((PsiExpression)caseValue); + } } } } diff --git a/java/java-tests/testData/inspection/defUse/AssignmentInCatch.java b/java/java-tests/testData/inspection/defUse/AssignmentInCatch.java new file mode 100644 index 000000000000..11333b53f2f0 --- /dev/null +++ b/java/java-tests/testData/inspection/defUse/AssignmentInCatch.java @@ -0,0 +1,16 @@ +class Main { + static int test() { + String msg = "ERR1"; + try { + msg = "ERR2"; // HERE + return throwsNFE(); + } catch (NumberFormatException e) { + System.err.println(msg); + } + return 0; + } + + static int throwsNFE() throws NumberFormatException { + throw new NumberFormatException("NFE"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/controlFlow/flow14.txt b/java/java-tests/testData/psi/controlFlow/flow14.txt index 88a23d8739e6..5feea14d06d1 100644 --- a/java/java-tests/testData/psi/controlFlow/flow14.txt +++ b/java/java-tests/testData/psi/controlFlow/flow14.txt @@ -1,30 +1,31 @@ -0: COND_THROW_TO 9 -1: GOTO [END] 7 RETURN -2: COND_THROW_TO 9 -3: COND_THROW_TO 9 -4: GOTO [END] 5 -5: CALL 11 -6: GOTO [END] 30 -7: CALL 11 -8: GOTO [END] 30 RETURN -9: CALL 11 -10: GOTO [END] 29 -11: COND_THROW_TO 19 -12: EMPTY -13: COND_THROW_TO 19 -14: GOTO [END] 15 -15: CALL 21 -16: GOTO [END] 26 -17: CALL 21 -18: GOTO [END] 27 RETURN -19: CALL 21 -20: GOTO [END] 25 -21: GOTO [END] 23 RETURN -22: RETURN FROM 21 -23: RETURN FROM 21 TO 18 -24: RETURN FROM 21 TO 20 -25: THROW_TO 30 -26: RETURN FROM 11 -27: RETURN FROM 11 TO 8 -28: RETURN FROM 11 TO 10 -29: THROW_TO 30 \ No newline at end of file +0: COND_THROW_TO 10 +1: COND_THROW_TO 10 +2: COND_THROW_TO 10 +3: GOTO [END] 8 RETURN +4: COND_THROW_TO 10 +5: GOTO [END] 6 +6: CALL 12 +7: GOTO [END] 31 +8: CALL 12 +9: GOTO [END] 31 RETURN +10: CALL 12 +11: GOTO [END] 30 +12: COND_THROW_TO 20 +13: EMPTY +14: COND_THROW_TO 20 +15: GOTO [END] 16 +16: CALL 22 +17: GOTO [END] 27 +18: CALL 22 +19: GOTO [END] 28 RETURN +20: CALL 22 +21: GOTO [END] 26 +22: GOTO [END] 24 RETURN +23: RETURN FROM 22 +24: RETURN FROM 22 TO 19 +25: RETURN FROM 22 TO 21 +26: THROW_TO 31 +27: RETURN FROM 12 +28: RETURN FROM 12 TO 9 +29: RETURN FROM 12 TO 11 +30: THROW_TO 31 \ No newline at end of file diff --git a/java/java-tests/testData/psi/controlFlow/flow15.txt b/java/java-tests/testData/psi/controlFlow/flow15.txt index 11aaeb74f8ef..cd0030e769f0 100644 --- a/java/java-tests/testData/psi/controlFlow/flow15.txt +++ b/java/java-tests/testData/psi/controlFlow/flow15.txt @@ -1,27 +1,28 @@ 0: READ obj -1: COND_GOTO [END] 27 -2: COND_THROW_TO 9 -3: COND_THROW_TO 20 -4: EMPTY -5: THROW_TO 9 -6: COND_THROW_TO 20 -7: COND_THROW_TO 20 -8: GOTO [END] 16 -9: WRITE re -10: COND_THROW_TO 20 -11: READ re -12: EMPTY -13: COND_THROW_TO 20 -14: COND_THROW_TO 20 -15: GOTO [END] 16 -16: CALL 22 -17: GOTO [END] 27 -18: CALL 22 -19: GOTO [END] 27 RETURN -20: CALL 22 -21: GOTO [END] 26 -22: WRITE obj -23: RETURN FROM 22 -24: RETURN FROM 22 TO 19 -25: RETURN FROM 22 TO 21 -26: THROW_TO 27 \ No newline at end of file +1: COND_GOTO [END] 28 +2: COND_THROW_TO 10 +3: COND_THROW_TO 21 +4: COND_THROW_TO 21 +5: EMPTY +6: COND_THROW_TO 21 +7: THROW_TO 10 +8: COND_THROW_TO 21 +9: GOTO [END] 17 +10: WRITE re +11: COND_THROW_TO 21 +12: READ re +13: EMPTY +14: COND_THROW_TO 21 +15: COND_THROW_TO 21 +16: GOTO [END] 17 +17: CALL 23 +18: GOTO [END] 28 +19: CALL 23 +20: GOTO [END] 28 RETURN +21: CALL 23 +22: GOTO [END] 27 +23: WRITE obj +24: RETURN FROM 23 +25: RETURN FROM 23 TO 20 +26: RETURN FROM 23 TO 22 +27: THROW_TO 28 \ No newline at end of file diff --git a/java/java-tests/testData/psi/controlFlow/flow16.txt b/java/java-tests/testData/psi/controlFlow/flow16.txt index 41d81dc179ae..1719936f3c35 100644 --- a/java/java-tests/testData/psi/controlFlow/flow16.txt +++ b/java/java-tests/testData/psi/controlFlow/flow16.txt @@ -1,28 +1,30 @@ -0: COND_THROW_TO 8 -1: COND_THROW_TO 19 -2: EMPTY -3: COND_THROW_TO 8 -4: GOTO [END] 17 RETURN -5: COND_THROW_TO 19 -6: COND_THROW_TO 19 -7: GOTO [END] 15 -8: WRITE e -9: COND_THROW_TO 19 -10: EMPTY -11: THROW_TO 19 -12: COND_THROW_TO 19 -13: COND_THROW_TO 19 -14: GOTO [END] 15 -15: CALL 21 -16: GOTO [END] 28 -17: CALL 21 -18: GOTO [END] 28 RETURN -19: CALL 21 -20: GOTO [END] 27 -21: EMPTY -22: COND_THROW_TO 26 -23: RETURN FROM 21 -24: RETURN FROM 21 TO 18 -25: RETURN FROM 21 TO 20 -26: RETURN FROM 21 TO 20 -27: THROW_TO 28 \ No newline at end of file +0: COND_THROW_TO 9 +1: COND_THROW_TO 21 +2: COND_THROW_TO 21 +3: EMPTY +4: COND_THROW_TO 9 +5: COND_THROW_TO 21 +6: GOTO [END] 19 RETURN +7: COND_THROW_TO 21 +8: GOTO [END] 17 +9: WRITE e +10: COND_THROW_TO 21 +11: COND_THROW_TO 21 +12: EMPTY +13: COND_THROW_TO 21 +14: THROW_TO 21 +15: COND_THROW_TO 21 +16: GOTO [END] 17 +17: CALL 23 +18: GOTO [END] 30 +19: CALL 23 +20: GOTO [END] 30 RETURN +21: CALL 23 +22: GOTO [END] 29 +23: EMPTY +24: COND_THROW_TO 28 +25: RETURN FROM 23 +26: RETURN FROM 23 TO 20 +27: RETURN FROM 23 TO 22 +28: RETURN FROM 23 TO 22 +29: THROW_TO 30 \ No newline at end of file diff --git a/java/java-tests/testData/psi/controlFlow/flow18.txt b/java/java-tests/testData/psi/controlFlow/flow18.txt index dcaf7868b101..568fbf08d16e 100644 --- a/java/java-tests/testData/psi/controlFlow/flow18.txt +++ b/java/java-tests/testData/psi/controlFlow/flow18.txt @@ -1,28 +1,29 @@ -0: COND_THROW_TO 24 -1: COND_THROW_TO 24 -2: COND_THROW_TO 12 -3: EMPTY -4: THROW_TO 24 -5: COND_THROW_TO 12 -6: COND_THROW_TO 12 -7: GOTO [END] 8 -8: CALL 14 -9: GOTO [END] 23 -10: CALL 14 -11: GOTO [END] 28 RETURN -12: CALL 14 -13: GOTO [END] 22 -14: READ writer -15: EMPTY -16: COND_THROW_TO 21 -17: COND_THROW_TO 21 -18: RETURN FROM 14 -19: RETURN FROM 14 TO 11 -20: RETURN FROM 14 TO 13 -21: RETURN FROM 14 TO 24 -22: THROW_TO 28 -23: GOTO [END] 28 -24: WRITE e -25: READ e -26: EMPTY -27: GOTO [END] 28 \ No newline at end of file +0: COND_THROW_TO 25 +1: COND_THROW_TO 25 +2: COND_THROW_TO 13 +3: COND_THROW_TO 13 +4: EMPTY +5: COND_THROW_TO 13 +6: THROW_TO 25 +7: COND_THROW_TO 13 +8: GOTO [END] 9 +9: CALL 15 +10: GOTO [END] 24 +11: CALL 15 +12: GOTO [END] 29 RETURN +13: CALL 15 +14: GOTO [END] 23 +15: READ writer +16: EMPTY +17: COND_THROW_TO 22 +18: COND_THROW_TO 22 +19: RETURN FROM 15 +20: RETURN FROM 15 TO 12 +21: RETURN FROM 15 TO 14 +22: RETURN FROM 15 TO 25 +23: THROW_TO 29 +24: GOTO [END] 29 +25: WRITE e +26: READ e +27: EMPTY +28: GOTO [END] 29 \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DefUseTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DefUseTest.java index 3859d6668490..ab0666294925 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DefUseTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DefUseTest.java @@ -74,6 +74,7 @@ public class DefUseTest extends LightJavaCodeInsightFixtureTestCase { public void testLastInTry() { doTest(); } public void testFieldOverwrite() { doTest(); } public void testFieldOverwriteAfterQualifierUpdate() { doTest(); } + public void testAssignmentInCatch() { doTest(); } @NotNull @Override