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 7714669d42ef..3e7703965943 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 @@ -397,7 +397,9 @@ class ControlFlowAnalyzer extends JavaElementVisitor { @Override public void visitBreakStatement(PsiBreakStatement statement) { startElement(statement); - PsiStatement exitedStatement = statement.findExitedStatement(); + generateExpressionInstructions(statement.getValueExpression()); + + PsiElement exitedStatement = statement.findExitedElement(); if (exitedStatement != null) { callFinallyBlocksOnExit(exitedStatement); @@ -419,7 +421,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { finishElement(statement); } - private void callFinallyBlocksOnExit(PsiStatement exitedStatement) { + private void callFinallyBlocksOnExit(PsiElement exitedStatement) { for (final ListIterator it = myFinallyBlocks.listIterator(myFinallyBlocks.size()); it.hasPrevious(); ) { final FinallyBlockSubroutine finallyBlockSubroutine = it.previous(); PsiElement finallyBlock = finallyBlockSubroutine.getElement(); @@ -503,13 +505,8 @@ class ControlFlowAnalyzer extends JavaElementVisitor { private void processVariable(@NotNull PsiVariable element) { final PsiExpression initializer = element.getInitializer(); - if (initializer != null) { - myStartStatementStack.pushStatement(initializer, false); - myEndStatementStack.pushStatement(initializer, false); - initializer.accept(this); - myStartStatementStack.popStatement(); - myEndStatementStack.popStatement(); - } + generateExpressionInstructions(initializer); + if (element instanceof PsiLocalVariable && initializer != null || element instanceof PsiField) { if (element instanceof PsiLocalVariable && !myPolicy.isLocalVariableAccepted((PsiLocalVariable)element)) return; @@ -839,13 +836,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { startElement(statement); PsiExpression caseValue = statement.getCaseValue(); - if (caseValue != null) { - myStartStatementStack.pushStatement(caseValue, false); - myEndStatementStack.pushStatement(caseValue, false); - caseValue.accept(this); - myStartStatementStack.popStatement(); - myEndStatementStack.popStatement(); - } + generateExpressionInstructions(caseValue); finishElement(statement); } @@ -857,11 +848,8 @@ class ControlFlowAnalyzer extends JavaElementVisitor { if (caseValues != null) { for (PsiExpression caseValue : caseValues.getExpressions()) { - myStartStatementStack.pushStatement(caseValue, false); - myEndStatementStack.pushStatement(caseValue, false); - caseValue.accept(this); - myStartStatementStack.popStatement(); - myEndStatementStack.popStatement(); + ProgressManager.checkCanceled(); + generateExpressionInstructions(caseValue); } } @@ -1321,6 +1309,13 @@ class ControlFlowAnalyzer extends JavaElementVisitor { PsiExpression[] expressions = list.getExpressions(); for (final PsiExpression expression : expressions) { ProgressManager.checkCanceled(); + generateExpressionInstructions(expression); + } + } + + private void generateExpressionInstructions(@Nullable PsiExpression expression) { + if (expression != null) { + // handle short circuit myStartStatementStack.pushStatement(expression, false); myEndStatementStack.pushStatement(expression, false); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchDefinitelyAssigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchDefinitelyAssigned.java index e40f0685eee6..885bc9b05fd0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchDefinitelyAssigned.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchDefinitelyAssigned.java @@ -105,4 +105,76 @@ class C { default -> 0; }; } + + static class FinalFieldSwitchExpression { + final String s = switch ((int)Math.random()) { + case 1 -> "a"; + default -> "?"; + }; + { + System.out.println(s); + } + } + + static class FinalFieldValueBreakSwitchExpression { + final String s = switch ((int)Math.random()) { + case 1: break "a"; + default: break "?"; + }; + { + System.out.println(s); + } + } + + void finalVariableSwitchExpression(String s) { + final int n = switch (s) { + case "a" -> 1; + default -> 0; + }; + System.out.println(n); + } + + void finalVariableValueBreakSwitchExpression(String s) { + final int n = switch (s) { + case "a": break 1; + default: break 0; + }; + System.out.println(n); + } + + void definitelyAssignedInSwitchExpression(String s) { + int n; + int x = switch (s) { + case "a" -> n = 1; + default -> n = 0; + }; + System.out.println(n); + } + + void notDefinitelyAssignedInSwitchExpression(String s) { + int n; + int x = switch (s) { + case "a" -> n = 1; + default -> 0; + }; + System.out.println(n); + } + + void definitelyAssignedInSwitchExpressionValueBreak(String s) { + int n; + int x = switch (s) { + case "a": break n = 1; + default: break n = 0; + }; + System.out.println(n); + } + + void notDefinitelyAssignedInSwitchExpressionValueBreak(String s) { + int n; + int x = switch (s) { + case "a": break n = 1; + default: break 0; + }; + System.out.println(n); + } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchUnreachable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchUnreachable.java index 034238b8db3f..b9670ce15f08 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchUnreachable.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting12/EnhancedSwitchUnreachable.java @@ -45,41 +45,13 @@ class C { System.out.println(); } - /* todo - void endlessLoopInBranchWithValue(String arg) { + void endlessLoopInBranchWithValueBreak(String arg) { int result = switch (arg) { - case "one" -> { while(true); break 1;} + case "one" -> { while(true); break 1;} default -> 0; }; System.out.println(result); } - */ - - static class FinalFieldSwitchExpression { - final String s = switch ((int)Math.random()) { - case 1 -> "a"; - default -> "?"; - }; - { - System.out.println(s); - } - } - - void finalVariableSwitchExpression(String s) { - final int n = switch (s) { - case "a" -> 1; - default -> 0; - }; - System.out.println(n); - } - - void notDefinitelyAssigned(String s) { - int n; - switch (s) { - case "a" -> n = 1; - } - System.out.println(n); - } int returnBeforeEnhancedSwitchStatement(String s) { return 2; @@ -129,6 +101,21 @@ class C { int bar(int i) throws Exception { return i; } } + static class ValueBreakSwitchExpressionReturnedFromTry { + int foo(String s) throws Exception { + try { + return switch (s) { + case "a": break bar(1); + default: break bar(0); + }; + } finally { + System.out.println("b"); + } + System.out.println("c"); + } + int bar(int i) throws Exception { return i; } + } + static class SwitchStatementReturnsFromTry { int foo(String s) throws Exception { try {