1 import jdk.incubator.code.CodeReflection;
2
3 /*
4 * @test
5 * @modules jdk.incubator.code
6 * @enablePreview
7 * @build SwitchExpressionTest2
8 * @build CodeReflectionTester
9 * @run main CodeReflectionTester SwitchExpressionTest2
10 */
11 public class SwitchExpressionTest2 {
12
13 @IR("""
14 func @"caseConstantRuleExpression" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
15 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
16 %2 : java.type:"java.lang.String" = var.load %1;
17 %3 : java.type:"java.lang.String" = java.switch.expression %2
18 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
19 %5 : java.type:"java.lang.String" = constant @"FOO";
20 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
21 yield %6;
22 }
23 ()java.type:"java.lang.String" -> {
24 %7 : java.type:"java.lang.String" = constant @"BAR";
25 yield %7;
26 }
27 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
28 %9 : java.type:"java.lang.String" = constant @"BAR";
29 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
30 yield %10;
31 }
32 ()java.type:"java.lang.String" -> {
33 %11 : java.type:"java.lang.String" = constant @"BAZ";
34 yield %11;
35 }
36 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
37 %13 : java.type:"java.lang.String" = constant @"BAZ";
38 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
39 yield %14;
40 }
41 ()java.type:"java.lang.String" -> {
42 %15 : java.type:"java.lang.String" = constant @"FOO";
43 yield %15;
44 }
45 ()java.type:"boolean" -> {
46 %16 : java.type:"boolean" = constant @true;
47 yield %16;
48 }
49 ()java.type:"java.lang.String" -> {
50 %17 : java.type:"java.lang.String" = constant @"";
51 yield %17;
52 };
53 return %3;
54 };
55 """)
56 @CodeReflection
57 public static String caseConstantRuleExpression(String r) {
58 return switch (r) {
59 case "FOO" -> "BAR";
60 case "BAR" -> "BAZ";
61 case "BAZ" -> "FOO";
62 default -> "";
63 };
64 }
65
66 @IR("""
67 func @"caseConstantRuleBlock" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
68 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
69 %2 : java.type:"java.lang.String" = var.load %1;
70 %3 : java.type:"java.lang.String" = java.switch.expression %2
71 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
72 %5 : java.type:"java.lang.String" = constant @"FOO";
73 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
74 yield %6;
75 }
76 ()java.type:"java.lang.String" -> {
77 %7 : java.type:"java.lang.String" = constant @"BAR";
78 java.yield %7;
79 }
80 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
81 %9 : java.type:"java.lang.String" = constant @"BAR";
82 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
83 yield %10;
84 }
85 ()java.type:"java.lang.String" -> {
86 %11 : java.type:"java.lang.String" = constant @"BAZ";
87 java.yield %11;
88 }
89 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
90 %13 : java.type:"java.lang.String" = constant @"BAZ";
91 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
92 yield %14;
93 }
94 ()java.type:"java.lang.String" -> {
95 %15 : java.type:"java.lang.String" = constant @"FOO";
96 java.yield %15;
97 }
98 ()java.type:"boolean" -> {
99 %16 : java.type:"boolean" = constant @true;
100 yield %16;
101 }
102 ()java.type:"java.lang.String" -> {
103 %17 : java.type:"java.lang.String" = constant @"";
104 java.yield %17;
105 };
106 return %3;
107 };
108 """)
109 @CodeReflection
110 public static String caseConstantRuleBlock(String r) {
111 return switch (r) {
112 case "FOO" -> {
113 yield "BAR";
114 }
115 case "BAR" -> {
116 yield "BAZ";
117 }
118 case "BAZ" -> {
119 yield "FOO";
120 }
121 default -> {
122 yield "";
123 }
124 };
125 }
126
127 @IR("""
128 func @"caseConstantStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
129 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
130 %2 : java.type:"java.lang.String" = var.load %1;
131 %3 : java.type:"java.lang.String" = java.switch.expression %2
132 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
133 %5 : java.type:"java.lang.String" = constant @"FOO";
134 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
135 yield %6;
136 }
137 ()java.type:"java.lang.String" -> {
138 %7 : java.type:"java.lang.String" = constant @"BAR";
139 java.yield %7;
140 }
141 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
142 %9 : java.type:"java.lang.String" = constant @"BAR";
143 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
144 yield %10;
145 }
146 ()java.type:"java.lang.String" -> {
147 %11 : java.type:"java.lang.String" = constant @"BAZ";
148 java.yield %11;
149 }
150 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
151 %13 : java.type:"java.lang.String" = constant @"BAZ";
152 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
153 yield %14;
154 }
155 ()java.type:"java.lang.String" -> {
156 %15 : java.type:"java.lang.String" = constant @"FOO";
157 java.yield %15;
158 }
159 ()java.type:"boolean" -> {
160 %16 : java.type:"boolean" = constant @true;
161 yield %16;
162 }
163 ()java.type:"java.lang.String" -> {
164 %17 : java.type:"java.lang.String" = constant @"";
165 java.yield %17;
166 };
167 return %3;
168 };
169 """)
170 @CodeReflection
171 private static String caseConstantStatement(String s) {
172 return switch (s) {
173 case "FOO": yield "BAR";
174 case "BAR": yield "BAZ";
175 case "BAZ": yield "FOO";
176 default: yield "";
177 };
178 }
179
180 @IR("""
181 func @"caseConstantMultiLabels" (%0 : java.type:"char")java.type:"java.lang.String" -> {
182 %1 : Var<java.type:"char"> = var %0 @"c";
183 %2 : java.type:"char" = var.load %1;
184 %3 : java.type:"char" = invoke %2 @java.ref:"java.lang.Character::toLowerCase(char):char";
185 %4 : java.type:"java.lang.String" = java.switch.expression %3
186 (%5 : java.type:"char")java.type:"boolean" -> {
187 %6 : java.type:"boolean" = java.cor
188 ()java.type:"boolean" -> {
189 %7 : java.type:"char" = constant @'a';
190 %8 : java.type:"boolean" = eq %5 %7;
191 yield %8;
192 }
193 ()java.type:"boolean" -> {
194 %9 : java.type:"char" = constant @'e';
195 %10 : java.type:"boolean" = eq %5 %9;
196 yield %10;
197 }
198 ()java.type:"boolean" -> {
199 %11 : java.type:"char" = constant @'i';
200 %12 : java.type:"boolean" = eq %5 %11;
201 yield %12;
202 }
203 ()java.type:"boolean" -> {
204 %13 : java.type:"char" = constant @'o';
205 %14 : java.type:"boolean" = eq %5 %13;
206 yield %14;
207 }
208 ()java.type:"boolean" -> {
209 %15 : java.type:"char" = constant @'u';
210 %16 : java.type:"boolean" = eq %5 %15;
211 yield %16;
212 };
213 yield %6;
214 }
215 ()java.type:"java.lang.String" -> {
216 %17 : java.type:"java.lang.String" = constant @"vowel";
217 java.yield %17;
218 }
219 ()java.type:"boolean" -> {
220 %18 : java.type:"boolean" = constant @true;
221 yield %18;
222 }
223 ()java.type:"java.lang.String" -> {
224 %19 : java.type:"java.lang.String" = constant @"consonant";
225 java.yield %19;
226 };
227 return %4;
228 };
229 """)
230 @CodeReflection
231 private static String caseConstantMultiLabels(char c) {
232 return switch (Character.toLowerCase(c)) {
233 case 'a', 'e', 'i', 'o', 'u': yield "vowel";
234 default: yield "consonant";
235 };
236 }
237
238 @IR("""
239 func @"caseConstantThrow" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
240 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
241 %2 : java.type:"java.lang.Integer" = var.load %1;
242 %3 : java.type:"java.lang.String" = java.switch.expression %2
243 (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
244 %5 : java.type:"int" = constant @8;
245 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
246 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
247 yield %7;
248 }
249 ()java.type:"java.lang.String" -> {
250 %8 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
251 throw %8;
252 }
253 (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
254 %10 : java.type:"int" = constant @9;
255 %11 : java.type:"java.lang.Integer" = invoke %10 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
256 %12 : java.type:"boolean" = invoke %9 %11 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
257 yield %12;
258 }
259 ()java.type:"java.lang.String" -> {
260 %13 : java.type:"java.lang.String" = constant @"NINE";
261 yield %13;
262 }
263 ()java.type:"boolean" -> {
264 %14 : java.type:"boolean" = constant @true;
265 yield %14;
266 }
267 ()java.type:"java.lang.String" -> {
268 %15 : java.type:"java.lang.String" = constant @"An integer";
269 yield %15;
270 };
271 return %3;
272 };
273 """)
274 @CodeReflection
275 private static String caseConstantThrow(Integer i) {
276 return switch (i) {
277 case 8 -> throw new IllegalArgumentException();
278 case 9 -> "NINE";
279 default -> "An integer";
280 };
281 }
282
283 @IR("""
284 func @"caseConstantNullLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
285 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
286 %2 : java.type:"java.lang.String" = var.load %1;
287 %3 : java.type:"java.lang.String" = java.switch.expression %2
288 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
289 %5 : java.type:"java.lang.Object" = constant @null;
290 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
291 yield %6;
292 }
293 ()java.type:"java.lang.String" -> {
294 %7 : java.type:"java.lang.String" = constant @"null";
295 yield %7;
296 }
297 ()java.type:"boolean" -> {
298 %8 : java.type:"boolean" = constant @true;
299 yield %8;
300 }
301 ()java.type:"java.lang.String" -> {
302 %9 : java.type:"java.lang.String" = constant @"non null";
303 yield %9;
304 };
305 return %3;
306 };
307 """)
308 @CodeReflection
309 private static String caseConstantNullLabel(String s) {
310 return switch (s) {
311 case null -> "null";
312 default -> "non null";
313 };
314 }
315
316 // @CodeReflection
317 // compiler code doesn't support case null, default
318 // @@@ support such as case and test the switch expression lowering for this case
319 private static String caseConstantNullAndDefault(String s) {
320 return switch (s) {
321 case "abc" -> "alphabet";
322 case null, default -> "null or default";
323 };
324 }
325
326 @IR("""
327 func @"caseConstantFallThrough" (%0 : java.type:"char")java.type:"java.lang.String" -> {
328 %1 : Var<java.type:"char"> = var %0 @"c";
329 %2 : java.type:"char" = var.load %1;
330 %3 : java.type:"java.lang.String" = java.switch.expression %2
331 (%4 : java.type:"char")java.type:"boolean" -> {
332 %5 : java.type:"char" = constant @'A';
333 %6 : java.type:"boolean" = eq %4 %5;
334 yield %6;
335 }
336 ()java.type:"java.lang.String" -> {
337 java.switch.fallthrough;
338 }
339 (%7 : java.type:"char")java.type:"boolean" -> {
340 %8 : java.type:"char" = constant @'B';
341 %9 : java.type:"boolean" = eq %7 %8;
342 yield %9;
343 }
344 ()java.type:"java.lang.String" -> {
345 %10 : java.type:"java.lang.String" = constant @"A or B";
346 java.yield %10;
347 }
348 ()java.type:"boolean" -> {
349 %11 : java.type:"boolean" = constant @true;
350 yield %11;
351 }
352 ()java.type:"java.lang.String" -> {
353 %12 : java.type:"java.lang.String" = constant @"Neither A nor B";
354 java.yield %12;
355 };
356 return %3;
357 };
358 """)
359 @CodeReflection
360 private static String caseConstantFallThrough(char c) {
361 return switch (c) {
362 case 'A':
363 case 'B':
364 yield "A or B";
365 default:
366 yield "Neither A nor B";
367 };
368 }
369
370 enum Day {
371 MON, TUE, WED, THU, FRI, SAT, SUN
372 }
373 @IR("""
374 func @"caseConstantEnum" (%0 : java.type:"SwitchExpressionTest2$Day")java.type:"int" -> {
375 %1 : Var<java.type:"SwitchExpressionTest2$Day"> = var %0 @"d";
376 %2 : java.type:"SwitchExpressionTest2$Day" = var.load %1;
377 %3 : java.type:"int" = java.switch.expression %2
378 (%4 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
379 %5 : java.type:"boolean" = java.cor
380 ()java.type:"boolean" -> {
381 %6 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::MON:SwitchExpressionTest2$Day";
382 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
383 yield %7;
384 }
385 ()java.type:"boolean" -> {
386 %8 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::FRI:SwitchExpressionTest2$Day";
387 %9 : java.type:"boolean" = invoke %4 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
388 yield %9;
389 }
390 ()java.type:"boolean" -> {
391 %10 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SUN:SwitchExpressionTest2$Day";
392 %11 : java.type:"boolean" = invoke %4 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
393 yield %11;
394 };
395 yield %5;
396 }
397 ()java.type:"int" -> {
398 %12 : java.type:"int" = constant @6;
399 yield %12;
400 }
401 (%13 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
402 %14 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::TUE:SwitchExpressionTest2$Day";
403 %15 : java.type:"boolean" = invoke %13 %14 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
404 yield %15;
405 }
406 ()java.type:"int" -> {
407 %16 : java.type:"int" = constant @7;
408 yield %16;
409 }
410 (%17 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
411 %18 : java.type:"boolean" = java.cor
412 ()java.type:"boolean" -> {
413 %19 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::THU:SwitchExpressionTest2$Day";
414 %20 : java.type:"boolean" = invoke %17 %19 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
415 yield %20;
416 }
417 ()java.type:"boolean" -> {
418 %21 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SAT:SwitchExpressionTest2$Day";
419 %22 : java.type:"boolean" = invoke %17 %21 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
420 yield %22;
421 };
422 yield %18;
423 }
424 ()java.type:"int" -> {
425 %23 : java.type:"int" = constant @8;
426 yield %23;
427 }
428 (%24 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
429 %25 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::WED:SwitchExpressionTest2$Day";
430 %26 : java.type:"boolean" = invoke %24 %25 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
431 yield %26;
432 }
433 ()java.type:"int" -> {
434 %27 : java.type:"int" = constant @9;
435 yield %27;
436 }
437 ()java.type:"boolean" -> {
438 %28 : java.type:"boolean" = constant @true;
439 yield %28;
440 }
441 ()java.type:"int" -> {
442 %29 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
443 throw %29;
444 };
445 return %3;
446 };
447 """)
448 @CodeReflection
449 private static int caseConstantEnum(Day d) {
450 return switch (d) {
451 case MON, FRI, SUN -> 6;
452 case TUE -> 7;
453 case THU, SAT -> 8;
454 case WED -> 9;
455 };
456 }
457
458 static class Constants {
459 static final int c1 = 12;
460 }
461 @IR("""
462 func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
463 %1 : Var<java.type:"int"> = var %0 @"i";
464 %2 : java.type:"int" = constant @11;
465 %3 : Var<java.type:"int"> = var %2 @"eleven";
466 %4 : java.type:"int" = var.load %1;
467 %5 : java.type:"java.lang.String" = java.switch.expression %4
468 (%6 : java.type:"int")java.type:"boolean" -> {
469 %7 : java.type:"int" = constant @1;
470 %8 : java.type:"int" = constant @15;
471 %9 : java.type:"int" = and %7 %8;
472 %10 : java.type:"boolean" = eq %6 %9;
473 yield %10;
474 }
475 ()java.type:"java.lang.String" -> {
476 %11 : java.type:"java.lang.String" = constant @"1";
477 yield %11;
478 }
479 (%12 : java.type:"int")java.type:"boolean" -> {
480 %13 : java.type:"int" = constant @4;
481 %14 : java.type:"int" = constant @1;
482 %15 : java.type:"int" = ashr %13 %14;
483 %16 : java.type:"boolean" = eq %12 %15;
484 yield %16;
485 }
486 ()java.type:"java.lang.String" -> {
487 %17 : java.type:"java.lang.String" = constant @"2";
488 yield %17;
489 }
490 (%18 : java.type:"int")java.type:"boolean" -> {
491 %19 : java.type:"long" = constant @3;
492 %20 : java.type:"int" = conv %19;
493 %21 : java.type:"boolean" = eq %18 %20;
494 yield %21;
495 }
496 ()java.type:"java.lang.String" -> {
497 %22 : java.type:"java.lang.String" = constant @"3";
498 yield %22;
499 }
500 (%23 : java.type:"int")java.type:"boolean" -> {
501 %24 : java.type:"int" = constant @2;
502 %25 : java.type:"int" = constant @1;
503 %26 : java.type:"int" = lshl %24 %25;
504 %27 : java.type:"boolean" = eq %23 %26;
505 yield %27;
506 }
507 ()java.type:"java.lang.String" -> {
508 %28 : java.type:"java.lang.String" = constant @"4";
509 yield %28;
510 }
511 (%29 : java.type:"int")java.type:"boolean" -> {
512 %30 : java.type:"int" = constant @10;
513 %31 : java.type:"int" = constant @2;
514 %32 : java.type:"int" = div %30 %31;
515 %33 : java.type:"boolean" = eq %29 %32;
516 yield %33;
517 }
518 ()java.type:"java.lang.String" -> {
519 %34 : java.type:"java.lang.String" = constant @"5";
520 yield %34;
521 }
522 (%35 : java.type:"int")java.type:"boolean" -> {
523 %36 : java.type:"int" = constant @12;
524 %37 : java.type:"int" = constant @6;
525 %38 : java.type:"int" = sub %36 %37;
526 %39 : java.type:"boolean" = eq %35 %38;
527 yield %39;
528 }
529 ()java.type:"java.lang.String" -> {
530 %40 : java.type:"java.lang.String" = constant @"6";
531 yield %40;
532 }
533 (%41 : java.type:"int")java.type:"boolean" -> {
534 %42 : java.type:"int" = constant @3;
535 %43 : java.type:"int" = constant @4;
536 %44 : java.type:"int" = add %42 %43;
537 %45 : java.type:"boolean" = eq %41 %44;
538 yield %45;
539 }
540 ()java.type:"java.lang.String" -> {
541 %46 : java.type:"java.lang.String" = constant @"7";
542 yield %46;
543 }
544 (%47 : java.type:"int")java.type:"boolean" -> {
545 %48 : java.type:"int" = constant @2;
546 %49 : java.type:"int" = constant @2;
547 %50 : java.type:"int" = mul %48 %49;
548 %51 : java.type:"int" = constant @2;
549 %52 : java.type:"int" = mul %50 %51;
550 %53 : java.type:"boolean" = eq %47 %52;
551 yield %53;
552 }
553 ()java.type:"java.lang.String" -> {
554 %54 : java.type:"java.lang.String" = constant @"8";
555 yield %54;
556 }
557 (%55 : java.type:"int")java.type:"boolean" -> {
558 %56 : java.type:"int" = constant @8;
559 %57 : java.type:"int" = constant @1;
560 %58 : java.type:"int" = or %56 %57;
561 %59 : java.type:"boolean" = eq %55 %58;
562 yield %59;
563 }
564 ()java.type:"java.lang.String" -> {
565 %60 : java.type:"java.lang.String" = constant @"9";
566 yield %60;
567 }
568 (%61 : java.type:"int")java.type:"boolean" -> {
569 %62 : java.type:"int" = constant @10;
570 %63 : java.type:"boolean" = eq %61 %62;
571 yield %63;
572 }
573 ()java.type:"java.lang.String" -> {
574 %64 : java.type:"java.lang.String" = constant @"10";
575 yield %64;
576 }
577 (%65 : java.type:"int")java.type:"boolean" -> {
578 %66 : java.type:"int" = var.load %3;
579 %67 : java.type:"boolean" = eq %65 %66;
580 yield %67;
581 }
582 ()java.type:"java.lang.String" -> {
583 %68 : java.type:"java.lang.String" = constant @"11";
584 yield %68;
585 }
586 (%69 : java.type:"int")java.type:"boolean" -> {
587 %70 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
588 %71 : java.type:"boolean" = eq %69 %70;
589 yield %71;
590 }
591 ()java.type:"java.lang.String" -> {
592 %72 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
593 %73 : java.type:"java.lang.String" = invoke %72 @java.ref:"java.lang.String::valueOf(int):java.lang.String";
594 yield %73;
595 }
596 (%74 : java.type:"int")java.type:"boolean" -> {
597 %75 : java.type:"int" = java.cexpression
598 ()java.type:"boolean" -> {
599 %76 : java.type:"int" = constant @1;
600 %77 : java.type:"int" = constant @0;
601 %78 : java.type:"boolean" = gt %76 %77;
602 yield %78;
603 }
604 ()java.type:"int" -> {
605 %79 : java.type:"int" = constant @13;
606 yield %79;
607 }
608 ()java.type:"int" -> {
609 %80 : java.type:"int" = constant @133;
610 yield %80;
611 };
612 %81 : java.type:"boolean" = eq %74 %75;
613 yield %81;
614 }
615 ()java.type:"java.lang.String" -> {
616 %82 : java.type:"java.lang.String" = constant @"13";
617 yield %82;
618 }
619 ()java.type:"boolean" -> {
620 %83 : java.type:"boolean" = constant @true;
621 yield %83;
622 }
623 ()java.type:"java.lang.String" -> {
624 %84 : java.type:"java.lang.String" = constant @"an int";
625 yield %84;
626 };
627 return %5;
628 };
629 """)
630 @CodeReflection
631 private static String caseConstantOtherKindsOfExpr(int i) {
632 final int eleven = 11;
633 return switch (i) {
634 case 1 & 0xF -> "1";
635 case 4>>1 -> "2";
636 case (int) 3L -> "3";
637 case 2<<1 -> "4";
638 case 10 / 2 -> "5";
639 case 12 - 6 -> "6";
640 case 3 + 4 -> "7";
641 case 2 * 2 * 2 -> "8";
642 case 8 | 1 -> "9";
643 case (10) -> "10";
644 case eleven -> "11";
645 case Constants.c1 -> String.valueOf(Constants.c1);
646 case 1 > 0 ? 13 : 133 -> "13";
647 default -> "an int";
648 };
649 }
650
651 // these are the conversions that applies in switch
652
653 @IR("""
654 func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
655 %1 : Var<java.type:"short"> = var %0 @"a";
656 %2 : java.type:"int" = constant @1;
657 %3 : java.type:"short" = conv %2;
658 %4 : Var<java.type:"short"> = var %3 @"s";
659 %5 : java.type:"int" = constant @2;
660 %6 : java.type:"byte" = conv %5;
661 %7 : Var<java.type:"byte"> = var %6 @"b";
662 %8 : java.type:"short" = var.load %1;
663 %9 : java.type:"java.lang.String" = java.switch.expression %8
664 (%10 : java.type:"short")java.type:"boolean" -> {
665 %11 : java.type:"short" = var.load %4;
666 %12 : java.type:"boolean" = eq %10 %11;
667 yield %12;
668 }
669 ()java.type:"java.lang.String" -> {
670 %13 : java.type:"java.lang.String" = constant @"one";
671 yield %13;
672 }
673 (%14 : java.type:"short")java.type:"boolean" -> {
674 %15 : java.type:"byte" = var.load %7;
675 %16 : java.type:"short" = conv %15;
676 %17 : java.type:"boolean" = eq %14 %16;
677 yield %17;
678 }
679 ()java.type:"java.lang.String" -> {
680 %18 : java.type:"java.lang.String" = constant @"three";
681 yield %18;
682 }
683 (%19 : java.type:"short")java.type:"boolean" -> {
684 %20 : java.type:"int" = constant @3;
685 %21 : java.type:"short" = conv %20;
686 %22 : java.type:"boolean" = eq %19 %21;
687 yield %22;
688 }
689 ()java.type:"java.lang.String" -> {
690 %23 : java.type:"java.lang.String" = constant @"two";
691 yield %23;
692 }
693 ()java.type:"boolean" -> {
694 %24 : java.type:"boolean" = constant @true;
695 yield %24;
696 }
697 ()java.type:"java.lang.String" -> {
698 %25 : java.type:"java.lang.String" = constant @"default";
699 yield %25;
700 };
701 return %9;
702 };
703 """)
704 @CodeReflection
705 static String caseConstantConv(short a) {
706 final short s = 1;
707 final byte b = 2;
708 return switch (a) {
709 case s -> "one"; // identity
710 case b -> "three"; // widening primitive conversion
711 case 3 -> "two"; // narrowing primitive conversion
712 default -> "default";
713 };
714 }
715
716 @IR("""
717 func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
718 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
719 %2 : java.type:"int" = constant @2;
720 %3 : java.type:"byte" = conv %2;
721 %4 : Var<java.type:"byte"> = var %3 @"b";
722 %5 : java.type:"java.lang.Byte" = var.load %1;
723 %6 : java.type:"java.lang.String" = java.switch.expression %5
724 (%7 : java.type:"java.lang.Byte")java.type:"boolean" -> {
725 %8 : java.type:"int" = constant @1;
726 %9 : java.type:"byte" = conv %8;
727 %10 : java.type:"java.lang.Byte" = invoke %9 @java.ref:"java.lang.Byte::valueOf(byte):java.lang.Byte";
728 %11 : java.type:"boolean" = invoke %7 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
729 yield %11;
730 }
731 ()java.type:"java.lang.String" -> {
732 %12 : java.type:"java.lang.String" = constant @"one";
733 yield %12;
734 }
735 (%13 : java.type:"java.lang.Byte")java.type:"boolean" -> {
736 %14 : java.type:"byte" = var.load %4;
737 %15 : java.type:"java.lang.Byte" = invoke %14 @java.ref:"java.lang.Byte::valueOf(byte):java.lang.Byte";
738 %16 : java.type:"boolean" = invoke %13 %15 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
739 yield %16;
740 }
741 ()java.type:"java.lang.String" -> {
742 %17 : java.type:"java.lang.String" = constant @"two";
743 yield %17;
744 }
745 ()java.type:"boolean" -> {
746 %18 : java.type:"boolean" = constant @true;
747 yield %18;
748 }
749 ()java.type:"java.lang.String" -> {
750 %19 : java.type:"java.lang.String" = constant @"default";
751 yield %19;
752 };
753 return %6;
754 };
755 """)
756 @CodeReflection
757 static String caseConstantConv2(Byte a) {
758 final byte b = 2;
759 return switch (a) {
760 // narrowing conv is missing in the code model
761 case 1 -> "one"; // narrowing primitive conversion followed by a boxing conversion
762 case b -> "two"; // boxing
763 default -> "default";
764 };
765 }
766
767 enum E { F, G }
768 @IR("""
769 func @"noDefaultLabelEnum" (%0 : java.type:"SwitchExpressionTest2$E")java.type:"java.lang.String" -> {
770 %1 : Var<java.type:"SwitchExpressionTest2$E"> = var %0 @"e";
771 %2 : java.type:"SwitchExpressionTest2$E" = var.load %1;
772 %3 : java.type:"java.lang.String" = java.switch.expression %2
773 (%4 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
774 %5 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::F:SwitchExpressionTest2$E";
775 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
776 yield %6;
777 }
778 ()java.type:"java.lang.String" -> {
779 %7 : java.type:"java.lang.String" = constant @"f";
780 yield %7;
781 }
782 (%8 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
783 %9 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::G:SwitchExpressionTest2$E";
784 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
785 yield %10;
786 }
787 ()java.type:"java.lang.String" -> {
788 %11 : java.type:"java.lang.String" = constant @"g";
789 yield %11;
790 }
791 ()java.type:"boolean" -> {
792 %12 : java.type:"boolean" = constant @true;
793 yield %12;
794 }
795 ()java.type:"java.lang.String" -> {
796 %13 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
797 throw %13;
798 };
799 return %3;
800 };
801 """)
802 @CodeReflection
803 static String noDefaultLabelEnum(E e) {
804 return switch (e) {
805 case F -> "f";
806 case G -> "g";
807 };
808 }
809
810 @IR("""
811 func @"unconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
812 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
813 %2 : java.type:"java.lang.String" = var.load %1;
814 %3 : java.type:"java.lang.Object" = constant @null;
815 %4 : Var<java.type:"java.lang.Object"> = var %3 @"o";
816 %5 : java.type:"java.lang.String" = java.switch.expression %2
817 (%6 : java.type:"java.lang.String")java.type:"boolean" -> {
818 %7 : java.type:"java.lang.String" = constant @"A";
819 %8 : java.type:"boolean" = invoke %6 %7 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
820 yield %8;
821 }
822 ()java.type:"java.lang.String" -> {
823 %9 : java.type:"java.lang.String" = constant @"Alphabet";
824 yield %9;
825 }
826 (%10 : java.type:"java.lang.String")java.type:"boolean" -> {
827 %11 : java.type:"boolean" = pattern.match %10
828 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
829 %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
830 yield %12;
831 }
832 (%13 : java.type:"java.lang.Object")java.type:"void" -> {
833 var.store %4 %13;
834 yield;
835 };
836 yield %11;
837 }
838 ()java.type:"java.lang.String" -> {
839 %14 : java.type:"java.lang.String" = constant @"default";
840 yield %14;
841 };
842 return %5;
843 };
844 """)
845 @CodeReflection
846 static String unconditionalPattern(String s) {
847 return switch (s) {
848 case "A" -> "Alphabet";
849 case Object o -> "default";
850 };
851 }
852
853 sealed interface A permits B, C {}
854 record B() implements A {}
855 final class C implements A {}
856 @IR("""
857 func @"noDefault" (%0 : java.type:"SwitchExpressionTest2$A")java.type:"java.lang.String" -> {
858 %1 : Var<java.type:"SwitchExpressionTest2$A"> = var %0 @"a";
859 %2 : java.type:"SwitchExpressionTest2$A" = var.load %1;
860 %3 : java.type:"SwitchExpressionTest2$B" = constant @null;
861 %4 : Var<java.type:"SwitchExpressionTest2$B"> = var %3 @"b";
862 %5 : java.type:"SwitchExpressionTest2::C" = constant @null;
863 %6 : Var<java.type:"SwitchExpressionTest2::C"> = var %5 @"c";
864 %7 : java.type:"java.lang.String" = java.switch.expression %2
865 (%8 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
866 %9 : java.type:"boolean" = pattern.match %8
867 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" -> {
868 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" = pattern.type @"b";
869 yield %10;
870 }
871 (%11 : java.type:"SwitchExpressionTest2$B")java.type:"void" -> {
872 var.store %4 %11;
873 yield;
874 };
875 yield %9;
876 }
877 ()java.type:"java.lang.String" -> {
878 %12 : java.type:"java.lang.String" = constant @"B";
879 yield %12;
880 }
881 (%13 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
882 %14 : java.type:"boolean" = pattern.match %13
883 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" -> {
884 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" = pattern.type @"c";
885 yield %15;
886 }
887 (%16 : java.type:"SwitchExpressionTest2::C")java.type:"void" -> {
888 var.store %6 %16;
889 yield;
890 };
891 yield %14;
892 }
893 ()java.type:"java.lang.String" -> {
894 %17 : java.type:"java.lang.String" = constant @"C";
895 yield %17;
896 }
897 ()java.type:"boolean" -> {
898 %18 : java.type:"boolean" = constant @true;
899 yield %18;
900 }
901 ()java.type:"java.lang.String" -> {
902 %19 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
903 throw %19;
904 };
905 return %7;
906 };
907 """)
908 @CodeReflection
909 static String noDefault(A a) {
910 return switch (a) {
911 case B b -> "B";
912 case C c -> "C";
913 };
914 }
915
916 @IR("""
917 func @"defaultNotTheLastLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
918 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
919 %2 : java.type:"java.lang.String" = var.load %1;
920 %3 : java.type:"java.lang.String" = java.switch.expression %2
921 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
922 %5 : java.type:"java.lang.String" = constant @"M";
923 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
924 yield %6;
925 }
926 ()java.type:"java.lang.String" -> {
927 %7 : java.type:"java.lang.String" = constant @"Mow";
928 yield %7;
929 }
930 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
931 %9 : java.type:"java.lang.String" = constant @"A";
932 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
933 yield %10;
934 }
935 ()java.type:"java.lang.String" -> {
936 %11 : java.type:"java.lang.String" = constant @"Aow";
937 yield %11;
938 }
939 ()java.type:"boolean" -> {
940 %12 : java.type:"boolean" = constant @true;
941 yield %12;
942 }
943 ()java.type:"java.lang.String" -> {
944 %13 : java.type:"java.lang.String" = constant @"else";
945 yield %13;
946 };
947 return %3;
948 };
949 """)
950 @CodeReflection
951 static String defaultNotTheLastLabel(String s) {
952 return switch (s) {
953 default -> "else";
954 case "M" -> "Mow";
955 case "A" -> "Aow";
956 };
957 }
958 }