java: dedicated switch expressions test

make tests on preview features disconnected from language level to make them evolve easily

GitOrigin-RevId: f87bbf684355bce7ae97711a0fc9b5861d58f775
This commit is contained in:
Anna Kozlova
2019-07-02 06:52:16 +03:00
committed by intellij-monorepo-bot
parent 594e81ebd7
commit 89fa4186d6
10 changed files with 3 additions and 3 deletions
@@ -0,0 +1,219 @@
class C {
void finalVariableAssignedInAllBranches(int k) {
final String s;
switch (k) {
case 1 -> s = "a";
case 2 -> s = "b";
case 3, 4 -> s = "c";
default -> s = "d";
}
System.out.println(s);
}
enum EnumAB {A, B}
void finalVariableAssignedInAllEnumConstantBranches(EnumAB ab) {
final int n;
switch (ab) {
case A -> n = 1;
case B -> n = 2;
}
System.out.println(<error descr="Variable 'n' might not have been initialized">n</error>);
}
void assignedInSomeBranches(String s) {
int n;
switch ((int)Math.random()) {
case 1 -> n = 1;
default -> {}
}
System.out.println(<error descr="Variable 'n' might not have been initialized">n</error>);
}
void finalVariableReassignedAfterSwitchStatement(int n) {
final String s;
switch (n) {
case 1 -> s = "a";
default -> {}
}
<error descr="Variable 's' might already have been assigned to">s</error> = "b";
System.out.println(s);
}
void finalVariableReassignedAfterSwitchExpression(int n) {
final String s;
String t = switch (n) {
case 1 -> s = "a";
default -> "";
};
<error descr="Variable 's' might already have been assigned to">s</error> = t;
System.out.println(s);
}
void finalVariableReassignedInSwitchStatement(int n) {
final String s = "b";
switch (n) {
case 1 -> <error descr="Cannot assign a value to final variable 's'">s</error> = "a";
default -> {}
};
System.out.println(s);
}
void finalVariableReassignedInSwitchExpression(int n) {
final String s = "b";
String string = switch (n) {
case 1 -> <error descr="Cannot assign a value to final variable 's'">s</error> = "a";
default -> "";
};
System.out.println(s);
}
static class FinalFieldAssignedInSomeBranches {
<error descr="Variable 'n' might not have been initialized">final int n</error>;
{
switch ((int)Math.random()) {
case 1 -> n = 1;
default -> {}
}
}
}
static class FinalFieldAssignedInSomeBranchesNoDefault {
<error descr="Variable 'n' might not have been initialized">final int n</error>;
{
switch ((int)Math.random()) {
case 1 -> n = 1;
case 0 -> n = 0;
}
}
}
static class FinalFieldAssignedInAllBranches {
final int n;
{
switch ((int)Math.random()) {
case 1 -> n = 1;
default -> n = 0;
}
}
}
static class FinalFieldInitializedWithswitchExpression {
final int n =
switch ((int)Math.random()) {
case 1 -> 1;
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>);
}
void switchExpressionAssignedInFinally(int n) {
String s;
try {
} finally {
s = switch (n) {
case -1 -> throw new RuntimeException();
case 0 -> "a";
default -> "b";
};
}
System.out.println(s);
}
void allSwitchRulesAssignInFinally(int n) {
String s;
try {
} finally {
String string = switch (n) {
case -1 -> throw new RuntimeException();
case 0 -> s = "a";
default -> { break s = "b"; }
};
}
System.out.println(s);
}
void notAllSwitchRulesAssignInFinally(int n) {
String s;
try {
} finally {
String t = switch (n) {
case -1 -> throw new RuntimeException();
case 0 -> s = "a";
default -> "b";
};
}
System.out.println(<error descr="Variable 's' might not have been initialized">s</error>);
}
}
@@ -0,0 +1,86 @@
import java.util.Random;
class EnhancedSwitchStatements {
static final int FI = 4;
enum E { E1, E2 }
void m(String... args) {
String count;
switch (args.length) {
case 0 -> throw new IllegalStateException("no args");
case 1 -> count = "one";
default -> { count = "many"; }
}
switch (new Random().nextInt()) {
case 0 -> throw new IllegalStateException("no args");
<error descr="Statement must be prepended with case label">break;</error>
}
switch (new Random().nextInt()) {
case 0 -> throw new IllegalStateException("no args");
<error descr="Different case kinds used in the switch">case 1:</error> break;
}
switch (new Random().nextInt()) {
case 0: throw new IllegalStateException("no args"); break;
<error descr="Different case kinds used in the switch">case 1 -> { System.out.println("one"); }</error>
}
{ <error descr="Case statement outside switch">case 11 -> System.out.println("hi there");</error> }
{ <error descr="Case statement outside switch">default -> System.out.println("hi there");</error> }
switch (new Random().nextInt()) {
case 42 -> <error descr="Not a statement">"bingo";</error>
}
switch (new Random().nextInt()) {
<error descr="Duplicate default label">default</error> -> noop();
case 1 -> noop();
<error descr="Duplicate default label">default</error> -> noop();
}
switch (new Random().nextInt()) {
case <error descr="Duplicate label '1'">FI/2 - 1</error> -> noop();
case <error descr="Duplicate label '1'">(1 + 35/16) % 2</error> -> noop();
case FI - 8 -> noop();
}
final byte b = 127;
switch (new Random().nextInt()) {
case <error descr="Duplicate label '127'">b</error> -> System.out.println("b=" + b + ";");
case <error descr="Duplicate label '127'">127</error> -> System.out.println("sweet spot");
}
switch (0) {
case 0 -> noop();
case "\410" == "!0" ? 1 : 0 -> noop();
case "" == "" + "" ? 3 : 0 -> noop();
}
switch (E.valueOf("E1")) {
case E1 -> noop();
}
switch (E.valueOf("E1")) {
case <error descr="Constant expression required">null</error> -> noop();
case <error descr="An enum switch case label must be the unqualified name of an enumeration constant">E.E1</error> -> noop();
case E2 -> noop();
case <error descr="Incompatible types. Found: 'int', required: 'EnhancedSwitchStatements.E'">1</error> -> noop();
}
switch (new Random().nextInt()) {
case <error descr="Duplicate label '1'">1</error>, <error descr="Duplicate label '1'">1</error> -> noop();
}
switch (new Random().nextInt()) {
case 1, <error descr="Duplicate label '2'">2</error>:
noop(); break;
case 3, <error descr="Duplicate label '2'">2</error>:
noop(); break;
}
switch (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum'">new Object()</error>) { }
}
private static void noop() { }
}
@@ -0,0 +1,157 @@
class C {
void alwaysThrow(String s) {
switch (s) {
case "a" -> throw new IllegalArgumentException();
default -> throw new IllegalStateException();
}
<error descr="Unreachable statement">System.out.println();</error>
}
void breakFromEndlessLoop() {
EndlessLoop:
for (;;) {
switch ((int)Math.random()) {
case 1 -> {break EndlessLoop;}
default -> throw new RuntimeException();
}
}
System.out.println();
}
void continueEndlessLoop() {
EndlessLoop:
for (;;) {
switch ((int)Math.random()) {
case 1 -> {continue EndlessLoop;}
default -> throw new RuntimeException();
}
}
<error descr="Unreachable statement">System.out.println();</error>
}
void endlessLoopsInAllBranches(String s) {
switch (s) {
case "a" -> { while(true); }
default -> { for(;;); }
}
<error descr="Unreachable statement">System.out.println();</error>
}
void endlessLoopInBranch(String s) {
switch (s) {
case "a" -> { while(true); }
default -> {}
};
System.out.println();
}
void endlessLoopInBranchWithValueBreak(String arg) {
int result = switch (arg) {
case "one" -> { while(true); <error descr="Unreachable statement">break 1;</error>}
default -> 0;
};
System.out.println(result);
}
int returnBeforeEnhancedSwitchStatement(String s) {
return 2;
<error descr="Unreachable statement">switch</error>(s) {
case "a" -> {return 1;}
default -> {return 0;}
}
}
int returnBeforeSwitchExpressionInInitializer(String s) {
return 2;
int n = <error descr="Unreachable statement">switch</error>(s) {
case "a" -> 1;
default -> 0;
};
}
int returnBeforeSwitchExpressionInAssignment(String s) {
int n;
return 2;
n = <error descr="Unreachable statement">switch</error>(s) {
case "a": n = 1; break 1;
default: n = 0; break 0;
};
}
int returnSwitchExpression(String s) {
return switch(s) {
case "a" -> 1;
default -> 0;
};
<error descr="Unreachable statement">System.out.println();</error>
}
void switchExpressionUnreachableInFinally(int n) {
String s;
try {
} finally {
return;
s = <error descr="Unreachable statement">switch</error> (n) {
case 0 -> "a";
default -> "b";
};
}
}
void switchExpressionReachableInFinally(int n) {
String s;
try {
return;
} finally {
s = switch (n) {
case 0 -> "a";
default -> "b";
};
}
}
static class SwitchExpressionReturnedFromTry {
int foo(String s) throws Exception {
try {
return switch (s) {
case "a" -> bar(1);
default -> 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 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 {
switch (s) {
case "a" -> { return bar(1); }
default -> { return bar(0); }
}
} finally {
System.out.println("b");
}
<error descr="Unreachable statement">System.out.println("c");</error>
}
int bar(int i) throws Exception { return i; }
}
}
@@ -0,0 +1,121 @@
import java.util.function.*;
class MyTest {
<T> T foo(T t) {
return t;
}
<T> T foo(Supplier<T> t) {
return t.get();
}
<T> T foo(IntSupplier t) {
return null;
}
static <K> K bar() {
return null;
}
void m(int i) {
String s = foo(switch (i) {default -> "str";});
String s1 = <error descr="Incompatible types. Required String but 'foo' was inferred to T:
no instance(s) of type variable(s) exist so that Object conforms to String">foo(switch (i) {case 1 -> new Object(); default -> "str";});</error>
String s2 = foo(() -> switch (i) {
default -> "str";
});
String s3 = foo(() -> switch (i) {default -> bar();});
String s4 = foo(() -> switch (i) {default -> { break bar();}});
String s5 = foo(<error descr="Incompatible types. Required String but 'foo' was inferred to T:
no instance(s) of type variable(s) exist so that Integer conforms to String">() -> switch (i) {default -> { break 1;}}</error>);
String s6 = switch (i) {
case 1 -> <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">2</error>;
default -> {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
}
};
Supplier<String> stringSupplier = switch (i) {
default -> {
break () -> <error descr="Bad return type in lambda expression: int cannot be converted to String">1</error>;
}
};
String s7 = switch (i) {
case 1: {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
}
default: {
int i1 = switch (0) {
default -> {
break 1;
}
};
break "";
}
};
}
void switchChain(final int i) {
String s = switch (i) {
default -> switch (0) {
default -> {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
}
};
};
String s1 = switch (i) {
default -> {
break switch (0) {
default -> {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
}
};
}
};
String s2 = switch (i) {
default: {
break switch (0) {
default -> {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
}
};
}
};
String s3 = switch (0) {
default: {
break switch (1) {
case 2: {
System.out.println();
int inside_switch = switch (8) {
default:
break 1;
};
}
case 1:
if (i > 3) break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">3</error>;
case 0:
try {
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">42</error>;
} finally {
//do nothing
}
default:
break <error descr="Bad type in switch expression: int cannot be converted to java.lang.String">1</error>;
};
}
};
Runnable r = () -> <error descr="Target type for switch expression cannot be void">switch</error>(0) {
default -> throw new IllegalArgumentException();
};
}
static void test(boolean b, int i) {
Class<?> c = (b ?
switch (i) {
case 1 -> true;
default -> 0;
} : 1).getClass();
System.out.println(c.getCanonicalName());
}
}
@@ -0,0 +1,149 @@
class C {
void defaultBranchHasNoResult(int n) {
String s = <error descr="Switch expression should produce result in all execution paths">switch</error> (n) {
default:
};
}
void defaultRuleHasNoResult(int n) {
String s = switch (n) {
<error descr="Switch expression rule should produce result in all execution paths">default</error> -> {}
};
}
void defaultBranchSometimesHasNoResult(int n, boolean b) {
String s = <error descr="Switch expression should produce result in all execution paths">switch</error> (n) {
default: {
if (b) break "";
}
};
}
void defaultRuleSometimesHasNoResult(int n, boolean b) {
String s = switch (n) {
<error descr="Switch expression rule should produce result in all execution paths">default</error> -> {
if (b) break "";
}
};
}
void defaultBranchAlwaysThrows(int n) {
String s = switch (n) {
default: throw new RuntimeException();
};
}
void defaultRuleAlwaysThrows(int n) {
String s = switch (n) {
default -> throw new RuntimeException();
};
}
void defaultBranchSometimesThrows(int n, boolean b) {
String s = switch (n) {
default:
if (b) throw new RuntimeException();
break "";
};
}
void defaultRuleSometimesThrows(int n, boolean b) {
String s = switch (n) {
default -> {
if (b) throw new RuntimeException();
break "";
}
};
}
void defaultBranchHasManyResults(int n, int k) {
String s = switch (n) {
default: {
if (k < n) break "a";
if (k > n) break "b";
break "c";
}
};
}
void defaultRuleHasManyResults(int n, int k) {
String s = switch (n) {
default -> {
if (k < n) break "a";
if (k > n) break "b";
break "c";
}
};
}
void oneOfBranchesHasNoResult(int n) {
String s = <error descr="Switch expression should produce result in all execution paths">switch</error> (n) {
case 0: break "";
default:
};
}
void oneOfRulesHasNoResult(int n) {
String s = switch (n) {
case 0 -> "";
<error descr="Switch expression rule should produce result in all execution paths">default</error> -> {
}
};
}
void allBranchesHaveNoResult(int n) {
String s = <error descr="Switch expression should produce result in all execution paths">switch</error> (n) {
case 0:
default:
};
}
void allRulesHaveNoResult(int n) {
String s = switch (n) {
<error descr="Switch expression rule should produce result in all execution paths">case</error> 0 -> {
}
<error descr="Switch expression rule should produce result in all execution paths">default</error> -> {
}
};
}
void allBranchesDoHaveResult(int n) {
String s = switch (n) {
case -1: throw new RuntimeException();
case 0: break "a";
default: break "b";
};
}
void allRulesDoHaveResult(int n) {
String s = switch (n) {
case -1 -> throw new RuntimeException();
case 0 -> "a";
default -> "b";
};
}
void allBranchesDoHaveResultInFinally(int n) {
String s;
try {
} finally {
s = switch (n) {
case -1: throw new RuntimeException();
case 0: break "a";
default: break "b";
};
}
}
void allRulesDoHaveResultInFinally(int n) {
String s;
try {
} finally {
s = switch (n) {
case -1 -> throw new RuntimeException();
case 0 -> "a";
default -> "b";
};
}
}
}
@@ -0,0 +1,68 @@
import java.util.Random;
class SwitchExpressions {
enum E { E1, E2 }
void m() {
System.out.println(switch (new Random().nextInt()) {
default -> "whatever";
});
System.out.println(switch (<error descr="'switch' expression does not have any case clauses">new Random().nextInt()</error>) { });
System.out.println(switch (new Random().nextInt()) {
case 0 -> throw new IllegalStateException("no args");
<error descr="Different case kinds used in the switch">case 1:</error> break "lone";
});
System.out.println(
switch (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum'">new Object()</error>) {
default -> "whatever";
}
);
System.out.println(switch (E.valueOf("E1")) {
case <error descr="Constant expression required">null</error> -> 0;
case <error descr="An enum switch case label must be the unqualified name of an enumeration constant">E.E1</error> -> 1;
case E2 -> 2;
case <error descr="Incompatible types. Found: 'int', required: 'SwitchExpressions.E'">1</error> -> 1;
});
System.out.println(switch (new Random().nextInt()) {
<error descr="Duplicate default label">default</error> -> -1;
case 1 -> 1;
<error descr="Duplicate default label">default</error> -> 0;
});
System.out.println(switch (<error descr="'switch' expression does not cover all possible input values">new Random().nextInt()</error>) {
case 1 -> 1;
});
System.out.println(switch (<error descr="'switch' expression does not cover all possible input values">E.valueOf("E1")</error>) {
case E1 -> 1;
});
System.out.println(switch (E.valueOf("E1")) {
case E1 -> 1;
case E2 -> 2;
});
lab: while (true) {
switch (new Random().nextInt()) {
case -1: return;
case -2: continue lab;
default: break lab;
}
System.out.println(switch (new Random().nextInt()) {
case -1: <error descr="Return outside of enclosing switch expression">return;</error>
case -2: <error descr="Continue outside of enclosing switch expression">continue lab;</error>
case -3: <error descr="Continue outside of enclosing switch expression">continue;</error>
default: <error descr="Break outside of enclosing switch expression">break lab;</error>
});
}
}
enum Empty {}
boolean testEmpty(Empty e) {
return switch (<error descr="'switch' expression does not have any case clauses">e</error>) {};
}
}
@@ -0,0 +1,12 @@
import java.util.Random;
class SwitchExpressionsEnumResolve {
enum E { E1, E2 }
E test(E e) {
return switch (e) {
case E1 -> <error descr="Cannot resolve symbol 'E2'">E2</error>;
case E2 -> <error descr="Cannot resolve symbol 'E1'">E1</error>;
};
}
}
@@ -0,0 +1,49 @@
class SwitchExpressions {
byte B = 1;
short S = 1;
char C = 1;
final int I = 1;
void m(int i) {
var v1 = switch(i) {
case 1 -> 1;
default -> 1.0;
};
double d = v1;
<error descr="Incompatible types. Found: 'double', required: 'float'">float f = v1;</error>
<error descr="Incompatible types. Found: 'double', required: 'int'">int in = v1;</error>
var v2 = switch (i) {
case 1 -> C;
default -> I;
};
in = v2;
<error descr="Incompatible types. Found: 'char', required: 'byte'">byte b = v2;</error>
<error descr="Incompatible types. Found: 'char', required: 'short'">short s = v2;</error>
char c = v2;
var v3 = switch (i) {
case 1 -> B;
default -> I;
};
in = v3;
b = v3;
s = v3;
<error descr="Incompatible types. Found: 'byte', required: 'char'">c = v3</error>;
var v4 = switch (i) {
case 1 -> B;
default -> Integer.MAX_VALUE;
};
in = v4;
<error descr="Incompatible types. Found: 'int', required: 'byte'">b = v4</error>;
<error descr="Incompatible types. Found: 'int', required: 'short'">s = v4</error>;
<error descr="Incompatible types. Found: 'int', required: 'char'">c = v4</error>;
}
}
@@ -0,0 +1,57 @@
class ValueBreaks {
static final int ref = -1;
void m() {
l1: break l1;
<error descr="Break outside switch or loop">break;</error>
break <error descr="Undefined label: 'wtf'">wtf</error>;
<error descr="Value break outside switch expression">break 42;</error>
switch (0) {
case 0: <error descr="Value break outside switch expression">break 42;</error>
case 1: break <error descr="Undefined label: 'ref'">ref</error>;
case 2: break <error descr="Undefined label: 'wtf'">wtf</error>;
case 3: ref: break ref;
case 4: ref: <error descr="Value break outside switch expression">break (ref);</error>
};
sink(switch (0) {
case 0 -> { while (true) <error descr="Value break outside switch expression">break 42;</error> }
case 1 -> { while (true) <error descr="Value break outside switch expression">break ref;</error> }
case 2 -> { while (true) break <error descr="Undefined label: 'wtf'">wtf</error>; }
case 3 -> { break ref; }
case 4 -> { break (ref); }
case 5 -> { break <error descr="Cannot resolve symbol 'wtf'">wtf</error>; }
case 6 -> {
int a = 0;
a: switch (0) {
default: break <error descr="Reference to 'a' is ambiguous, both 'a:' and 'variable a' match">a</error>;
}
}
default -> throw new RuntimeException();
});
switch (0) {
case 0 -> { while (true) break <error descr="Undefined label: 'ref'">ref</error>; }
case 1 -> {
int a = 0;
a: switch (0) {
default: break a;
}
}
}
ref: sink(switch (0) {
default: break <error descr="Reference to 'ref' is ambiguous, both 'ref:' and 'ValueBreaks.ref' match">ref</error>;
});
while (true) {
sink(switch (0) {
default: <error descr="Missing break value">break;</error>
});
}
}
private static void sink(Object o) { }
}