1 /*
2  * @test /nodynamiccopyright/
3  * @bug 8206986 8222169 8224031
4  * @summary Check expression switch works.
5  * @compile/fail/ref=ExpressionSwitch-old.out -source 9 -Xlint:-options -XDrawDiagnostics ExpressionSwitch.java
6  * @compile --enable-preview -source ${jdk.version} ExpressionSwitch.java
7  * @run main/othervm --enable-preview ExpressionSwitch
8  */
9 
10 import java.util.Objects;
11 import java.util.function.Supplier;
12 
13 public class ExpressionSwitch {
main(String... args)14     public static void main(String... args) {
15         new ExpressionSwitch().run();
16     }
17 
run()18     private void run() {
19         check(T.A, "A");
20         check(T.B, "B");
21         check(T.C, "other");
22         assertEquals(exhaustive1(T.C), "C");
23         assertEquals(scopesIsolated(T.B), "B");
24         assertEquals(lambdas1(T.B).get(), "B");
25         assertEquals(lambdas2(T.B).get(), "B");
26         assertEquals(convert1("A"), 0);
27         assertEquals(convert1("B"), 0);
28         assertEquals(convert1("C"), 1);
29         assertEquals(convert1(""), -1);
30         assertEquals(convert1(null), -2);
31         assertEquals(convert2("A"), 0);
32         assertEquals(convert2("B"), 0);
33         assertEquals(convert2("C"), 1);
34         assertEquals(convert2(""), -1);
35         localClass(T.A);
36         assertEquals(castSwitchExpressions(T.A), "A");
37     }
38 
print(T t)39     private String print(T t) {
40         return switch (t) {
41             case A -> "A";
42             case B -> { yield "B"; }
43             default -> { yield "other"; }
44         };
45     }
46 
exhaustive1(T t)47     private String exhaustive1(T t) {
48         return switch (t) {
49             case A -> "A";
50             case B -> { yield "B"; }
51             case C -> "C";
52             case D -> "D";
53         };
54     }
55 
56     private String exhaustive2(T t) {
57         return switch (t) {
58             case A -> "A";
59             case B -> "B";
60             case C -> "C";
61             case D -> "D";
62         };
63     }
64 
65     private String scopesIsolated(T t) {
66         return switch (t) {
67             case A -> { String res = "A"; yield res;}
68             case B -> { String res = "B"; yield res;}
69             default -> { String res = "default"; yield res;}
70         };
71     }
72 
73     private Supplier<String> lambdas1(T t) {
74         return switch (t) {
75             case A -> () -> "A";
76             case B -> { yield () -> "B"; }
77             default -> () -> "default";
78         };
79     }
80 
81     private Supplier<String> lambdas2(T t) {
82         return switch (t) {
83             case A: yield () -> "A";
84             case B: { yield () -> "B"; }
85             default: yield () -> "default";
86         };
87     }
88 
89     private int convert1(String s) {
90         return s == null
91                 ? -2
92                 : switch (s) {
93                       case "A", "B" -> 0;
94                       case "C" -> { yield 1; }
95                       default -> -1;
96                   };
97     }
98 
99     private int convert2(String s) {
100         return switch (s) {
101             case "A", "B": yield 0;
102             case "C": yield 1;
103             default: yield -1;
104         };
105     }
106 
107     private void localClass(T t) {
108         String good = "good";
109         class L {
110             public String c() {
111                 STOP: switch (t) {
112                     default: break STOP;
113                 }
114                 return switch (t) {
115                     default: yield good;
116                 };
117             }
118         }
119         String result = new L().c();
120         if (!Objects.equals(result, good)) {
121             throw new AssertionError("Unexpected result: " + result);
122         }
123     }
124 
125     private String castSwitchExpressions(T t) {
126         return (String) switch (t) {
127             case A -> "A";
128             default -> 1;
129         };
130     }
131 
132     private void check(T t, String expected) {
133         String result = print(t);
134         assertEquals(result, expected);
135     }
136 
137     private void assertEquals(Object result, Object expected) {
138         if (!Objects.equals(result, expected)) {
139             throw new AssertionError("Unexpected result: " + result);
140         }
141     }
142 
143     enum T {
144         A, B, C, D;
145     }
146     void t() {
147         Runnable r = () -> {};
148         r.run();
149     }
150 }
151