1 /*
2 * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import jdk.incubator.code.Reflect;
25
26 /*
27 * @test
28 * @modules jdk.incubator.code
29 * @enablePreview
30 * @build SwitchExpressionTest2
31 * @build CodeReflectionTester
32 * @run main CodeReflectionTester SwitchExpressionTest2
33 */
34 public class SwitchExpressionTest2 {
35
36 @IR("""
37 func @"caseConstantRuleExpression" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
38 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
39 %2 : java.type:"java.lang.String" = var.load %1;
40 %3 : java.type:"java.lang.String" = java.switch.expression %2
41 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
42 %5 : java.type:"java.lang.String" = constant @"FOO";
43 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
44 yield %6;
45 }
46 ()java.type:"java.lang.String" -> {
47 %7 : java.type:"java.lang.String" = constant @"BAR";
48 yield %7;
49 }
50 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
51 %9 : java.type:"java.lang.String" = constant @"BAR";
52 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
53 yield %10;
54 }
55 ()java.type:"java.lang.String" -> {
56 %11 : java.type:"java.lang.String" = constant @"BAZ";
57 yield %11;
58 }
59 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
60 %13 : java.type:"java.lang.String" = constant @"BAZ";
61 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
62 yield %14;
63 }
64 ()java.type:"java.lang.String" -> {
65 %15 : java.type:"java.lang.String" = constant @"FOO";
66 yield %15;
67 }
68 ()java.type:"boolean" -> {
69 %16 : java.type:"boolean" = constant @true;
70 yield %16;
71 }
72 ()java.type:"java.lang.String" -> {
73 %17 : java.type:"java.lang.String" = constant @"";
74 yield %17;
75 };
76 return %3;
77 };
78 """)
79 @Reflect
80 public static String caseConstantRuleExpression(String r) {
81 return switch (r) {
82 case "FOO" -> "BAR";
83 case "BAR" -> "BAZ";
84 case "BAZ" -> "FOO";
85 default -> "";
86 };
87 }
88
89 @IR("""
90 func @"caseConstantRuleBlock" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
91 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
92 %2 : java.type:"java.lang.String" = var.load %1;
93 %3 : java.type:"java.lang.String" = java.switch.expression %2
94 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
95 %5 : java.type:"java.lang.String" = constant @"FOO";
96 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
97 yield %6;
98 }
99 ()java.type:"java.lang.String" -> {
100 %7 : java.type:"java.lang.String" = constant @"BAR";
101 java.yield %7;
102 }
103 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
104 %9 : java.type:"java.lang.String" = constant @"BAR";
105 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
106 yield %10;
107 }
108 ()java.type:"java.lang.String" -> {
109 %11 : java.type:"java.lang.String" = constant @"BAZ";
110 java.yield %11;
111 }
112 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
113 %13 : java.type:"java.lang.String" = constant @"BAZ";
114 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
115 yield %14;
116 }
117 ()java.type:"java.lang.String" -> {
118 %15 : java.type:"java.lang.String" = constant @"FOO";
119 java.yield %15;
120 }
121 ()java.type:"boolean" -> {
122 %16 : java.type:"boolean" = constant @true;
123 yield %16;
124 }
125 ()java.type:"java.lang.String" -> {
126 %17 : java.type:"java.lang.String" = constant @"";
127 java.yield %17;
128 };
129 return %3;
130 };
131 """)
132 @Reflect
133 public static String caseConstantRuleBlock(String r) {
134 return switch (r) {
135 case "FOO" -> {
136 yield "BAR";
137 }
138 case "BAR" -> {
139 yield "BAZ";
140 }
141 case "BAZ" -> {
142 yield "FOO";
143 }
144 default -> {
145 yield "";
146 }
147 };
148 }
149
150 @IR("""
151 func @"caseConstantStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
152 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
153 %2 : java.type:"java.lang.String" = var.load %1;
154 %3 : java.type:"java.lang.String" = java.switch.expression %2
155 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
156 %5 : java.type:"java.lang.String" = constant @"FOO";
157 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
158 yield %6;
159 }
160 ()java.type:"java.lang.String" -> {
161 %7 : java.type:"java.lang.String" = constant @"BAR";
162 java.yield %7;
163 }
164 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
165 %9 : java.type:"java.lang.String" = constant @"BAR";
166 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
167 yield %10;
168 }
169 ()java.type:"java.lang.String" -> {
170 %11 : java.type:"java.lang.String" = constant @"BAZ";
171 java.yield %11;
172 }
173 (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
174 %13 : java.type:"java.lang.String" = constant @"BAZ";
175 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
176 yield %14;
177 }
178 ()java.type:"java.lang.String" -> {
179 %15 : java.type:"java.lang.String" = constant @"FOO";
180 java.yield %15;
181 }
182 ()java.type:"boolean" -> {
183 %16 : java.type:"boolean" = constant @true;
184 yield %16;
185 }
186 ()java.type:"java.lang.String" -> {
187 %17 : java.type:"java.lang.String" = constant @"";
188 java.yield %17;
189 };
190 return %3;
191 };
192 """)
193 @Reflect
194 private static String caseConstantStatement(String s) {
195 return switch (s) {
196 case "FOO": yield "BAR";
197 case "BAR": yield "BAZ";
198 case "BAZ": yield "FOO";
199 default: yield "";
200 };
201 }
202
203 @IR("""
204 func @"caseConstantMultiLabels" (%0 : java.type:"char")java.type:"java.lang.String" -> {
205 %1 : Var<java.type:"char"> = var %0 @"c";
206 %2 : java.type:"char" = var.load %1;
207 %3 : java.type:"char" = invoke %2 @java.ref:"java.lang.Character::toLowerCase(char):char";
208 %4 : java.type:"java.lang.String" = java.switch.expression %3
209 (%5 : java.type:"char")java.type:"boolean" -> {
210 %6 : java.type:"boolean" = java.cor
211 ()java.type:"boolean" -> {
212 %7 : java.type:"char" = constant @'a';
213 %8 : java.type:"boolean" = eq %5 %7;
214 yield %8;
215 }
216 ()java.type:"boolean" -> {
217 %9 : java.type:"char" = constant @'e';
218 %10 : java.type:"boolean" = eq %5 %9;
219 yield %10;
220 }
221 ()java.type:"boolean" -> {
222 %11 : java.type:"char" = constant @'i';
223 %12 : java.type:"boolean" = eq %5 %11;
224 yield %12;
225 }
226 ()java.type:"boolean" -> {
227 %13 : java.type:"char" = constant @'o';
228 %14 : java.type:"boolean" = eq %5 %13;
229 yield %14;
230 }
231 ()java.type:"boolean" -> {
232 %15 : java.type:"char" = constant @'u';
233 %16 : java.type:"boolean" = eq %5 %15;
234 yield %16;
235 };
236 yield %6;
237 }
238 ()java.type:"java.lang.String" -> {
239 %17 : java.type:"java.lang.String" = constant @"vowel";
240 java.yield %17;
241 }
242 ()java.type:"boolean" -> {
243 %18 : java.type:"boolean" = constant @true;
244 yield %18;
245 }
246 ()java.type:"java.lang.String" -> {
247 %19 : java.type:"java.lang.String" = constant @"consonant";
248 java.yield %19;
249 };
250 return %4;
251 };
252 """)
253 @Reflect
254 private static String caseConstantMultiLabels(char c) {
255 return switch (Character.toLowerCase(c)) {
256 case 'a', 'e', 'i', 'o', 'u': yield "vowel";
257 default: yield "consonant";
258 };
259 }
260
261 @IR("""
262 func @"casePatternMultiLabel" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
263 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
264 %2 : java.type:"java.lang.Object" = var.load %1;
265 %3 : java.type:"java.lang.Integer" = constant @null;
266 %4 : Var<java.type:"java.lang.Integer"> = var %3;
267 %5 : java.type:"java.lang.Long" = constant @null;
268 %6 : Var<java.type:"java.lang.Long"> = var %5;
269 %7 : java.type:"java.lang.Character" = constant @null;
270 %8 : Var<java.type:"java.lang.Character"> = var %7;
271 %9 : java.type:"java.lang.Byte" = constant @null;
272 %10 : Var<java.type:"java.lang.Byte"> = var %9;
273 %11 : java.type:"java.lang.Short" = constant @null;
274 %12 : Var<java.type:"java.lang.Short"> = var %11;
275 %13 : java.type:"java.lang.String" = java.switch.expression %2
276 (%14 : java.type:"java.lang.Object")java.type:"boolean" -> {
277 %15 : java.type:"boolean" = java.cor
278 ()java.type:"boolean" -> {
279 %16 : java.type:"boolean" = pattern.match %14
280 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
281 %17 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
282 yield %17;
283 }
284 (%18 : java.type:"java.lang.Integer")java.type:"void" -> {
285 var.store %4 %18;
286 yield;
287 };
288 yield %16;
289 }
290 ()java.type:"boolean" -> {
291 %19 : java.type:"boolean" = pattern.match %14
292 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" -> {
293 %20 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" = pattern.type;
294 yield %20;
295 }
296 (%21 : java.type:"java.lang.Long")java.type:"void" -> {
297 var.store %6 %21;
298 yield;
299 };
300 yield %19;
301 }
302 ()java.type:"boolean" -> {
303 %22 : java.type:"boolean" = pattern.match %14
304 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Character>" -> {
305 %23 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Character>" = pattern.type;
306 yield %23;
307 }
308 (%24 : java.type:"java.lang.Character")java.type:"void" -> {
309 var.store %8 %24;
310 yield;
311 };
312 yield %22;
313 }
314 ()java.type:"boolean" -> {
315 %25 : java.type:"boolean" = pattern.match %14
316 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" -> {
317 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" = pattern.type;
318 yield %26;
319 }
320 (%27 : java.type:"java.lang.Byte")java.type:"void" -> {
321 var.store %10 %27;
322 yield;
323 };
324 yield %25;
325 }
326 ()java.type:"boolean" -> {
327 %28 : java.type:"boolean" = pattern.match %14
328 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" -> {
329 %29 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" = pattern.type;
330 yield %29;
331 }
332 (%30 : java.type:"java.lang.Short")java.type:"void" -> {
333 var.store %12 %30;
334 yield;
335 };
336 yield %28;
337 };
338 yield %15;
339 }
340 ()java.type:"java.lang.String" -> {
341 %31 : java.type:"java.lang.String" = constant @"integral type";
342 yield %31;
343 }
344 ()java.type:"boolean" -> {
345 %32 : java.type:"boolean" = constant @true;
346 yield %32;
347 }
348 ()java.type:"java.lang.String" -> {
349 %33 : java.type:"java.lang.String" = constant @"non integral type";
350 yield %33;
351 };
352 return %13;
353 };
354 """)
355 @Reflect
356 private static String casePatternMultiLabel(Object o) {
357 return switch (o) {
358 case Integer _, Long _, Character _, Byte _, Short _-> "integral type";
359 default -> "non integral type";
360 };
361 }
362
363 @IR("""
364 func @"casePatternGuardedMultiLabel" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
365 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
366 %2 : java.type:"java.lang.Object" = var.load %1;
367 %3 : java.type:"java.lang.Integer" = constant @null;
368 %4 : Var<java.type:"java.lang.Integer"> = var %3;
369 %5 : java.type:"java.lang.Long" = constant @null;
370 %6 : Var<java.type:"java.lang.Long"> = var %5;
371 %7 : java.type:"java.lang.Byte" = constant @null;
372 %8 : Var<java.type:"java.lang.Byte"> = var %7;
373 %9 : java.type:"java.lang.Short" = constant @null;
374 %10 : Var<java.type:"java.lang.Short"> = var %9;
375 %11 : java.type:"java.lang.String" = java.switch.expression %2
376 (%12 : java.type:"java.lang.Object")java.type:"boolean" -> {
377 %13 : java.type:"boolean" = java.cand
378 ()java.type:"boolean" -> {
379 %14 : java.type:"boolean" = java.cor
380 ()java.type:"boolean" -> {
381 %15 : java.type:"boolean" = pattern.match %12
382 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
383 %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
384 yield %16;
385 }
386 (%17 : java.type:"java.lang.Integer")java.type:"void" -> {
387 var.store %4 %17;
388 yield;
389 };
390 yield %15;
391 }
392 ()java.type:"boolean" -> {
393 %18 : java.type:"boolean" = pattern.match %12
394 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" -> {
395 %19 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" = pattern.type;
396 yield %19;
397 }
398 (%20 : java.type:"java.lang.Long")java.type:"void" -> {
399 var.store %6 %20;
400 yield;
401 };
402 yield %18;
403 }
404 ()java.type:"boolean" -> {
405 %21 : java.type:"boolean" = pattern.match %12
406 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" -> {
407 %22 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" = pattern.type;
408 yield %22;
409 }
410 (%23 : java.type:"java.lang.Byte")java.type:"void" -> {
411 var.store %8 %23;
412 yield;
413 };
414 yield %21;
415 }
416 ()java.type:"boolean" -> {
417 %24 : java.type:"boolean" = pattern.match %12
418 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" -> {
419 %25 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" = pattern.type;
420 yield %25;
421 }
422 (%26 : java.type:"java.lang.Short")java.type:"void" -> {
423 var.store %10 %26;
424 yield;
425 };
426 yield %24;
427 };
428 yield %14;
429 }
430 ()java.type:"boolean" -> {
431 %27 : java.type:"java.lang.Object" = var.load %1;
432 %28 : java.type:"java.lang.Number" = cast %27 @java.type:"java.lang.Number";
433 %29 : java.type:"int" = invoke %28 @java.ref:"java.lang.Number::intValue():int";
434 %30 : java.type:"int" = constant @0;
435 %31 : java.type:"boolean" = gt %29 %30;
436 yield %31;
437 };
438 yield %13;
439 }
440 ()java.type:"java.lang.String" -> {
441 %32 : java.type:"java.lang.String" = constant @"integral type";
442 yield %32;
443 }
444 ()java.type:"boolean" -> {
445 %33 : java.type:"boolean" = constant @true;
446 yield %33;
447 }
448 ()java.type:"java.lang.String" -> {
449 %34 : java.type:"java.lang.String" = constant @"non integral type";
450 yield %34;
451 };
452 return %11;
453 };
454 """)
455 @Reflect
456 private static String casePatternGuardedMultiLabel(Object o) {
457 return switch (o) {
458 case Integer _, Long _, Byte _, Short _ when ((Number)o).intValue() > 0 -> "integral type";
459 default -> "non integral type";
460 };
461 }
462
463 @IR("""
464 func @"caseConstantThrow" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
465 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
466 %2 : java.type:"java.lang.Integer" = var.load %1;
467 %3 : java.type:"java.lang.String" = java.switch.expression %2
468 (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
469 %5 : java.type:"int" = invoke %4 @java.ref:"java.lang.Integer::intValue():int";
470 %6 : java.type:"int" = constant @8;
471 %7 : java.type:"boolean" = eq %5 %6;
472 yield %7;
473 }
474 ()java.type:"java.lang.String" -> {
475 %8 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
476 throw %8;
477 }
478 (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
479 %10 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
480 %11 : java.type:"int" = constant @9;
481 %12 : java.type:"boolean" = eq %10 %11;
482 yield %12;
483 }
484 ()java.type:"java.lang.String" -> {
485 %13 : java.type:"java.lang.String" = constant @"NINE";
486 yield %13;
487 }
488 ()java.type:"boolean" -> {
489 %14 : java.type:"boolean" = constant @true;
490 yield %14;
491 }
492 ()java.type:"java.lang.String" -> {
493 %15 : java.type:"java.lang.String" = constant @"An integer";
494 yield %15;
495 };
496 return %3;
497 };
498 """)
499 @Reflect
500 private static String caseConstantThrow(Integer i) {
501 return switch (i) {
502 case 8 -> throw new IllegalArgumentException();
503 case 9 -> "NINE";
504 default -> "An integer";
505 };
506 }
507
508 @IR("""
509 func @"caseConstantNullLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
510 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
511 %2 : java.type:"java.lang.String" = var.load %1;
512 %3 : java.type:"java.lang.String" = java.switch.expression %2 @switch.handle.nulls=true
513 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
514 %5 : java.type:"java.lang.Object" = constant @null;
515 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
516 yield %6;
517 }
518 ()java.type:"java.lang.String" -> {
519 %7 : java.type:"java.lang.String" = constant @"null";
520 yield %7;
521 }
522 ()java.type:"boolean" -> {
523 %8 : java.type:"boolean" = constant @true;
524 yield %8;
525 }
526 ()java.type:"java.lang.String" -> {
527 %9 : java.type:"java.lang.String" = constant @"non null";
528 yield %9;
529 };
530 return %3;
531 };
532 """)
533 @Reflect
534 private static String caseConstantNullLabel(String s) {
535 return switch (s) {
536 case null -> "null";
537 default -> "non null";
538 };
539 }
540
541 @IR("""
542 func @"caseConstantNullAndDefault" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
543 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
544 %2 : java.type:"java.lang.String" = var.load %1;
545 %3 : java.type:"java.lang.String" = java.switch.expression %2 @switch.handle.nulls=true
546 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
547 %5 : java.type:"java.lang.String" = constant @"abc";
548 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
549 yield %6;
550 }
551 ()java.type:"java.lang.String" -> {
552 %7 : java.type:"java.lang.String" = constant @"alphabet";
553 yield %7;
554 }
555 ()java.type:"boolean" -> {
556 %8 : java.type:"boolean" = constant @true;
557 yield %8;
558 }
559 ()java.type:"java.lang.String" -> {
560 %9 : java.type:"java.lang.String" = constant @"null or default";
561 yield %9;
562 };
563 return %3;
564 };
565 """)
566 @Reflect
567 private static String caseConstantNullAndDefault(String s) {
568 return switch (s) {
569 case "abc" -> "alphabet";
570 case null, default -> "null or default";
571 };
572 }
573
574 @IR("""
575 func @"caseConstantFallThrough" (%0 : java.type:"char")java.type:"java.lang.String" -> {
576 %1 : Var<java.type:"char"> = var %0 @"c";
577 %2 : java.type:"char" = var.load %1;
578 %3 : java.type:"java.lang.String" = java.switch.expression %2
579 (%4 : java.type:"char")java.type:"boolean" -> {
580 %5 : java.type:"char" = constant @'A';
581 %6 : java.type:"boolean" = eq %4 %5;
582 yield %6;
583 }
584 ()java.type:"java.lang.String" -> {
585 java.switch.fallthrough;
586 }
587 (%7 : java.type:"char")java.type:"boolean" -> {
588 %8 : java.type:"char" = constant @'B';
589 %9 : java.type:"boolean" = eq %7 %8;
590 yield %9;
591 }
592 ()java.type:"java.lang.String" -> {
593 %10 : java.type:"java.lang.String" = constant @"A or B";
594 java.yield %10;
595 }
596 ()java.type:"boolean" -> {
597 %11 : java.type:"boolean" = constant @true;
598 yield %11;
599 }
600 ()java.type:"java.lang.String" -> {
601 %12 : java.type:"java.lang.String" = constant @"Neither A nor B";
602 java.yield %12;
603 };
604 return %3;
605 };
606 """)
607 @Reflect
608 private static String caseConstantFallThrough(char c) {
609 return switch (c) {
610 case 'A':
611 case 'B':
612 yield "A or B";
613 default:
614 yield "Neither A nor B";
615 };
616 }
617
618 enum Day {
619 MON, TUE, WED, THU, FRI, SAT, SUN
620 }
621 @IR("""
622 func @"caseConstantEnum" (%0 : java.type:"SwitchExpressionTest2$Day")java.type:"int" -> {
623 %1 : Var<java.type:"SwitchExpressionTest2$Day"> = var %0 @"d";
624 %2 : java.type:"SwitchExpressionTest2$Day" = var.load %1;
625 %3 : java.type:"int" = java.switch.expression %2
626 (%4 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
627 %5 : java.type:"boolean" = java.cor
628 ()java.type:"boolean" -> {
629 %6 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::MON:SwitchExpressionTest2$Day";
630 %7 : java.type:"boolean" = eq %4 %6;
631 yield %7;
632 }
633 ()java.type:"boolean" -> {
634 %8 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::FRI:SwitchExpressionTest2$Day";
635 %9 : java.type:"boolean" = eq %4 %8;
636 yield %9;
637 }
638 ()java.type:"boolean" -> {
639 %10 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SUN:SwitchExpressionTest2$Day";
640 %11 : java.type:"boolean" = eq %4 %10;
641 yield %11;
642 };
643 yield %5;
644 }
645 ()java.type:"int" -> {
646 %12 : java.type:"int" = constant @6;
647 yield %12;
648 }
649 (%13 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
650 %14 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::TUE:SwitchExpressionTest2$Day";
651 %15 : java.type:"boolean" = eq %13 %14;
652 yield %15;
653 }
654 ()java.type:"int" -> {
655 %16 : java.type:"int" = constant @7;
656 yield %16;
657 }
658 (%17 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
659 %18 : java.type:"boolean" = java.cor
660 ()java.type:"boolean" -> {
661 %19 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::THU:SwitchExpressionTest2$Day";
662 %20 : java.type:"boolean" = eq %17 %19;
663 yield %20;
664 }
665 ()java.type:"boolean" -> {
666 %21 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SAT:SwitchExpressionTest2$Day";
667 %22 : java.type:"boolean" = eq %17 %21;
668 yield %22;
669 };
670 yield %18;
671 }
672 ()java.type:"int" -> {
673 %23 : java.type:"int" = constant @8;
674 yield %23;
675 }
676 (%24 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
677 %25 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::WED:SwitchExpressionTest2$Day";
678 %26 : java.type:"boolean" = eq %24 %25;
679 yield %26;
680 }
681 ()java.type:"int" -> {
682 %27 : java.type:"int" = constant @9;
683 yield %27;
684 }
685 ()java.type:"boolean" -> {
686 %28 : java.type:"boolean" = constant @true;
687 yield %28;
688 }
689 ()java.type:"int" -> {
690 %29 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
691 throw %29;
692 };
693 return %3;
694 };
695 """)
696 @Reflect
697 private static int caseConstantEnum(Day d) {
698 return switch (d) {
699 case MON, FRI, SUN -> 6;
700 case TUE -> 7;
701 case THU, SAT -> 8;
702 case WED -> 9;
703 };
704 }
705
706 static class Constants {
707 static final int c1 = 12;
708 }
709 @IR("""
710 func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
711 %1 : Var<java.type:"int"> = var %0 @"i";
712 %2 : java.type:"int" = constant @11;
713 %3 : Var<java.type:"int"> = var %2 @"eleven";
714 %4 : java.type:"int" = var.load %1;
715 %5 : java.type:"java.lang.String" = java.switch.expression %4
716 (%6 : java.type:"int")java.type:"boolean" -> {
717 %7 : java.type:"int" = constant @1;
718 %8 : java.type:"int" = constant @15;
719 %9 : java.type:"int" = and %7 %8;
720 %10 : java.type:"boolean" = eq %6 %9;
721 yield %10;
722 }
723 ()java.type:"java.lang.String" -> {
724 %11 : java.type:"java.lang.String" = constant @"1";
725 yield %11;
726 }
727 (%12 : java.type:"int")java.type:"boolean" -> {
728 %13 : java.type:"int" = constant @4;
729 %14 : java.type:"int" = constant @1;
730 %15 : java.type:"int" = ashr %13 %14;
731 %16 : java.type:"boolean" = eq %12 %15;
732 yield %16;
733 }
734 ()java.type:"java.lang.String" -> {
735 %17 : java.type:"java.lang.String" = constant @"2";
736 yield %17;
737 }
738 (%18 : java.type:"int")java.type:"boolean" -> {
739 %19 : java.type:"long" = constant @3;
740 %20 : java.type:"int" = conv %19;
741 %21 : java.type:"boolean" = eq %18 %20;
742 yield %21;
743 }
744 ()java.type:"java.lang.String" -> {
745 %22 : java.type:"java.lang.String" = constant @"3";
746 yield %22;
747 }
748 (%23 : java.type:"int")java.type:"boolean" -> {
749 %24 : java.type:"int" = constant @2;
750 %25 : java.type:"int" = constant @1;
751 %26 : java.type:"int" = lshl %24 %25;
752 %27 : java.type:"boolean" = eq %23 %26;
753 yield %27;
754 }
755 ()java.type:"java.lang.String" -> {
756 %28 : java.type:"java.lang.String" = constant @"4";
757 yield %28;
758 }
759 (%29 : java.type:"int")java.type:"boolean" -> {
760 %30 : java.type:"int" = constant @10;
761 %31 : java.type:"int" = constant @2;
762 %32 : java.type:"int" = div %30 %31;
763 %33 : java.type:"boolean" = eq %29 %32;
764 yield %33;
765 }
766 ()java.type:"java.lang.String" -> {
767 %34 : java.type:"java.lang.String" = constant @"5";
768 yield %34;
769 }
770 (%35 : java.type:"int")java.type:"boolean" -> {
771 %36 : java.type:"int" = constant @12;
772 %37 : java.type:"int" = constant @6;
773 %38 : java.type:"int" = sub %36 %37;
774 %39 : java.type:"boolean" = eq %35 %38;
775 yield %39;
776 }
777 ()java.type:"java.lang.String" -> {
778 %40 : java.type:"java.lang.String" = constant @"6";
779 yield %40;
780 }
781 (%41 : java.type:"int")java.type:"boolean" -> {
782 %42 : java.type:"int" = constant @3;
783 %43 : java.type:"int" = constant @4;
784 %44 : java.type:"int" = add %42 %43;
785 %45 : java.type:"boolean" = eq %41 %44;
786 yield %45;
787 }
788 ()java.type:"java.lang.String" -> {
789 %46 : java.type:"java.lang.String" = constant @"7";
790 yield %46;
791 }
792 (%47 : java.type:"int")java.type:"boolean" -> {
793 %48 : java.type:"int" = constant @2;
794 %49 : java.type:"int" = constant @2;
795 %50 : java.type:"int" = mul %48 %49;
796 %51 : java.type:"int" = constant @2;
797 %52 : java.type:"int" = mul %50 %51;
798 %53 : java.type:"boolean" = eq %47 %52;
799 yield %53;
800 }
801 ()java.type:"java.lang.String" -> {
802 %54 : java.type:"java.lang.String" = constant @"8";
803 yield %54;
804 }
805 (%55 : java.type:"int")java.type:"boolean" -> {
806 %56 : java.type:"int" = constant @8;
807 %57 : java.type:"int" = constant @1;
808 %58 : java.type:"int" = or %56 %57;
809 %59 : java.type:"boolean" = eq %55 %58;
810 yield %59;
811 }
812 ()java.type:"java.lang.String" -> {
813 %60 : java.type:"java.lang.String" = constant @"9";
814 yield %60;
815 }
816 (%61 : java.type:"int")java.type:"boolean" -> {
817 %62 : java.type:"int" = constant @10;
818 %63 : java.type:"boolean" = eq %61 %62;
819 yield %63;
820 }
821 ()java.type:"java.lang.String" -> {
822 %64 : java.type:"java.lang.String" = constant @"10";
823 yield %64;
824 }
825 (%65 : java.type:"int")java.type:"boolean" -> {
826 %66 : java.type:"int" = var.load %3;
827 %67 : java.type:"boolean" = eq %65 %66;
828 yield %67;
829 }
830 ()java.type:"java.lang.String" -> {
831 %68 : java.type:"java.lang.String" = constant @"11";
832 yield %68;
833 }
834 (%69 : java.type:"int")java.type:"boolean" -> {
835 %70 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
836 %71 : java.type:"boolean" = eq %69 %70;
837 yield %71;
838 }
839 ()java.type:"java.lang.String" -> {
840 %72 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
841 %73 : java.type:"java.lang.String" = invoke %72 @java.ref:"java.lang.String::valueOf(int):java.lang.String";
842 yield %73;
843 }
844 (%74 : java.type:"int")java.type:"boolean" -> {
845 %75 : java.type:"int" = java.cexpression
846 ()java.type:"boolean" -> {
847 %76 : java.type:"int" = constant @1;
848 %77 : java.type:"int" = constant @0;
849 %78 : java.type:"boolean" = gt %76 %77;
850 yield %78;
851 }
852 ()java.type:"int" -> {
853 %79 : java.type:"int" = constant @13;
854 yield %79;
855 }
856 ()java.type:"int" -> {
857 %80 : java.type:"int" = constant @133;
858 yield %80;
859 };
860 %81 : java.type:"boolean" = eq %74 %75;
861 yield %81;
862 }
863 ()java.type:"java.lang.String" -> {
864 %82 : java.type:"java.lang.String" = constant @"13";
865 yield %82;
866 }
867 ()java.type:"boolean" -> {
868 %83 : java.type:"boolean" = constant @true;
869 yield %83;
870 }
871 ()java.type:"java.lang.String" -> {
872 %84 : java.type:"java.lang.String" = constant @"an int";
873 yield %84;
874 };
875 return %5;
876 };
877 """)
878 @Reflect
879 private static String caseConstantOtherKindsOfExpr(int i) {
880 final int eleven = 11;
881 return switch (i) {
882 case 1 & 0xF -> "1";
883 case 4>>1 -> "2";
884 case (int) 3L -> "3";
885 case 2<<1 -> "4";
886 case 10 / 2 -> "5";
887 case 12 - 6 -> "6";
888 case 3 + 4 -> "7";
889 case 2 * 2 * 2 -> "8";
890 case 8 | 1 -> "9";
891 case (10) -> "10";
892 case eleven -> "11";
893 case Constants.c1 -> String.valueOf(Constants.c1);
894 case 1 > 0 ? 13 : 133 -> "13";
895 default -> "an int";
896 };
897 }
898
899 // these are the conversions that applies in switch
900
901 @IR("""
902 func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
903 %1 : Var<java.type:"short"> = var %0 @"a";
904 %2 : java.type:"int" = constant @1;
905 %3 : java.type:"short" = conv %2;
906 %4 : Var<java.type:"short"> = var %3 @"s";
907 %5 : java.type:"int" = constant @2;
908 %6 : java.type:"byte" = conv %5;
909 %7 : Var<java.type:"byte"> = var %6 @"b";
910 %8 : java.type:"short" = var.load %1;
911 %9 : java.type:"java.lang.String" = java.switch.expression %8
912 (%10 : java.type:"short")java.type:"boolean" -> {
913 %11 : java.type:"short" = var.load %4;
914 %12 : java.type:"boolean" = eq %10 %11;
915 yield %12;
916 }
917 ()java.type:"java.lang.String" -> {
918 %13 : java.type:"java.lang.String" = constant @"one";
919 yield %13;
920 }
921 (%14 : java.type:"short")java.type:"boolean" -> {
922 %15 : java.type:"byte" = var.load %7;
923 %16 : java.type:"short" = conv %15;
924 %17 : java.type:"boolean" = eq %14 %16;
925 yield %17;
926 }
927 ()java.type:"java.lang.String" -> {
928 %18 : java.type:"java.lang.String" = constant @"three";
929 yield %18;
930 }
931 (%19 : java.type:"short")java.type:"boolean" -> {
932 %20 : java.type:"int" = constant @3;
933 %21 : java.type:"short" = conv %20;
934 %22 : java.type:"boolean" = eq %19 %21;
935 yield %22;
936 }
937 ()java.type:"java.lang.String" -> {
938 %23 : java.type:"java.lang.String" = constant @"two";
939 yield %23;
940 }
941 ()java.type:"boolean" -> {
942 %24 : java.type:"boolean" = constant @true;
943 yield %24;
944 }
945 ()java.type:"java.lang.String" -> {
946 %25 : java.type:"java.lang.String" = constant @"default";
947 yield %25;
948 };
949 return %9;
950 };
951 """)
952 @Reflect
953 static String caseConstantConv(short a) {
954 final short s = 1;
955 final byte b = 2;
956 return switch (a) {
957 case s -> "one"; // identity
958 case b -> "three"; // widening primitive conversion
959 case 3 -> "two"; // narrowing primitive conversion
960 default -> "default";
961 };
962 }
963
964 @IR("""
965 func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
966 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
967 %2 : java.type:"int" = constant @2;
968 %3 : java.type:"byte" = conv %2;
969 %4 : Var<java.type:"byte"> = var %3 @"b";
970 %5 : java.type:"java.lang.Byte" = var.load %1;
971 %6 : java.type:"java.lang.String" = java.switch.expression %5
972 (%7 : java.type:"java.lang.Byte")java.type:"boolean" -> {
973 %8 : java.type:"byte" = invoke %7 @java.ref:"java.lang.Byte::byteValue():byte";
974 %9 : java.type:"int" = constant @1;
975 %10 : java.type:"byte" = conv %9;
976 %11 : java.type:"boolean" = eq %8 %10;
977 yield %11;
978 }
979 ()java.type:"java.lang.String" -> {
980 %11 : java.type:"java.lang.String" = constant @"one";
981 yield %11;
982 }
983 (%13 : java.type:"java.lang.Byte")java.type:"boolean" -> {
984 %14 : java.type:"byte" = invoke %13 @java.ref:"java.lang.Byte::byteValue():byte";
985 %15 : java.type:"byte" = var.load %4;
986 %16 : java.type:"boolean" = eq %14 %15;
987 yield %16;
988 }
989 ()java.type:"java.lang.String" -> {
990 %17 : java.type:"java.lang.String" = constant @"two";
991 yield %17;
992 }
993 ()java.type:"boolean" -> {
994 %18 : java.type:"boolean" = constant @true;
995 yield %18;
996 }
997 ()java.type:"java.lang.String" -> {
998 %19 : java.type:"java.lang.String" = constant @"default";
999 yield %19;
1000 };
1001 return %6;
1002 };
1003 """)
1004 @Reflect
1005 static String caseConstantConv2(Byte a) {
1006 final byte b = 2;
1007 return switch (a) {
1008 // narrowing conv is missing in the code model
1009 case 1 -> "one"; // narrowing primitive conversion followed by a boxing conversion
1010 case b -> "two"; // boxing
1011 default -> "default";
1012 };
1013 }
1014
1015 enum E { F, G }
1016 @IR("""
1017 func @"noDefaultLabelEnum" (%0 : java.type:"SwitchExpressionTest2$E")java.type:"java.lang.String" -> {
1018 %1 : Var<java.type:"SwitchExpressionTest2$E"> = var %0 @"e";
1019 %2 : java.type:"SwitchExpressionTest2$E" = var.load %1;
1020 %3 : java.type:"java.lang.String" = java.switch.expression %2
1021 (%4 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
1022 %5 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::F:SwitchExpressionTest2$E";
1023 %6 : java.type:"boolean" = eq %4 %5;
1024 yield %6;
1025 }
1026 ()java.type:"java.lang.String" -> {
1027 %7 : java.type:"java.lang.String" = constant @"f";
1028 yield %7;
1029 }
1030 (%8 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
1031 %9 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::G:SwitchExpressionTest2$E";
1032 %10 : java.type:"boolean" = eq %8 %9;
1033 yield %10;
1034 }
1035 ()java.type:"java.lang.String" -> {
1036 %11 : java.type:"java.lang.String" = constant @"g";
1037 yield %11;
1038 }
1039 ()java.type:"boolean" -> {
1040 %12 : java.type:"boolean" = constant @true;
1041 yield %12;
1042 }
1043 ()java.type:"java.lang.String" -> {
1044 %13 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
1045 throw %13;
1046 };
1047 return %3;
1048 };
1049 """)
1050 @Reflect
1051 static String noDefaultLabelEnum(E e) {
1052 return switch (e) {
1053 case F -> "f";
1054 case G -> "g";
1055 };
1056 }
1057
1058 @IR("""
1059 func @"unconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1060 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1061 %2 : java.type:"java.lang.String" = var.load %1;
1062 %3 : java.type:"java.lang.Object" = constant @null;
1063 %4 : Var<java.type:"java.lang.Object"> = var %3 @"o";
1064 %5 : java.type:"java.lang.String" = java.switch.expression %2
1065 (%6 : java.type:"java.lang.String")java.type:"boolean" -> {
1066 %7 : java.type:"java.lang.String" = constant @"A";
1067 %8 : java.type:"boolean" = invoke %6 %7 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1068 yield %8;
1069 }
1070 ()java.type:"java.lang.String" -> {
1071 %9 : java.type:"java.lang.String" = constant @"Alphabet";
1072 yield %9;
1073 }
1074 (%10 : java.type:"java.lang.String")java.type:"boolean" -> {
1075 %11 : java.type:"boolean" = pattern.match %10
1076 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
1077 %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
1078 yield %12;
1079 }
1080 (%13 : java.type:"java.lang.Object")java.type:"void" -> {
1081 var.store %4 %13;
1082 yield;
1083 };
1084 yield %11;
1085 }
1086 ()java.type:"java.lang.String" -> {
1087 %14 : java.type:"java.lang.String" = constant @"default";
1088 yield %14;
1089 };
1090 return %5;
1091 };
1092 """)
1093 @Reflect
1094 static String unconditionalPattern(String s) {
1095 return switch (s) {
1096 case "A" -> "Alphabet";
1097 case Object o -> "default";
1098 };
1099 }
1100
1101 sealed interface A permits B, C {}
1102 record B() implements A {}
1103 final class C implements A {}
1104 @IR("""
1105 func @"noDefault" (%0 : java.type:"SwitchExpressionTest2$A")java.type:"java.lang.String" -> {
1106 %1 : Var<java.type:"SwitchExpressionTest2$A"> = var %0 @"a";
1107 %2 : java.type:"SwitchExpressionTest2$A" = var.load %1;
1108 %3 : java.type:"SwitchExpressionTest2$B" = constant @null;
1109 %4 : Var<java.type:"SwitchExpressionTest2$B"> = var %3 @"b";
1110 %5 : java.type:"SwitchExpressionTest2::C" = constant @null;
1111 %6 : Var<java.type:"SwitchExpressionTest2::C"> = var %5 @"c";
1112 %7 : java.type:"java.lang.String" = java.switch.expression %2
1113 (%8 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
1114 %9 : java.type:"boolean" = pattern.match %8
1115 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" -> {
1116 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" = pattern.type @"b";
1117 yield %10;
1118 }
1119 (%11 : java.type:"SwitchExpressionTest2$B")java.type:"void" -> {
1120 var.store %4 %11;
1121 yield;
1122 };
1123 yield %9;
1124 }
1125 ()java.type:"java.lang.String" -> {
1126 %12 : java.type:"java.lang.String" = constant @"B";
1127 yield %12;
1128 }
1129 (%13 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
1130 %14 : java.type:"boolean" = pattern.match %13
1131 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" -> {
1132 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" = pattern.type @"c";
1133 yield %15;
1134 }
1135 (%16 : java.type:"SwitchExpressionTest2::C")java.type:"void" -> {
1136 var.store %6 %16;
1137 yield;
1138 };
1139 yield %14;
1140 }
1141 ()java.type:"java.lang.String" -> {
1142 %17 : java.type:"java.lang.String" = constant @"C";
1143 yield %17;
1144 }
1145 ()java.type:"boolean" -> {
1146 %18 : java.type:"boolean" = constant @true;
1147 yield %18;
1148 }
1149 ()java.type:"java.lang.String" -> {
1150 %19 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
1151 throw %19;
1152 };
1153 return %7;
1154 };
1155 """)
1156 @Reflect
1157 static String noDefault(A a) {
1158 return switch (a) {
1159 case B b -> "B";
1160 case C c -> "C";
1161 };
1162 }
1163
1164 @IR("""
1165 func @"defaultNotTheLastLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1166 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1167 %2 : java.type:"java.lang.String" = var.load %1;
1168 %3 : java.type:"java.lang.String" = java.switch.expression %2
1169 ()java.type:"boolean" -> {
1170 %12 : java.type:"boolean" = constant @true;
1171 yield %12;
1172 }
1173 ()java.type:"java.lang.String" -> {
1174 %13 : java.type:"java.lang.String" = constant @"else";
1175 yield %13;
1176 }
1177 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
1178 %5 : java.type:"java.lang.String" = constant @"M";
1179 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1180 yield %6;
1181 }
1182 ()java.type:"java.lang.String" -> {
1183 %7 : java.type:"java.lang.String" = constant @"Mow";
1184 yield %7;
1185 }
1186 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
1187 %9 : java.type:"java.lang.String" = constant @"A";
1188 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1189 yield %10;
1190 }
1191 ()java.type:"java.lang.String" -> {
1192 %11 : java.type:"java.lang.String" = constant @"Aow";
1193 yield %11;
1194 };
1195 return %3;
1196 };
1197 """)
1198 @Reflect
1199 static String defaultNotTheLastLabel(String s) {
1200 return switch (s) {
1201 default -> "else";
1202 case "M" -> "Mow";
1203 case "A" -> "Aow";
1204 };
1205 }
1206
1207 @IR("""
1208 func @"caseConstantPrimitiveWrapperSelector" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
1209 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
1210 %2 : java.type:"java.lang.Integer" = var.load %1;
1211 %3 : java.type:"java.lang.String" = java.switch.expression %2
1212 (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1213 %5 : java.type:"int" = invoke %4 @java.ref:"java.lang.Integer::intValue():int";
1214 %6 : java.type:"int" = constant @1;
1215 %7 : java.type:"boolean" = eq %5 %6;
1216 yield %7;
1217 }
1218 ()java.type:"java.lang.String" -> {
1219 %8 : java.type:"java.lang.String" = constant @"one";
1220 yield %8;
1221 }
1222 (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1223 %10 : java.type:"boolean" = java.cor
1224 ()java.type:"boolean" -> {
1225 %11 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1226 %12 : java.type:"int" = constant @2;
1227 %13 : java.type:"boolean" = eq %11 %12;
1228 yield %13;
1229 }
1230 ()java.type:"boolean" -> {
1231 %14 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1232 %15 : java.type:"int" = constant @3;
1233 %16 : java.type:"boolean" = eq %14 %15;
1234 yield %16;
1235 };
1236 yield %10;
1237 }
1238 ()java.type:"java.lang.String" -> {
1239 %17 : java.type:"java.lang.String" = constant @"two or three";
1240 yield %17;
1241 }
1242 ()java.type:"boolean" -> {
1243 %18 : java.type:"boolean" = constant @true;
1244 yield %18;
1245 }
1246 ()java.type:"java.lang.String" -> {
1247 %19 : java.type:"java.lang.String" = constant @"else";
1248 yield %19;
1249 };
1250 return %3;
1251 };
1252 """)
1253 @Reflect
1254 static String caseConstantPrimitiveWrapperSelector(Integer i) {
1255 return switch (i) {
1256 case 1 -> "one";
1257 case 2, 3 -> "two or three";
1258 default -> "else";
1259 };
1260 }
1261
1262 @IR("""
1263 func @"constantLabelCasted" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1264 %1 : Var<java.type:"int"> = var %0 @"i";
1265 %2 : java.type:"int" = var.load %1;
1266 %3 : java.type:"java.lang.String" = java.switch.expression %2
1267 (%4 : java.type:"int")java.type:"boolean" -> {
1268 %5 : java.type:"int" = constant @1;
1269 %6 : java.type:"byte" = conv %5;
1270 %7 : java.type:"int" = conv %6;
1271 %8 : java.type:"boolean" = eq %4 %7;
1272 yield %8;
1273 }
1274 ()java.type:"java.lang.String" -> {
1275 %9 : java.type:"java.lang.String" = constant @"one";
1276 yield %9;
1277 }
1278 ()java.type:"boolean" -> {
1279 %10 : java.type:"boolean" = constant @true;
1280 yield %10;
1281 }
1282 ()java.type:"java.lang.String" -> {
1283 %11 : java.type:"java.lang.String" = constant @"not one";
1284 yield %11;
1285 };
1286 return %3;
1287 };
1288 """)
1289 @Reflect
1290 static String constantLabelCasted(int i) {
1291 return switch (i) {
1292 case (byte) 1 -> "one";
1293 default -> "not one";
1294 };
1295 }
1296
1297 @IR("""
1298 func @"caseConstantStringLiteral" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1299 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1300 %2 : java.type:"java.lang.String" = var.load %1;
1301 %3 : java.type:"java.lang.String" = java.switch.expression %2
1302 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
1303 %5 : java.type:"java.lang.String" = constant @"1";
1304 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1305 yield %6;
1306 }
1307 ()java.type:"java.lang.String" -> {
1308 %7 : java.type:"java.lang.String" = constant @"one";
1309 yield %7;
1310 }
1311 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
1312 %9 : java.type:"boolean" = java.cor
1313 ()java.type:"boolean" -> {
1314 %10 : java.type:"java.lang.String" = constant @"2";
1315 %11 : java.type:"boolean" = invoke %8 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1316 yield %11;
1317 }
1318 ()java.type:"boolean" -> {
1319 %12 : java.type:"java.lang.String" = constant @"3";
1320 %13 : java.type:"boolean" = invoke %8 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1321 yield %13;
1322 };
1323 yield %9;
1324 }
1325 ()java.type:"java.lang.String" -> {
1326 %14 : java.type:"java.lang.String" = constant @"two or three";
1327 yield %14;
1328 }
1329 ()java.type:"boolean" -> {
1330 %15 : java.type:"boolean" = constant @true;
1331 yield %15;
1332 }
1333 ()java.type:"java.lang.String" -> {
1334 %16 : java.type:"java.lang.String" = constant @"else";
1335 yield %16;
1336 };
1337 return %3;
1338 };
1339 """)
1340 @Reflect
1341 static String caseConstantStringLiteral(String s) {
1342 return switch (s) {
1343 case "1" -> "one";
1344 case "2", "3" -> "two or three";
1345 default -> "else";
1346 };
1347 }
1348
1349 @IR("""
1350 func @"casePatternWithCaseConstant" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1351 %1 : Var<java.type:"int"> = var %0 @"i";
1352 %2 : java.type:"int" = var.load %1;
1353 %3 : java.type:"java.lang.Integer" = constant @null;
1354 %4 : Var<java.type:"java.lang.Integer"> = var %3 @"j";
1355 %5 : java.type:"java.lang.Integer" = constant @null;
1356 %6 : Var<java.type:"java.lang.Integer"> = var %5;
1357 %7 : java.type:"java.lang.String" = java.switch.expression %2
1358 (%8 : java.type:"int")java.type:"boolean" -> {
1359 %9 : java.type:"int" = constant @0;
1360 %10 : java.type:"boolean" = eq %8 %9;
1361 yield %10;
1362 }
1363 ()java.type:"java.lang.String" -> {
1364 %11 : java.type:"java.lang.String" = constant @"zero";
1365 yield %11;
1366 }
1367 (%12 : java.type:"int")java.type:"boolean" -> {
1368 %13 : java.type:"boolean" = java.cand
1369 ()java.type:"boolean" -> {
1370 %14 : java.type:"java.lang.Integer" = invoke %12 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1371 %15 : java.type:"boolean" = pattern.match %14
1372 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1373 %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"j";
1374 yield %16;
1375 }
1376 (%17 : java.type:"java.lang.Integer")java.type:"void" -> {
1377 var.store %4 %17;
1378 yield;
1379 };
1380 yield %15;
1381 }
1382 ()java.type:"boolean" -> {
1383 %18 : java.type:"java.lang.Integer" = var.load %4;
1384 %19 : java.type:"int" = invoke %18 @java.ref:"java.lang.Integer::intValue():int";
1385 %20 : java.type:"int" = constant @0;
1386 %21 : java.type:"boolean" = gt %19 %20;
1387 yield %21;
1388 };
1389 yield %13;
1390 }
1391 ()java.type:"java.lang.String" -> {
1392 %22 : java.type:"java.lang.String" = constant @"positive";
1393 yield %22;
1394 }
1395 (%23 : java.type:"int")java.type:"boolean" -> {
1396 %24 : java.type:"java.lang.Integer" = invoke %23 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1397 %25 : java.type:"boolean" = pattern.match %24
1398 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1399 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
1400 yield %26;
1401 }
1402 (%27 : java.type:"java.lang.Integer")java.type:"void" -> {
1403 var.store %6 %27;
1404 yield;
1405 };
1406 yield %25;
1407 }
1408 ()java.type:"java.lang.String" -> {
1409 %28 : java.type:"java.lang.String" = constant @"negative";
1410 yield %28;
1411 };
1412 return %7;
1413 };
1414 """)
1415 @Reflect
1416 static String casePatternWithCaseConstant(int i) {
1417 return switch (i) {
1418 case 0 -> "zero";
1419 case Integer j when j > 0 -> "positive";
1420 case Integer _ -> "negative";
1421 };
1422 }
1423 }