Java: Extend control flow analysis to support enhanced switch & switch expression, including break-with-value (IDEA-202131)

This commit is contained in:
Pavel Dolgov
2018-11-21 16:36:48 +03:00
parent 84aa9b4bf5
commit 9fc8a64cd6
3 changed files with 105 additions and 51 deletions
@@ -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(<error descr="Variable 'n' might not have been initialized">n</error>);
}
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(<error descr="Variable 'n' might not have been initialized">n</error>);
}
}
@@ -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); <error descr="Unreachable statement">break 1;</error>}
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(<error descr="Variable 'n' might not have been initialized">n</error>);
}
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");
}
<error descr="Unreachable statement">System.out.println("c");</error>
}
int bar(int i) throws Exception { return i; }
}
static class SwitchStatementReturnsFromTry {
int foo(String s) throws Exception {
try {