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 import java.util.function.Consumer;
 26 import java.util.function.Supplier;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with switch expressions.
 31  * @modules jdk.incubator.code
 32  * @enablePreview
 33  * @build SwitchExpressionTest
 34  * @build CodeReflectionTester
 35  * @run main CodeReflectionTester SwitchExpressionTest
 36  */
 37 
 38 public class SwitchExpressionTest {
 39 
 40     @Reflect
 41     @IR("""
 42             func @"constantCaseLabelRule" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
 43                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
 44                 %2 : java.type:"java.lang.String" = var.load %1;
 45                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
 46                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
 47                         %5 : java.type:"java.lang.String" = constant @"FOO";
 48                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 49                         yield %6;
 50                     }
 51                     ()java.type:"java.lang.Object" -> {
 52                         %7 : java.type:"java.lang.String" = constant @"FOO";
 53                         yield %7;
 54                     }
 55                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
 56                         %9 : java.type:"java.lang.String" = constant @"BAR";
 57                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 58                         yield %10;
 59                     }
 60                     ()java.type:"java.lang.Object" -> {
 61                         %11 : java.type:"java.lang.String" = constant @"FOO";
 62                         yield %11;
 63                     }
 64                     (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
 65                         %13 : java.type:"java.lang.String" = constant @"BAZ";
 66                         %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 67                         yield %14;
 68                     }
 69                     ()java.type:"java.lang.Object" -> {
 70                         %15 : java.type:"java.lang.String" = constant @"FOO";
 71                         yield %15;
 72                     }
 73                     ()java.type:"boolean" -> {
 74                         %16 : java.type:"boolean" = constant @true;
 75                         yield %16;
 76                     }
 77                     ()java.type:"java.lang.Object" -> {
 78                         %17 : java.type:"java.lang.String" = constant @"";
 79                         yield %17;
 80                     };
 81                 return %3;
 82             };
 83             """)
 84     public static Object constantCaseLabelRule(String r) {
 85         return switch (r) {
 86             case "FOO" -> "FOO";
 87             case "BAR" -> "FOO";
 88             case "BAZ" -> "FOO";
 89             default -> "";
 90         };
 91     }
 92 
 93     @Reflect
 94     @IR("""
 95             func @"constantCaseLabelsRule" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
 96                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
 97                 %2 : java.type:"java.lang.String" = var.load %1;
 98                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
 99                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
100                         %5 : java.type:"boolean" = java.cor
101                             ()java.type:"boolean" -> {
102                                 %6 : java.type:"java.lang.String" = constant @"FOO";
103                                 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
104                                 yield %7;
105                             }
106                             ()java.type:"boolean" -> {
107                                 %8 : java.type:"java.lang.String" = constant @"BAR";
108                                 %9 : java.type:"boolean" = invoke %4 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
109                                 yield %9;
110                             }
111                             ()java.type:"boolean" -> {
112                                 %10 : java.type:"java.lang.String" = constant @"BAZ";
113                                 %11 : java.type:"boolean" = invoke %4 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
114                                 yield %11;
115                             };
116                         yield %5;
117                     }
118                     ()java.type:"java.lang.Object" -> {
119                         %12 : java.type:"java.lang.String" = constant @"FOO";
120                         yield %12;
121                     }
122                     ()java.type:"boolean" -> {
123                         %13 : java.type:"boolean" = constant @true;
124                         yield %13;
125                     }
126                     ()java.type:"java.lang.Object" -> {
127                         %14 : java.type:"java.lang.String" = constant @"";
128                         java.yield %14;
129                     };
130                 return %3;
131             };
132             """)
133     public static Object constantCaseLabelsRule(String r) {
134         return switch (r) {
135             case "FOO", "BAR", "BAZ" -> "FOO";
136             default -> {
137                 yield "";
138             }
139         };
140     }
141 
142     @Reflect
143     @IR("""
144             func @"constantCaseLabelStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
145                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
146                 %2 : java.type:"java.lang.String" = var.load %1;
147                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
148                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
149                         %5 : java.type:"java.lang.String" = constant @"FOO";
150                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
151                         yield %6;
152                     }
153                     ()java.type:"java.lang.Object" -> {
154                         %7 : java.type:"java.lang.String" = constant @"FOO";
155                         java.yield %7;
156                     }
157                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
158                         %9 : java.type:"java.lang.String" = constant @"BAR";
159                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
160                         yield %10;
161                     }
162                     ()java.type:"java.lang.Object" -> {
163                         %11 : java.type:"java.lang.String" = constant @"FOO";
164                         java.yield %11;
165                     }
166                     (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
167                         %13 : java.type:"java.lang.String" = constant @"BAZ";
168                         %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
169                         yield %14;
170                     }
171                     ()java.type:"java.lang.Object" -> {
172                         %15 : java.type:"java.lang.String" = constant @"FOO";
173                         java.yield %15;
174                     }
175                     ()java.type:"boolean" -> {
176                         %16 : java.type:"boolean" = constant @true;
177                         yield %16;
178                     }
179                     ()java.type:"java.lang.Object" -> {
180                         %17 : java.type:"java.lang.String" = constant @"";
181                         java.yield %17;
182                     };
183                 return %3;
184             };
185             """)
186     public static Object constantCaseLabelStatement(String r) {
187         return switch (r) {
188             case "FOO" : yield "FOO";
189             case "BAR" : yield "FOO";
190             case "BAZ" : yield "FOO";
191             default : yield "";
192         };
193     }
194 
195     @Reflect
196     @IR("""
197             func @"constantCaseLabelsStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
198                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
199                 %2 : java.type:"java.lang.String" = var.load %1;
200                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
201                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
202                         %5 : java.type:"boolean" = java.cor
203                             ()java.type:"boolean" -> {
204                                 %6 : java.type:"java.lang.String" = constant @"FOO";
205                                 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
206                                 yield %7;
207                             }
208                             ()java.type:"boolean" -> {
209                                 %8 : java.type:"java.lang.String" = constant @"BAR";
210                                 %9 : java.type:"boolean" = invoke %4 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
211                                 yield %9;
212                             }
213                             ()java.type:"boolean" -> {
214                                 %10 : java.type:"java.lang.String" = constant @"BAZ";
215                                 %11 : java.type:"boolean" = invoke %4 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
216                                 yield %11;
217                             };
218                         yield %5;
219                     }
220                     ()java.type:"java.lang.Object" -> {
221                         %12 : java.type:"java.lang.String" = constant @"FOO";
222                         java.yield %12;
223                     }
224                     ()java.type:"boolean" -> {
225                         %13 : java.type:"boolean" = constant @true;
226                         yield %13;
227                     }
228                     ()java.type:"java.lang.Object" -> {
229                         java.block ()java.type:"void" -> {
230                             %14 : java.type:"java.lang.String" = constant @"";
231                             java.yield %14;
232                         };
233                         unreachable;
234                     };
235                 return %3;
236             };
237             """)
238     public static Object constantCaseLabelsStatement(String r) {
239         return switch (r) {
240             case "FOO", "BAR", "BAZ" : yield "FOO";
241             default : { yield ""; }
242         };
243     }
244 
245     @Reflect
246     @IR("""
247             func @"constantCaseLabelStatements" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
248                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
249                 %2 : java.type:"java.lang.String" = var.load %1;
250                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
251                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
252                         %5 : java.type:"java.lang.String" = constant @"FOO";
253                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
254                         yield %6;
255                     }
256                     ()java.type:"java.lang.Object" -> {
257                         java.block ()java.type:"void" -> {
258                             %7 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
259                             %8 : java.type:"java.lang.String" = constant @"FOO";
260                             invoke %7 %8 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
261                             yield;
262                         };
263                         java.block ()java.type:"void" -> {
264                             %9 : java.type:"java.lang.String" = constant @"FOO";
265                             java.yield %9;
266                         };
267                         unreachable;
268                     }
269                     ()java.type:"boolean" -> {
270                         %10 : java.type:"boolean" = constant @true;
271                         yield %10;
272                     }
273                     ()java.type:"java.lang.Object" -> {
274                         %11 : java.type:"java.lang.String" = constant @"";
275                         java.yield %11;
276                     };
277                 return %3;
278             };
279             """)
280     public static Object constantCaseLabelStatements(String r) {
281         return switch (r) {
282             case "FOO" : {
283                 System.out.println("FOO");
284             }
285             {
286                 yield "FOO";
287             }
288             default : yield "";
289         };
290     }
291 
292     @Reflect
293     @IR("""
294             func @"constantCaseLabelFallthrough" (%0 : java.type:"java.lang.String")java.type:"java.lang.Object" -> {
295                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
296                 %2 : java.type:"java.lang.String" = var.load %1;
297                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
298                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
299                         %5 : java.type:"java.lang.String" = constant @"FOO";
300                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
301                         yield %6;
302                     }
303                     ()java.type:"java.lang.Object" -> {
304                         java.block ()java.type:"void" -> {
305                             %7 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
306                             %8 : java.type:"java.lang.String" = constant @"FOO";
307                             invoke %7 %8 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
308                             yield;
309                         };
310                         java.switch.fallthrough;
311                     }
312                     ()java.type:"boolean" -> {
313                         %9 : java.type:"boolean" = constant @true;
314                         yield %9;
315                     }
316                     ()java.type:"java.lang.Object" -> {
317                         %10 : java.type:"java.lang.String" = constant @"";
318                         java.yield %10;
319                     };
320                 return %3;
321             };
322             """)
323     public static Object constantCaseLabelFallthrough(String r) {
324         return switch (r) {
325             case "FOO" : {
326                 System.out.println("FOO");
327             }
328             default : yield "";
329         };
330     }
331 
332     record A(Number n) {
333     }
334 
335     @Reflect
336     @IR("""
337             func @"patternCaseLabel" (%0 : java.type:"java.lang.Object")java.type:"java.lang.Object" -> {
338                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"r";
339                 %2 : java.type:"java.lang.Object" = var.load %1;
340                 %3 : Var<java.type:"java.lang.Number"> = var @"n";
341                 %4 : Var<java.type:"java.lang.String"> = var @"s";
342                 %5 : java.type:"java.lang.Object" = java.switch.expression %2
343                     (%6 : java.type:"java.lang.Object")java.type:"boolean" -> {
344                         %7 : java.type:"boolean" = pattern.match %6
345                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchExpressionTest$A>" -> {
346                                 %8 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
347                                 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchExpressionTest$A>" = pattern.record %8 @java.ref:"(java.lang.Number n)SwitchExpressionTest$A";
348                                 yield %9;
349                             }
350                             (%10 : java.type:"java.lang.Number")java.type:"void" -> {
351                                 var.store %3 %10;
352                                 yield;
353                             };
354                         yield %7;
355                     }
356                     ()java.type:"java.lang.Object" -> {
357                         %11 : java.type:"java.lang.Number" = var.load %3;
358                         java.yield %11;
359                     }
360                     (%12 : java.type:"java.lang.Object")java.type:"boolean" -> {
361                         %13 : java.type:"boolean" = pattern.match %12
362                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
363                                 %14 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
364                                 yield %14;
365                             }
366                             (%15 : java.type:"java.lang.String")java.type:"void" -> {
367                                 var.store %4 %15;
368                                 yield;
369                             };
370                         yield %13;
371                     }
372                     ()java.type:"java.lang.Object" -> {
373                         %16 : java.type:"java.lang.String" = var.load %4;
374                         java.yield %16;
375                     }
376                     ()java.type:"boolean" -> {
377                         %17 : java.type:"boolean" = constant @true;
378                         yield %17;
379                     }
380                     ()java.type:"java.lang.Object" -> {
381                         %18 : java.type:"java.lang.String" = constant @"";
382                         java.yield %18;
383                     };
384                 return %5;
385             };
386             """)
387     public static Object patternCaseLabel(Object r) {
388         return switch (r) {
389             case A(Number n) -> {
390                 yield n;
391             }
392             case String s -> {
393                 yield s;
394             }
395             default -> {
396                 yield "";
397             }
398         };
399     }
400 
401     @Reflect
402     @IR("""
403             func @"patternCaseLabelGuard" (%0 : java.type:"java.lang.Object")java.type:"java.lang.Object" -> {
404                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"r";
405                 %2 : java.type:"java.lang.Object" = var.load %1;
406                 %3 : Var<java.type:"java.lang.Number"> = var @"n";
407                 %4 : Var<java.type:"java.lang.String"> = var @"s";
408                 %5 : Var<java.type:"java.lang.String"> = var @"s";
409                 %6 : java.type:"java.lang.Object" = java.switch.expression %2
410                     (%7 : java.type:"java.lang.Object")java.type:"boolean" -> {
411                         %8 : java.type:"boolean" = pattern.match %7
412                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchExpressionTest$A>" -> {
413                                 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
414                                 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchExpressionTest$A>" = pattern.record %9 @java.ref:"(java.lang.Number n)SwitchExpressionTest$A";
415                                 yield %10;
416                             }
417                             (%11 : java.type:"java.lang.Number")java.type:"void" -> {
418                                 var.store %3 %11;
419                                 yield;
420                             };
421                         yield %8;
422                     }
423                     ()java.type:"java.lang.Object" -> {
424                         %12 : java.type:"java.lang.Number" = var.load %3;
425                         java.yield %12;
426                     }
427                     (%13 : java.type:"java.lang.Object")java.type:"boolean" -> {
428                         %14 : java.type:"boolean" = java.cand
429                             ()java.type:"boolean" -> {
430                                 %15 : java.type:"boolean" = pattern.match %13
431                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
432                                         %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
433                                         yield %16;
434                                     }
435                                     (%17 : java.type:"java.lang.String")java.type:"void" -> {
436                                         var.store %4 %17;
437                                         yield;
438                                     };
439                                 yield %15;
440                             }
441                             ()java.type:"boolean" -> {
442                                 %18 : java.type:"java.lang.String" = var.load %4;
443                                 %19 : java.type:"int" = invoke %18 @java.ref:"java.lang.String::length():int";
444                                 %20 : java.type:"int" = constant @5;
445                                 %21 : java.type:"boolean" = lt %19 %20;
446                                 yield %21;
447                             };
448                         yield %14;
449                     }
450                     ()java.type:"java.lang.Object" -> {
451                         %22 : java.type:"java.lang.String" = var.load %4;
452                         java.yield %22;
453                     }
454                     (%23 : java.type:"java.lang.Object")java.type:"boolean" -> {
455                         %24 : java.type:"boolean" = java.cand
456                             ()java.type:"boolean" -> {
457                                 %25 : java.type:"boolean" = pattern.match %23
458                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
459                                         %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
460                                         yield %26;
461                                     }
462                                     (%27 : java.type:"java.lang.String")java.type:"void" -> {
463                                         var.store %5 %27;
464                                         yield;
465                                     };
466                                 yield %25;
467                             }
468                             ()java.type:"boolean" -> {
469                                 %28 : java.type:"java.lang.String" = var.load %5;
470                                 %29 : java.type:"int" = invoke %28 @java.ref:"java.lang.String::length():int";
471                                 %30 : java.type:"int" = constant @10;
472                                 %31 : java.type:"boolean" = lt %29 %30;
473                                 yield %31;
474                             };
475                         yield %24;
476                     }
477                     ()java.type:"java.lang.Object" -> {
478                         %32 : java.type:"java.lang.String" = var.load %5;
479                         java.yield %32;
480                     }
481                     ()java.type:"boolean" -> {
482                         %33 : java.type:"boolean" = constant @true;
483                         yield %33;
484                     }
485                     ()java.type:"java.lang.Object" -> {
486                         %34 : java.type:"java.lang.String" = constant @"";
487                         java.yield %34;
488                     };
489                 return %6;
490             };
491             """)
492     public static Object patternCaseLabelGuard(Object r) {
493         return switch (r) {
494             case A(Number n) -> {
495                 yield n;
496             }
497             case String s when s.length() < 5 -> {
498                 yield s;
499             }
500             case String s when s.length() < 10 -> {
501                 yield s;
502             }
503             default -> {
504                 yield "";
505             }
506         };
507     }
508 
509     @IR("""
510             func @"caseBoxedGuard" (%0 : java.type:"java.lang.Object", %1 : java.type:"java.lang.Boolean")java.type:"java.lang.String" -> {
511                 %2 : Var<java.type:"java.lang.Object"> = var %0 @"o";
512                 %3 : Var<java.type:"java.lang.Boolean"> = var %1 @"B";
513                 %4 : java.type:"java.lang.Object" = var.load %2;
514                 %5 : Var<java.type:"java.lang.Object"> = var;
515                 %6 : java.type:"java.lang.String" = java.switch.expression %4
516                     (%7 : java.type:"java.lang.Object")java.type:"boolean" -> {
517                         %8 : java.type:"boolean" = java.cand
518                             ()java.type:"boolean" -> {
519                                 %9 : java.type:"boolean" = pattern.match %7
520                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
521                                         %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type;
522                                         yield %10;
523                                     }
524                                     (%11 : java.type:"java.lang.Object")java.type:"void" -> {
525                                         var.store %5 %11;
526                                         yield;
527                                     };
528                                 yield %9;
529                             }
530                             ()java.type:"boolean" -> {
531                                 %12 : java.type:"java.lang.Boolean" = var.load %3;
532                                 %13 : java.type:"boolean" = invoke %12 @java.ref:"java.lang.Boolean::booleanValue():boolean";
533                                 yield %13;
534                             };
535                         yield %8;
536                     }
537                     ()java.type:"java.lang.String" -> {
538                         %14 : java.type:"java.lang.String" = constant @"match";
539                         yield %14;
540                     }
541                     ()java.type:"boolean" -> {
542                         %15 : java.type:"boolean" = constant @true;
543                         yield %15;
544                     }
545                     ()java.type:"java.lang.String" -> {
546                         %16 : java.type:"java.lang.String" = constant @"no match";
547                         yield %16;
548                     };
549                 return %6;
550             };
551             """)
552     @Reflect
553     private static String caseBoxedGuard(Object o, Boolean B) {
554         return switch (o) {
555             case Object _ when B -> "match";
556             default -> "no match";
557         };
558     }
559 
560     @IR("""
561             func @"statementGroupsYieldingBoolean" (%0 : java.type:"int")java.type:"int" -> {
562                 %1 : Var<java.type:"int"> = var %0 @"value";
563                 java.if
564                     ()java.type:"boolean" -> {
565                         %2 : java.type:"int" = var.load %1;
566                         %3 : java.type:"boolean" = java.switch.expression %2
567                             (%4 : java.type:"int")java.type:"boolean" -> {
568                                 %5 : java.type:"int" = constant @0;
569                                 %6 : java.type:"boolean" = eq %4 %5;
570                                 yield %6;
571                             }
572                             ()java.type:"boolean" -> {
573                                 %7 : java.type:"boolean" = constant @false;
574                                 java.yield %7;
575                             }
576                             ()java.type:"boolean" -> {
577                                 %8 : java.type:"boolean" = constant @true;
578                                 yield %8;
579                             }
580                             ()java.type:"boolean" -> {
581                                 %9 : java.type:"int" = var.load %1;
582                                 %10 : java.type:"int" = constant @0;
583                                 %11 : java.type:"boolean" = gt %9 %10;
584                                 java.yield %11;
585                             };
586                         yield %3;
587                     }
588                     ()java.type:"void" -> {
589                         %12 : java.type:"int" = constant @1;
590                         return %12;
591                     };
592                 %13 : java.type:"int" = constant @0;
593                 return %13;
594             };
595             """)
596     @Reflect
597     private static int statementGroupsYieldingBoolean(int value) {
598         if (switch (value) {
599             case 0: yield false;
600             default: yield value > 0;}) {
601             return 1;
602         }
603         return 0;
604     }
605 
606     @IR("""
607             func @"statementGroupsYieldingObjects" (%0 : java.type:"int")java.type:"void" -> {
608                 %1 : Var<java.type:"int"> = var %0 @"value";
609                 %2 : java.type:"int" = var.load %1;
610                 %3 : java.type:"java.lang.Object" = java.switch.expression %2
611                     (%4 : java.type:"int")java.type:"boolean" -> {
612                         %5 : java.type:"int" = constant @0;
613                         %6 : java.type:"boolean" = eq %4 %5;
614                         yield %6;
615                     }
616                     ()java.type:"java.lang.Object" -> {
617                         %7 : java.type:"int" = constant @2147483647;
618                         %8 : java.type:"java.lang.Integer" = invoke %7 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
619                         java.yield %8;
620                     }
621                     ()java.type:"boolean" -> {
622                         %9 : java.type:"boolean" = constant @true;
623                         yield %9;
624                     }
625                     ()java.type:"java.lang.Object" -> {
626                         %10 : java.type:"java.lang.String" = constant @"default";
627                         java.yield %10;
628                     };
629                 %11 : Var<java.type:"java.lang.Object"> = var %3 @"r";
630                 return;
631             };
632             """)
633     @Reflect
634     private static void statementGroupsYieldingObjects(int value) {
635         Object r = switch (value) {
636             case 0: yield Integer.MAX_VALUE;
637             default: yield "default";
638         };
639     }
640 }