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.String" = constant @null;
691 %30 : java.type:"java.lang.Throwable" = constant @null;
692 %31 : java.type:"java.lang.MatchException" = new %29 %30 @java.ref:"java.lang.MatchException::(java.lang.String, java.lang.Throwable)";
693 throw %31;
694 };
695 return %3;
696 };
697 """)
698 @Reflect
699 private static int caseConstantEnum(Day d) {
700 return switch (d) {
701 case MON, FRI, SUN -> 6;
702 case TUE -> 7;
703 case THU, SAT -> 8;
704 case WED -> 9;
705 };
706 }
707
708 static class Constants {
709 static final int c1 = 12;
710 }
711 @IR("""
712 func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
713 %1 : Var<java.type:"int"> = var %0 @"i";
714 %2 : java.type:"int" = constant @11;
715 %3 : Var<java.type:"int"> = var %2 @"eleven";
716 %4 : java.type:"int" = var.load %1;
717 %5 : java.type:"java.lang.String" = java.switch.expression %4
718 (%6 : java.type:"int")java.type:"boolean" -> {
719 %7 : java.type:"int" = constant @1;
720 %8 : java.type:"int" = constant @15;
721 %9 : java.type:"int" = and %7 %8;
722 %10 : java.type:"boolean" = eq %6 %9;
723 yield %10;
724 }
725 ()java.type:"java.lang.String" -> {
726 %11 : java.type:"java.lang.String" = constant @"1";
727 yield %11;
728 }
729 (%12 : java.type:"int")java.type:"boolean" -> {
730 %13 : java.type:"int" = constant @4;
731 %14 : java.type:"int" = constant @1;
732 %15 : java.type:"int" = ashr %13 %14;
733 %16 : java.type:"boolean" = eq %12 %15;
734 yield %16;
735 }
736 ()java.type:"java.lang.String" -> {
737 %17 : java.type:"java.lang.String" = constant @"2";
738 yield %17;
739 }
740 (%18 : java.type:"int")java.type:"boolean" -> {
741 %19 : java.type:"long" = constant @3;
742 %20 : java.type:"int" = conv %19;
743 %21 : java.type:"boolean" = eq %18 %20;
744 yield %21;
745 }
746 ()java.type:"java.lang.String" -> {
747 %22 : java.type:"java.lang.String" = constant @"3";
748 yield %22;
749 }
750 (%23 : java.type:"int")java.type:"boolean" -> {
751 %24 : java.type:"int" = constant @2;
752 %25 : java.type:"int" = constant @1;
753 %26 : java.type:"int" = lshl %24 %25;
754 %27 : java.type:"boolean" = eq %23 %26;
755 yield %27;
756 }
757 ()java.type:"java.lang.String" -> {
758 %28 : java.type:"java.lang.String" = constant @"4";
759 yield %28;
760 }
761 (%29 : java.type:"int")java.type:"boolean" -> {
762 %30 : java.type:"int" = constant @10;
763 %31 : java.type:"int" = constant @2;
764 %32 : java.type:"int" = div %30 %31;
765 %33 : java.type:"boolean" = eq %29 %32;
766 yield %33;
767 }
768 ()java.type:"java.lang.String" -> {
769 %34 : java.type:"java.lang.String" = constant @"5";
770 yield %34;
771 }
772 (%35 : java.type:"int")java.type:"boolean" -> {
773 %36 : java.type:"int" = constant @12;
774 %37 : java.type:"int" = constant @6;
775 %38 : java.type:"int" = sub %36 %37;
776 %39 : java.type:"boolean" = eq %35 %38;
777 yield %39;
778 }
779 ()java.type:"java.lang.String" -> {
780 %40 : java.type:"java.lang.String" = constant @"6";
781 yield %40;
782 }
783 (%41 : java.type:"int")java.type:"boolean" -> {
784 %42 : java.type:"int" = constant @3;
785 %43 : java.type:"int" = constant @4;
786 %44 : java.type:"int" = add %42 %43;
787 %45 : java.type:"boolean" = eq %41 %44;
788 yield %45;
789 }
790 ()java.type:"java.lang.String" -> {
791 %46 : java.type:"java.lang.String" = constant @"7";
792 yield %46;
793 }
794 (%47 : java.type:"int")java.type:"boolean" -> {
795 %48 : java.type:"int" = constant @2;
796 %49 : java.type:"int" = constant @2;
797 %50 : java.type:"int" = mul %48 %49;
798 %51 : java.type:"int" = constant @2;
799 %52 : java.type:"int" = mul %50 %51;
800 %53 : java.type:"boolean" = eq %47 %52;
801 yield %53;
802 }
803 ()java.type:"java.lang.String" -> {
804 %54 : java.type:"java.lang.String" = constant @"8";
805 yield %54;
806 }
807 (%55 : java.type:"int")java.type:"boolean" -> {
808 %56 : java.type:"int" = constant @8;
809 %57 : java.type:"int" = constant @1;
810 %58 : java.type:"int" = or %56 %57;
811 %59 : java.type:"boolean" = eq %55 %58;
812 yield %59;
813 }
814 ()java.type:"java.lang.String" -> {
815 %60 : java.type:"java.lang.String" = constant @"9";
816 yield %60;
817 }
818 (%61 : java.type:"int")java.type:"boolean" -> {
819 %62 : java.type:"int" = constant @10;
820 %63 : java.type:"boolean" = eq %61 %62;
821 yield %63;
822 }
823 ()java.type:"java.lang.String" -> {
824 %64 : java.type:"java.lang.String" = constant @"10";
825 yield %64;
826 }
827 (%65 : java.type:"int")java.type:"boolean" -> {
828 %66 : java.type:"int" = var.load %3;
829 %67 : java.type:"boolean" = eq %65 %66;
830 yield %67;
831 }
832 ()java.type:"java.lang.String" -> {
833 %68 : java.type:"java.lang.String" = constant @"11";
834 yield %68;
835 }
836 (%69 : java.type:"int")java.type:"boolean" -> {
837 %70 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
838 %71 : java.type:"boolean" = eq %69 %70;
839 yield %71;
840 }
841 ()java.type:"java.lang.String" -> {
842 %72 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
843 %73 : java.type:"java.lang.String" = invoke %72 @java.ref:"java.lang.String::valueOf(int):java.lang.String";
844 yield %73;
845 }
846 (%74 : java.type:"int")java.type:"boolean" -> {
847 %75 : java.type:"int" = java.cexpression
848 ()java.type:"boolean" -> {
849 %76 : java.type:"int" = constant @1;
850 %77 : java.type:"int" = constant @0;
851 %78 : java.type:"boolean" = gt %76 %77;
852 yield %78;
853 }
854 ()java.type:"int" -> {
855 %79 : java.type:"int" = constant @13;
856 yield %79;
857 }
858 ()java.type:"int" -> {
859 %80 : java.type:"int" = constant @133;
860 yield %80;
861 };
862 %81 : java.type:"boolean" = eq %74 %75;
863 yield %81;
864 }
865 ()java.type:"java.lang.String" -> {
866 %82 : java.type:"java.lang.String" = constant @"13";
867 yield %82;
868 }
869 ()java.type:"boolean" -> {
870 %83 : java.type:"boolean" = constant @true;
871 yield %83;
872 }
873 ()java.type:"java.lang.String" -> {
874 %84 : java.type:"java.lang.String" = constant @"an int";
875 yield %84;
876 };
877 return %5;
878 };
879 """)
880 @Reflect
881 private static String caseConstantOtherKindsOfExpr(int i) {
882 final int eleven = 11;
883 return switch (i) {
884 case 1 & 0xF -> "1";
885 case 4>>1 -> "2";
886 case (int) 3L -> "3";
887 case 2<<1 -> "4";
888 case 10 / 2 -> "5";
889 case 12 - 6 -> "6";
890 case 3 + 4 -> "7";
891 case 2 * 2 * 2 -> "8";
892 case 8 | 1 -> "9";
893 case (10) -> "10";
894 case eleven -> "11";
895 case Constants.c1 -> String.valueOf(Constants.c1);
896 case 1 > 0 ? 13 : 133 -> "13";
897 default -> "an int";
898 };
899 }
900
901 // these are the conversions that applies in switch
902
903 @IR("""
904 func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
905 %1 : Var<java.type:"short"> = var %0 @"a";
906 %2 : java.type:"int" = constant @1;
907 %3 : java.type:"short" = conv %2;
908 %4 : Var<java.type:"short"> = var %3 @"s";
909 %5 : java.type:"int" = constant @2;
910 %6 : java.type:"byte" = conv %5;
911 %7 : Var<java.type:"byte"> = var %6 @"b";
912 %8 : java.type:"short" = var.load %1;
913 %9 : java.type:"java.lang.String" = java.switch.expression %8
914 (%10 : java.type:"short")java.type:"boolean" -> {
915 %11 : java.type:"short" = var.load %4;
916 %12 : java.type:"boolean" = eq %10 %11;
917 yield %12;
918 }
919 ()java.type:"java.lang.String" -> {
920 %13 : java.type:"java.lang.String" = constant @"one";
921 yield %13;
922 }
923 (%14 : java.type:"short")java.type:"boolean" -> {
924 %15 : java.type:"byte" = var.load %7;
925 %16 : java.type:"short" = conv %15;
926 %17 : java.type:"boolean" = eq %14 %16;
927 yield %17;
928 }
929 ()java.type:"java.lang.String" -> {
930 %18 : java.type:"java.lang.String" = constant @"three";
931 yield %18;
932 }
933 (%19 : java.type:"short")java.type:"boolean" -> {
934 %20 : java.type:"int" = constant @3;
935 %21 : java.type:"short" = conv %20;
936 %22 : java.type:"boolean" = eq %19 %21;
937 yield %22;
938 }
939 ()java.type:"java.lang.String" -> {
940 %23 : java.type:"java.lang.String" = constant @"two";
941 yield %23;
942 }
943 ()java.type:"boolean" -> {
944 %24 : java.type:"boolean" = constant @true;
945 yield %24;
946 }
947 ()java.type:"java.lang.String" -> {
948 %25 : java.type:"java.lang.String" = constant @"default";
949 yield %25;
950 };
951 return %9;
952 };
953 """)
954 @Reflect
955 static String caseConstantConv(short a) {
956 final short s = 1;
957 final byte b = 2;
958 return switch (a) {
959 case s -> "one"; // identity
960 case b -> "three"; // widening primitive conversion
961 case 3 -> "two"; // narrowing primitive conversion
962 default -> "default";
963 };
964 }
965
966 @IR("""
967 func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
968 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
969 %2 : java.type:"int" = constant @2;
970 %3 : java.type:"byte" = conv %2;
971 %4 : Var<java.type:"byte"> = var %3 @"b";
972 %5 : java.type:"java.lang.Byte" = var.load %1;
973 %6 : java.type:"java.lang.String" = java.switch.expression %5
974 (%7 : java.type:"java.lang.Byte")java.type:"boolean" -> {
975 %8 : java.type:"byte" = invoke %7 @java.ref:"java.lang.Byte::byteValue():byte";
976 %9 : java.type:"int" = constant @1;
977 %10 : java.type:"byte" = conv %9;
978 %11 : java.type:"boolean" = eq %8 %10;
979 yield %11;
980 }
981 ()java.type:"java.lang.String" -> {
982 %11 : java.type:"java.lang.String" = constant @"one";
983 yield %11;
984 }
985 (%13 : java.type:"java.lang.Byte")java.type:"boolean" -> {
986 %14 : java.type:"byte" = invoke %13 @java.ref:"java.lang.Byte::byteValue():byte";
987 %15 : java.type:"byte" = var.load %4;
988 %16 : java.type:"boolean" = eq %14 %15;
989 yield %16;
990 }
991 ()java.type:"java.lang.String" -> {
992 %17 : java.type:"java.lang.String" = constant @"two";
993 yield %17;
994 }
995 ()java.type:"boolean" -> {
996 %18 : java.type:"boolean" = constant @true;
997 yield %18;
998 }
999 ()java.type:"java.lang.String" -> {
1000 %19 : java.type:"java.lang.String" = constant @"default";
1001 yield %19;
1002 };
1003 return %6;
1004 };
1005 """)
1006 @Reflect
1007 static String caseConstantConv2(Byte a) {
1008 final byte b = 2;
1009 return switch (a) {
1010 // narrowing conv is missing in the code model
1011 case 1 -> "one"; // narrowing primitive conversion followed by a boxing conversion
1012 case b -> "two"; // boxing
1013 default -> "default";
1014 };
1015 }
1016
1017 enum E { F, G }
1018 @IR("""
1019 func @"noDefaultLabelEnum" (%0 : java.type:"SwitchExpressionTest2$E")java.type:"java.lang.String" -> {
1020 %1 : Var<java.type:"SwitchExpressionTest2$E"> = var %0 @"e";
1021 %2 : java.type:"SwitchExpressionTest2$E" = var.load %1;
1022 %3 : java.type:"java.lang.String" = java.switch.expression %2
1023 (%4 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
1024 %5 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::F:SwitchExpressionTest2$E";
1025 %6 : java.type:"boolean" = eq %4 %5;
1026 yield %6;
1027 }
1028 ()java.type:"java.lang.String" -> {
1029 %7 : java.type:"java.lang.String" = constant @"f";
1030 yield %7;
1031 }
1032 (%8 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
1033 %9 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::G:SwitchExpressionTest2$E";
1034 %10 : java.type:"boolean" = eq %8 %9;
1035 yield %10;
1036 }
1037 ()java.type:"java.lang.String" -> {
1038 %11 : java.type:"java.lang.String" = constant @"g";
1039 yield %11;
1040 }
1041 ()java.type:"boolean" -> {
1042 %12 : java.type:"boolean" = constant @true;
1043 yield %12;
1044 }
1045 ()java.type:"java.lang.String" -> {
1046 %13 : java.type:"java.lang.String" = constant @null;
1047 %14 : java.type:"java.lang.Throwable" = constant @null;
1048 %15 : java.type:"java.lang.MatchException" = new %13 %14 @java.ref:"java.lang.MatchException::(java.lang.String, java.lang.Throwable)";
1049 throw %15;
1050 };
1051 return %3;
1052 };
1053 """)
1054 @Reflect
1055 static String noDefaultLabelEnum(E e) {
1056 return switch (e) {
1057 case F -> "f";
1058 case G -> "g";
1059 };
1060 }
1061
1062 @IR("""
1063 func @"unconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1064 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1065 %2 : java.type:"java.lang.String" = var.load %1;
1066 %3 : java.type:"java.lang.Object" = constant @null;
1067 %4 : Var<java.type:"java.lang.Object"> = var %3 @"o";
1068 %5 : java.type:"java.lang.String" = java.switch.expression %2
1069 (%6 : java.type:"java.lang.String")java.type:"boolean" -> {
1070 %7 : java.type:"java.lang.String" = constant @"A";
1071 %8 : java.type:"boolean" = invoke %6 %7 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1072 yield %8;
1073 }
1074 ()java.type:"java.lang.String" -> {
1075 %9 : java.type:"java.lang.String" = constant @"Alphabet";
1076 yield %9;
1077 }
1078 (%10 : java.type:"java.lang.String")java.type:"boolean" -> {
1079 %11 : java.type:"boolean" = pattern.match %10
1080 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
1081 %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
1082 yield %12;
1083 }
1084 (%13 : java.type:"java.lang.Object")java.type:"void" -> {
1085 var.store %4 %13;
1086 yield;
1087 };
1088 yield %11;
1089 }
1090 ()java.type:"java.lang.String" -> {
1091 %14 : java.type:"java.lang.String" = constant @"default";
1092 yield %14;
1093 };
1094 return %5;
1095 };
1096 """)
1097 @Reflect
1098 static String unconditionalPattern(String s) {
1099 return switch (s) {
1100 case "A" -> "Alphabet";
1101 case Object o -> "default";
1102 };
1103 }
1104
1105 sealed interface A permits B, C {}
1106 record B() implements A {}
1107 final class C implements A {}
1108 @IR("""
1109 func @"noDefault" (%0 : java.type:"SwitchExpressionTest2$A")java.type:"java.lang.String" -> {
1110 %1 : Var<java.type:"SwitchExpressionTest2$A"> = var %0 @"a";
1111 %2 : java.type:"SwitchExpressionTest2$A" = var.load %1;
1112 %3 : java.type:"SwitchExpressionTest2$B" = constant @null;
1113 %4 : Var<java.type:"SwitchExpressionTest2$B"> = var %3 @"b";
1114 %5 : java.type:"SwitchExpressionTest2::C" = constant @null;
1115 %6 : Var<java.type:"SwitchExpressionTest2::C"> = var %5 @"c";
1116 %7 : java.type:"java.lang.String" = java.switch.expression %2
1117 (%8 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
1118 %9 : java.type:"boolean" = pattern.match %8
1119 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" -> {
1120 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" = pattern.type @"b";
1121 yield %10;
1122 }
1123 (%11 : java.type:"SwitchExpressionTest2$B")java.type:"void" -> {
1124 var.store %4 %11;
1125 yield;
1126 };
1127 yield %9;
1128 }
1129 ()java.type:"java.lang.String" -> {
1130 %12 : java.type:"java.lang.String" = constant @"B";
1131 yield %12;
1132 }
1133 (%13 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
1134 %14 : java.type:"boolean" = pattern.match %13
1135 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" -> {
1136 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" = pattern.type @"c";
1137 yield %15;
1138 }
1139 (%16 : java.type:"SwitchExpressionTest2::C")java.type:"void" -> {
1140 var.store %6 %16;
1141 yield;
1142 };
1143 yield %14;
1144 }
1145 ()java.type:"java.lang.String" -> {
1146 %17 : java.type:"java.lang.String" = constant @"C";
1147 yield %17;
1148 }
1149 ()java.type:"boolean" -> {
1150 %18 : java.type:"boolean" = constant @true;
1151 yield %18;
1152 }
1153 ()java.type:"java.lang.String" -> {
1154 %19 : java.type:"java.lang.String" = constant @null;
1155 %20 : java.type:"java.lang.Throwable" = constant @null;
1156 %21 : java.type:"java.lang.MatchException" = new %19 %20 @java.ref:"java.lang.MatchException::(java.lang.String, java.lang.Throwable)";
1157 throw %21;
1158 };
1159 return %7;
1160 };
1161 """)
1162 @Reflect
1163 static String noDefault(A a) {
1164 return switch (a) {
1165 case B b -> "B";
1166 case C c -> "C";
1167 };
1168 }
1169
1170 @IR("""
1171 func @"defaultNotTheLastLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1172 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1173 %2 : java.type:"java.lang.String" = var.load %1;
1174 %3 : java.type:"java.lang.String" = java.switch.expression %2
1175 ()java.type:"boolean" -> {
1176 %12 : java.type:"boolean" = constant @true;
1177 yield %12;
1178 }
1179 ()java.type:"java.lang.String" -> {
1180 %13 : java.type:"java.lang.String" = constant @"else";
1181 yield %13;
1182 }
1183 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
1184 %5 : java.type:"java.lang.String" = constant @"M";
1185 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1186 yield %6;
1187 }
1188 ()java.type:"java.lang.String" -> {
1189 %7 : java.type:"java.lang.String" = constant @"Mow";
1190 yield %7;
1191 }
1192 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
1193 %9 : java.type:"java.lang.String" = constant @"A";
1194 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1195 yield %10;
1196 }
1197 ()java.type:"java.lang.String" -> {
1198 %11 : java.type:"java.lang.String" = constant @"Aow";
1199 yield %11;
1200 };
1201 return %3;
1202 };
1203 """)
1204 @Reflect
1205 static String defaultNotTheLastLabel(String s) {
1206 return switch (s) {
1207 default -> "else";
1208 case "M" -> "Mow";
1209 case "A" -> "Aow";
1210 };
1211 }
1212
1213 @IR("""
1214 func @"caseConstantPrimitiveWrapperSelector" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
1215 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
1216 %2 : java.type:"java.lang.Integer" = var.load %1;
1217 %3 : java.type:"java.lang.String" = java.switch.expression %2
1218 (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1219 %5 : java.type:"int" = invoke %4 @java.ref:"java.lang.Integer::intValue():int";
1220 %6 : java.type:"int" = constant @1;
1221 %7 : java.type:"boolean" = eq %5 %6;
1222 yield %7;
1223 }
1224 ()java.type:"java.lang.String" -> {
1225 %8 : java.type:"java.lang.String" = constant @"one";
1226 yield %8;
1227 }
1228 (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1229 %10 : java.type:"boolean" = java.cor
1230 ()java.type:"boolean" -> {
1231 %11 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1232 %12 : java.type:"int" = constant @2;
1233 %13 : java.type:"boolean" = eq %11 %12;
1234 yield %13;
1235 }
1236 ()java.type:"boolean" -> {
1237 %14 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1238 %15 : java.type:"int" = constant @3;
1239 %16 : java.type:"boolean" = eq %14 %15;
1240 yield %16;
1241 };
1242 yield %10;
1243 }
1244 ()java.type:"java.lang.String" -> {
1245 %17 : java.type:"java.lang.String" = constant @"two or three";
1246 yield %17;
1247 }
1248 ()java.type:"boolean" -> {
1249 %18 : java.type:"boolean" = constant @true;
1250 yield %18;
1251 }
1252 ()java.type:"java.lang.String" -> {
1253 %19 : java.type:"java.lang.String" = constant @"else";
1254 yield %19;
1255 };
1256 return %3;
1257 };
1258 """)
1259 @Reflect
1260 static String caseConstantPrimitiveWrapperSelector(Integer i) {
1261 return switch (i) {
1262 case 1 -> "one";
1263 case 2, 3 -> "two or three";
1264 default -> "else";
1265 };
1266 }
1267
1268 @IR("""
1269 func @"constantLabelCasted" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1270 %1 : Var<java.type:"int"> = var %0 @"i";
1271 %2 : java.type:"int" = var.load %1;
1272 %3 : java.type:"java.lang.String" = java.switch.expression %2
1273 (%4 : java.type:"int")java.type:"boolean" -> {
1274 %5 : java.type:"int" = constant @1;
1275 %6 : java.type:"byte" = conv %5;
1276 %7 : java.type:"int" = conv %6;
1277 %8 : java.type:"boolean" = eq %4 %7;
1278 yield %8;
1279 }
1280 ()java.type:"java.lang.String" -> {
1281 %9 : java.type:"java.lang.String" = constant @"one";
1282 yield %9;
1283 }
1284 ()java.type:"boolean" -> {
1285 %10 : java.type:"boolean" = constant @true;
1286 yield %10;
1287 }
1288 ()java.type:"java.lang.String" -> {
1289 %11 : java.type:"java.lang.String" = constant @"not one";
1290 yield %11;
1291 };
1292 return %3;
1293 };
1294 """)
1295 @Reflect
1296 static String constantLabelCasted(int i) {
1297 return switch (i) {
1298 case (byte) 1 -> "one";
1299 default -> "not one";
1300 };
1301 }
1302
1303 @IR("""
1304 func @"caseConstantStringLiteral" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1305 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1306 %2 : java.type:"java.lang.String" = var.load %1;
1307 %3 : java.type:"java.lang.String" = java.switch.expression %2
1308 (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
1309 %5 : java.type:"java.lang.String" = constant @"1";
1310 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1311 yield %6;
1312 }
1313 ()java.type:"java.lang.String" -> {
1314 %7 : java.type:"java.lang.String" = constant @"one";
1315 yield %7;
1316 }
1317 (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
1318 %9 : java.type:"boolean" = java.cor
1319 ()java.type:"boolean" -> {
1320 %10 : java.type:"java.lang.String" = constant @"2";
1321 %11 : java.type:"boolean" = invoke %8 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1322 yield %11;
1323 }
1324 ()java.type:"boolean" -> {
1325 %12 : java.type:"java.lang.String" = constant @"3";
1326 %13 : java.type:"boolean" = invoke %8 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1327 yield %13;
1328 };
1329 yield %9;
1330 }
1331 ()java.type:"java.lang.String" -> {
1332 %14 : java.type:"java.lang.String" = constant @"two or three";
1333 yield %14;
1334 }
1335 ()java.type:"boolean" -> {
1336 %15 : java.type:"boolean" = constant @true;
1337 yield %15;
1338 }
1339 ()java.type:"java.lang.String" -> {
1340 %16 : java.type:"java.lang.String" = constant @"else";
1341 yield %16;
1342 };
1343 return %3;
1344 };
1345 """)
1346 @Reflect
1347 static String caseConstantStringLiteral(String s) {
1348 return switch (s) {
1349 case "1" -> "one";
1350 case "2", "3" -> "two or three";
1351 default -> "else";
1352 };
1353 }
1354
1355 @IR("""
1356 func @"casePatternWithCaseConstant" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1357 %1 : Var<java.type:"int"> = var %0 @"i";
1358 %2 : java.type:"int" = var.load %1;
1359 %3 : java.type:"java.lang.Integer" = constant @null;
1360 %4 : Var<java.type:"java.lang.Integer"> = var %3 @"j";
1361 %5 : java.type:"java.lang.Integer" = constant @null;
1362 %6 : Var<java.type:"java.lang.Integer"> = var %5;
1363 %7 : java.type:"java.lang.String" = java.switch.expression %2
1364 (%8 : java.type:"int")java.type:"boolean" -> {
1365 %9 : java.type:"int" = constant @0;
1366 %10 : java.type:"boolean" = eq %8 %9;
1367 yield %10;
1368 }
1369 ()java.type:"java.lang.String" -> {
1370 %11 : java.type:"java.lang.String" = constant @"zero";
1371 yield %11;
1372 }
1373 (%12 : java.type:"int")java.type:"boolean" -> {
1374 %13 : java.type:"boolean" = java.cand
1375 ()java.type:"boolean" -> {
1376 %14 : java.type:"java.lang.Integer" = invoke %12 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1377 %15 : java.type:"boolean" = pattern.match %14
1378 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1379 %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"j";
1380 yield %16;
1381 }
1382 (%17 : java.type:"java.lang.Integer")java.type:"void" -> {
1383 var.store %4 %17;
1384 yield;
1385 };
1386 yield %15;
1387 }
1388 ()java.type:"boolean" -> {
1389 %18 : java.type:"java.lang.Integer" = var.load %4;
1390 %19 : java.type:"int" = invoke %18 @java.ref:"java.lang.Integer::intValue():int";
1391 %20 : java.type:"int" = constant @0;
1392 %21 : java.type:"boolean" = gt %19 %20;
1393 yield %21;
1394 };
1395 yield %13;
1396 }
1397 ()java.type:"java.lang.String" -> {
1398 %22 : java.type:"java.lang.String" = constant @"positive";
1399 yield %22;
1400 }
1401 (%23 : java.type:"int")java.type:"boolean" -> {
1402 %24 : java.type:"java.lang.Integer" = invoke %23 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1403 %25 : java.type:"boolean" = pattern.match %24
1404 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1405 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
1406 yield %26;
1407 }
1408 (%27 : java.type:"java.lang.Integer")java.type:"void" -> {
1409 var.store %6 %27;
1410 yield;
1411 };
1412 yield %25;
1413 }
1414 ()java.type:"java.lang.String" -> {
1415 %28 : java.type:"java.lang.String" = constant @"negative";
1416 yield %28;
1417 };
1418 return %7;
1419 };
1420 """)
1421 @Reflect
1422 static String casePatternWithCaseConstant(int i) {
1423 return switch (i) {
1424 case 0 -> "zero";
1425 case Integer j when j > 0 -> "positive";
1426 case Integer _ -> "negative";
1427 };
1428 }
1429 }