| /* |
| * @test /nodynamiccopyright/ |
| * @bug 8206986 8222169 8224031 8240964 8267119 8268670 8321582 |
| * @summary Check expression switch works. |
| * @compile ExpressionSwitch.java |
| * @run main ExpressionSwitch |
| */ |
| |
| // * @compile/fail/ref=ExpressionSwitch-old.out --release 9 -XDrawDiagnostics ExpressionSwitch.java |
| import java.util.Objects; |
| import java.util.function.Supplier; |
| |
| public class ExpressionSwitch { |
| public static void main(String... args) { |
| new ExpressionSwitch().run(); |
| } |
| |
| private void run() { |
| check(T.A, "A"); |
| check(T.B, "B"); |
| check(T.C, "other"); |
| assertEquals(exhaustive1(T.C), "C"); |
| assertEquals(scopesIsolated(T.B), "B"); |
| assertEquals(lambdas1(T.B).get(), "B"); |
| assertEquals(lambdas2(T.B).get(), "B"); |
| assertEquals(convert1("A"), 0); |
| assertEquals(convert1("B"), 0); |
| assertEquals(convert1("C"), 1); |
| assertEquals(convert1(""), -1); |
| assertEquals(convert1(null), -2); |
| assertEquals(convert2("A"), 0); |
| assertEquals(convert2("B"), 0); |
| assertEquals(convert2("C"), 1); |
| assertEquals(convert2(""), -1); |
| localClass(T.A); |
| assertEquals(castSwitchExpressions(T.A), "A"); |
| testTypeInference(true, 0); |
| assertEquals(yieldPrimitiveDotClass("byte"), byte.class); |
| assertEquals(yieldPrimitiveDotClass("char"), char.class); |
| assertEquals(yieldPrimitiveDotClass("short"), short.class); |
| assertEquals(yieldPrimitiveDotClass("int"), int.class); |
| assertEquals(yieldPrimitiveDotClass("long"), long.class); |
| assertEquals(yieldPrimitiveDotClass("float"), float.class); |
| assertEquals(yieldPrimitiveDotClass("double"), double.class); |
| assertEquals(yieldPrimitiveDotClass("void"), void.class); |
| assertEquals(yieldPrimitiveDotClass("boolean"), boolean.class); |
| assertEquals(yieldPrimitiveDotClass("other"), null); |
| } |
| |
| private String print(T t) { |
| return switch (t) { |
| case A -> "A"; |
| case B -> { yield "B"; } |
| default -> { yield "other"; } |
| }; |
| } |
| |
| private String exhaustive1(T t) { |
| return switch (t) { |
| case A -> "A"; |
| case B -> { yield "B"; } |
| case C -> "C"; |
| case D -> "D"; |
| }; |
| } |
| |
| private String exhaustive2(T t) { |
| return switch (t) { |
| case A -> "A"; |
| case B -> "B"; |
| case C -> "C"; |
| case D -> "D"; |
| }; |
| } |
| |
| private String scopesIsolated(T t) { |
| return switch (t) { |
| case A -> { String res = "A"; yield res;} |
| case B -> { String res = "B"; yield res;} |
| default -> { String res = "default"; yield res;} |
| }; |
| } |
| |
| private Supplier<String> lambdas1(T t) { |
| return switch (t) { |
| case A -> () -> "A"; |
| case B -> { yield () -> "B"; } |
| default -> () -> "default"; |
| }; |
| } |
| |
| private Supplier<String> lambdas2(T t) { |
| return switch (t) { |
| case A: yield () -> "A"; |
| case B: { yield () -> "B"; } |
| default: yield () -> "default"; |
| }; |
| } |
| |
| private int convert1(String s) { |
| return s == null |
| ? -2 |
| : switch (s) { |
| case "A", "B" -> 0; |
| case "C" -> { yield 1; } |
| default -> -1; |
| }; |
| } |
| |
| private int convert2(String s) { |
| return switch (s) { |
| case "A", "B": yield 0; |
| case "C": yield 1; |
| default: yield -1; |
| }; |
| } |
| |
| private Object yieldDisambiguationLiterals(String s) { |
| return switch (s) { |
| case "a": yield 0; |
| case "b": yield 0L; |
| case "c": yield 0.0f; |
| case "d": yield 0.0d; |
| case "e": yield true; |
| case "f": yield false; |
| case "g": yield '0'; |
| case "h": yield ""; |
| case "i": yield null; |
| default: yield 0; |
| }; |
| } |
| |
| private int yieldUnaryNumberOperator(String s, int a) { |
| return switch (s) { |
| case "a": yield +a; |
| case "b": yield -a; |
| case "c": yield ~a; // intentionally repeated ~a, test the case clause |
| case "d": yield ++a; |
| case "e": yield --a; |
| case "f": yield a++; |
| case "g": yield a--; |
| default: yield ~a; // intentionally repeated ~a, test the default clause |
| }; |
| } |
| |
| private boolean yieldUnaryNotOperator(String s, boolean b) { |
| return switch (s) { |
| case "a": yield !b; // intentionally repeated !b, test the case clause |
| default: yield !b; // intentionally repeated !b, test the default clause |
| }; |
| } |
| |
| private Class<?> yieldPrimitiveDotClass(String s) { |
| return switch (s) { |
| case "byte": yield byte.class; |
| case "char": yield char.class; |
| case "short": yield short.class; |
| case "int": yield int.class; |
| case "long": yield long.class; |
| case "float": yield float.class; |
| case "double": yield double.class; |
| case "void": yield void.class; |
| case "boolean": yield boolean.class; |
| default: yield null; |
| }; |
| } |
| |
| private void localClass(T t) { |
| String good = "good"; |
| class L { |
| public String c() { |
| STOP: switch (t) { |
| default: break STOP; |
| } |
| return switch (t) { |
| default: yield good; |
| }; |
| } |
| } |
| String result = new L().c(); |
| if (!Objects.equals(result, good)) { |
| throw new AssertionError("Unexpected result: " + result); |
| } |
| } |
| |
| private String castSwitchExpressions(T t) { |
| return (String) switch (t) { |
| case A -> "A"; |
| default -> 1; |
| }; |
| } |
| |
| private void testTypeInference(boolean b, int i) { |
| m(s -> s.length(), String.class); |
| m(b ? s -> s.length() : s -> s.length(), String.class); |
| m(switch (i) { |
| case 0 -> s -> s.length(); |
| default -> s -> s.length(); |
| }, String.class); |
| } |
| |
| <Z> void m(Consumer<Z> c, Class<Z> cl) {} |
| |
| private void check(T t, String expected) { |
| String result = print(t); |
| assertEquals(result, expected); |
| } |
| |
| private void assertEquals(Object result, Object expected) { |
| if (!Objects.equals(result, expected)) { |
| throw new AssertionError("Unexpected result: " + result); |
| } |
| } |
| |
| enum T { |
| A, B, C, D; |
| } |
| void t() { |
| Runnable r = () -> {}; |
| r.run(); |
| } |
| |
| interface Consumer<Z> { |
| public void consume(Z z); |
| } |
| } |