1 import java.lang.runtime.CodeReflection; 2 import java.util.Collection; 3 import java.util.RandomAccess; 4 import java.util.Stack; 5 6 /* 7 * @test 8 * @build SwitchStatementTest 9 * @build CodeReflectionTester 10 * @run main CodeReflectionTester SwitchStatementTest 11 */ 12 public class SwitchStatementTest { 13 14 @IR(""" 15 func @"caseConstantRuleExpression" (%0 : java.lang.String)java.lang.String -> { 16 %1 : Var<java.lang.String> = var %0 @"r"; 17 %2 : java.lang.String = constant @""; 18 %3 : Var<java.lang.String> = var %2 @"s"; 19 %4 : java.lang.String = var.load %1; 20 java.switch.statement %4 21 (%5 : java.lang.String)boolean -> { 22 %6 : java.lang.String = constant @"FOO"; 23 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 24 yield %7; 25 } 26 ()void -> { 27 %8 : java.lang.String = var.load %3; 28 %9 : java.lang.String = constant @"BAR"; 29 %10 : java.lang.String = concat %8 %9; 30 var.store %3 %10; 31 yield; 32 } 33 (%11 : java.lang.String)boolean -> { 34 %12 : java.lang.String = constant @"BAR"; 35 %13 : boolean = invoke %11 %12 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 36 yield %13; 37 } 38 ()void -> { 39 %14 : java.lang.String = var.load %3; 40 %15 : java.lang.String = constant @"BAZ"; 41 %16 : java.lang.String = concat %14 %15; 42 var.store %3 %16; 43 yield; 44 } 45 (%17 : java.lang.String)boolean -> { 46 %18 : java.lang.String = constant @"BAZ"; 47 %19 : boolean = invoke %17 %18 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 48 yield %19; 49 } 50 ()void -> { 51 %20 : java.lang.String = var.load %3; 52 %21 : java.lang.String = constant @"FOO"; 53 %22 : java.lang.String = concat %20 %21; 54 var.store %3 %22; 55 yield; 56 } 57 ()boolean -> { 58 %26 : boolean = constant @"true"; 59 yield %26; 60 } 61 ()void -> { 62 %23 : java.lang.String = var.load %3; 63 %24 : java.lang.String = constant @"else"; 64 %25 : java.lang.String = concat %23 %24; 65 var.store %3 %25; 66 yield; 67 }; 68 %26 : java.lang.String = var.load %3; 69 return %26; 70 }; 71 """) 72 @CodeReflection 73 public static String caseConstantRuleExpression(String r) { 74 String s = ""; 75 switch (r) { 76 case "FOO" -> s += "BAR"; 77 case "BAR" -> s += "BAZ"; 78 case "BAZ" -> s += "FOO"; 79 default -> s += "else"; 80 } 81 return s; 82 } 83 84 @IR(""" 85 func @"caseConstantRuleBlock" (%0 : java.lang.String)java.lang.String -> { 86 %1 : Var<java.lang.String> = var %0 @"r"; 87 %2 : java.lang.String = constant @""; 88 %3 : Var<java.lang.String> = var %2 @"s"; 89 %4 : java.lang.String = var.load %1; 90 java.switch.statement %4 91 (%5 : java.lang.String)boolean -> { 92 %6 : java.lang.String = constant @"FOO"; 93 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 94 yield %7; 95 } 96 ()void -> { 97 %8 : java.lang.String = var.load %3; 98 %9 : java.lang.String = constant @"BAR"; 99 %10 : java.lang.String = concat %8 %9; 100 var.store %3 %10; 101 yield; 102 } 103 (%11 : java.lang.String)boolean -> { 104 %12 : java.lang.String = constant @"BAR"; 105 %13 : boolean = invoke %11 %12 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 106 yield %13; 107 } 108 ()void -> { 109 %14 : java.lang.String = var.load %3; 110 %15 : java.lang.String = constant @"BAZ"; 111 %16 : java.lang.String = concat %14 %15; 112 var.store %3 %16; 113 yield; 114 } 115 (%17 : java.lang.String)boolean -> { 116 %18 : java.lang.String = constant @"BAZ"; 117 %19 : boolean = invoke %17 %18 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 118 yield %19; 119 } 120 ()void -> { 121 %20 : java.lang.String = var.load %3; 122 %21 : java.lang.String = constant @"FOO"; 123 %22 : java.lang.String = concat %20 %21; 124 var.store %3 %22; 125 yield; 126 } 127 ()boolean -> { 128 %26 : boolean = constant @"true"; 129 yield %26; 130 } 131 ()void -> { 132 %23 : java.lang.String = var.load %3; 133 %24 : java.lang.String = constant @"else"; 134 %25 : java.lang.String = concat %23 %24; 135 var.store %3 %25; 136 yield; 137 }; 138 %26 : java.lang.String = var.load %3; 139 return %26; 140 }; 141 """) 142 @CodeReflection 143 public static String caseConstantRuleBlock(String r) { 144 String s = ""; 145 switch (r) { 146 case "FOO" -> { 147 s += "BAR"; 148 } 149 case "BAR" -> { 150 s += "BAZ"; 151 } 152 case "BAZ" -> { 153 s += "FOO"; 154 } 155 default -> { 156 s += "else"; 157 } 158 } 159 return s; 160 } 161 162 @IR(""" 163 func @"caseConstantStatement" (%0 : java.lang.String)java.lang.String -> { 164 %1 : Var<java.lang.String> = var %0 @"s"; 165 %2 : java.lang.String = constant @""; 166 %3 : Var<java.lang.String> = var %2 @"r"; 167 %4 : java.lang.String = var.load %1; 168 java.switch.statement %4 169 (%5 : java.lang.String)boolean -> { 170 %6 : java.lang.String = constant @"FOO"; 171 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 172 yield %7; 173 } 174 ()void -> { 175 %8 : java.lang.String = var.load %3; 176 %9 : java.lang.String = constant @"BAR"; 177 %10 : java.lang.String = concat %8 %9; 178 var.store %3 %10; 179 java.break; 180 } 181 (%11 : java.lang.String)boolean -> { 182 %12 : java.lang.String = constant @"BAR"; 183 %13 : boolean = invoke %11 %12 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 184 yield %13; 185 } 186 ()void -> { 187 %14 : java.lang.String = var.load %3; 188 %15 : java.lang.String = constant @"BAZ"; 189 %16 : java.lang.String = concat %14 %15; 190 var.store %3 %16; 191 java.break; 192 } 193 (%17 : java.lang.String)boolean -> { 194 %18 : java.lang.String = constant @"BAZ"; 195 %19 : boolean = invoke %17 %18 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 196 yield %19; 197 } 198 ()void -> { 199 %20 : java.lang.String = var.load %3; 200 %21 : java.lang.String = constant @"FOO"; 201 %22 : java.lang.String = concat %20 %21; 202 var.store %3 %22; 203 java.break; 204 } 205 ()boolean -> { 206 %26 : boolean = constant @"true"; 207 yield %26; 208 } 209 ()void -> { 210 %23 : java.lang.String = var.load %3; 211 %24 : java.lang.String = constant @"else"; 212 %25 : java.lang.String = concat %23 %24; 213 var.store %3 %25; 214 yield; 215 }; 216 %26 : java.lang.String = var.load %3; 217 return %26; 218 }; 219 """) 220 @CodeReflection 221 private static String caseConstantStatement(String s) { 222 String r = ""; 223 switch (s) { 224 case "FOO": 225 r += "BAR"; 226 break; 227 case "BAR": 228 r += "BAZ"; 229 break; 230 case "BAZ": 231 r += "FOO"; 232 break; 233 default: 234 r += "else"; 235 } 236 return r; 237 } 238 239 @IR(""" 240 func @"caseConstantMultiLabels" (%0 : char)java.lang.String -> { 241 %1 : Var<char> = var %0 @"c"; 242 %2 : java.lang.String = constant @""; 243 %3 : Var<java.lang.String> = var %2 @"r"; 244 %4 : char = var.load %1; 245 %5 : char = invoke %4 @"java.lang.Character::toLowerCase(char)char"; 246 java.switch.statement %5 247 (%6 : char)boolean -> { 248 %7 : boolean = java.cor 249 ()boolean -> { 250 %8 : char = constant @"a"; 251 %9 : boolean = eq %6 %8; 252 yield %9; 253 } 254 ()boolean -> { 255 %10 : char = constant @"e"; 256 %11 : boolean = eq %6 %10; 257 yield %11; 258 } 259 ()boolean -> { 260 %12 : char = constant @"i"; 261 %13 : boolean = eq %6 %12; 262 yield %13; 263 } 264 ()boolean -> { 265 %14 : char = constant @"o"; 266 %15 : boolean = eq %6 %14; 267 yield %15; 268 } 269 ()boolean -> { 270 %16 : char = constant @"u"; 271 %17 : boolean = eq %6 %16; 272 yield %17; 273 }; 274 yield %7; 275 } 276 ()void -> { 277 %18 : java.lang.String = var.load %3; 278 %19 : java.lang.String = constant @"vowel"; 279 %20 : java.lang.String = concat %18 %19; 280 var.store %3 %20; 281 java.break; 282 } 283 ()boolean -> { 284 %24 : boolean = constant @"true"; 285 yield %24; 286 } 287 ()void -> { 288 %21 : java.lang.String = var.load %3; 289 %22 : java.lang.String = constant @"consonant"; 290 %23 : java.lang.String = concat %21 %22; 291 var.store %3 %23; 292 yield; 293 }; 294 %24 : java.lang.String = var.load %3; 295 return %24; 296 }; 297 """) 298 @CodeReflection 299 private static String caseConstantMultiLabels(char c) { 300 String r = ""; 301 switch (Character.toLowerCase(c)) { 302 case 'a', 'e', 'i', 'o', 'u': 303 r += "vowel"; 304 break; 305 default: 306 r += "consonant"; 307 } 308 return r; 309 } 310 311 @IR(""" 312 func @"caseConstantThrow" (%0 : java.lang.Integer)java.lang.String -> { 313 %1 : Var<java.lang.Integer> = var %0 @"i"; 314 %2 : java.lang.String = constant @""; 315 %3 : Var<java.lang.String> = var %2 @"r"; 316 %4 : java.lang.Integer = var.load %1; 317 java.switch.statement %4 318 (%5 : java.lang.Integer)boolean -> { 319 %6 : int = constant @"8"; 320 %7 : java.lang.Integer = invoke %6 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 321 %8 : boolean = invoke %5 %7 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 322 yield %8; 323 } 324 ()void -> { 325 %9 : java.lang.IllegalArgumentException = new @"func<java.lang.IllegalArgumentException>"; 326 throw %9; 327 } 328 (%10 : java.lang.Integer)boolean -> { 329 %11 : int = constant @"9"; 330 %12 : java.lang.Integer = invoke %11 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 331 %13 : boolean = invoke %10 %12 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 332 yield %13; 333 } 334 ()void -> { 335 %14 : java.lang.String = var.load %3; 336 %15 : java.lang.String = constant @"Nine"; 337 %16 : java.lang.String = concat %14 %15; 338 var.store %3 %16; 339 yield; 340 } 341 ()boolean -> { 342 %17 : boolean = constant @"true"; 343 yield %17; 344 } 345 ()void -> { 346 %17 : java.lang.String = var.load %3; 347 %18 : java.lang.String = constant @"An integer"; 348 %19 : java.lang.String = concat %17 %18; 349 var.store %3 %19; 350 yield; 351 }; 352 %20 : java.lang.String = var.load %3; 353 return %20; 354 }; 355 """) 356 @CodeReflection 357 private static String caseConstantThrow(Integer i) { 358 String r = ""; 359 switch (i) { 360 case 8 -> throw new IllegalArgumentException(); 361 case 9 -> r += "Nine"; 362 default -> r += "An integer"; 363 } 364 return r; 365 } 366 367 @IR(""" 368 func @"caseConstantNullLabel" (%0 : java.lang.String)java.lang.String -> { 369 %1 : Var<java.lang.String> = var %0 @"s"; 370 %2 : java.lang.String = constant @""; 371 %3 : Var<java.lang.String> = var %2 @"r"; 372 %4 : java.lang.String = var.load %1; 373 java.switch.statement %4 374 (%5 : java.lang.String)boolean -> { 375 %6 : java.lang.Object = constant @null; 376 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 377 yield %7; 378 } 379 ()void -> { 380 %8 : java.lang.String = var.load %3; 381 %9 : java.lang.String = constant @"null"; 382 %10 : java.lang.String = concat %8 %9; 383 var.store %3 %10; 384 yield; 385 } 386 ()boolean -> { 387 %17 : boolean = constant @"true"; 388 yield %17; 389 } 390 ()void -> { 391 %11 : java.lang.String = var.load %3; 392 %12 : java.lang.String = constant @"non null"; 393 %13 : java.lang.String = concat %11 %12; 394 var.store %3 %13; 395 yield; 396 }; 397 %14 : java.lang.String = var.load %3; 398 return %14; 399 }; 400 """) 401 @CodeReflection 402 private static String caseConstantNullLabel(String s) { 403 String r = ""; 404 switch (s) { 405 case null -> r += "null"; 406 default -> r += "non null"; 407 } 408 return r; 409 } 410 411 // @CodeReflection 412 // @@@ not supported 413 private static String caseConstantNullAndDefault(String s) { 414 String r = ""; 415 switch (s) { 416 case "abc" -> r += "alphabet"; 417 case null, default -> r += "null or default"; 418 } 419 return r; 420 } 421 422 @IR(""" 423 func @"caseConstantFallThrough" (%0 : char)java.lang.String -> { 424 %1 : Var<char> = var %0 @"c"; 425 %2 : java.lang.String = constant @""; 426 %3 : Var<java.lang.String> = var %2 @"r"; 427 %4 : char = var.load %1; 428 java.switch.statement %4 429 (%5 : char)boolean -> { 430 %6 : char = constant @"A"; 431 %7 : boolean = eq %5 %6; 432 yield %7; 433 } 434 ()void -> { 435 java.switch.fallthrough; 436 } 437 (%8 : char)boolean -> { 438 %9 : char = constant @"B"; 439 %10 : boolean = eq %8 %9; 440 yield %10; 441 } 442 ()void -> { 443 %11 : java.lang.String = var.load %3; 444 %12 : java.lang.String = constant @"A or B"; 445 %13 : java.lang.String = concat %11 %12; 446 var.store %3 %13; 447 java.break; 448 } 449 ()boolean -> { 450 %17 : boolean = constant @"true"; 451 yield %17; 452 } 453 ()void -> { 454 %14 : java.lang.String = var.load %3; 455 %15 : java.lang.String = constant @"Neither A nor B"; 456 %16 : java.lang.String = concat %14 %15; 457 var.store %3 %16; 458 yield; 459 }; 460 %17 : java.lang.String = var.load %3; 461 return %17; 462 }; 463 """) 464 @CodeReflection 465 private static String caseConstantFallThrough(char c) { 466 String r = ""; 467 switch (c) { 468 case 'A': 469 case 'B': 470 r += "A or B"; 471 break; 472 default: 473 r += "Neither A nor B"; 474 } 475 return r; 476 } 477 478 enum Day { 479 MON, TUE, WED, THU, FRI, SAT, SUN 480 } 481 @IR(""" 482 func @"caseConstantEnum" (%0 : SwitchStatementTest$Day)java.lang.String -> { 483 %1 : Var<SwitchStatementTest$Day> = var %0 @"d"; 484 %2 : java.lang.String = constant @""; 485 %3 : Var<java.lang.String> = var %2 @"r"; 486 %4 : SwitchStatementTest$Day = var.load %1; 487 java.switch.statement %4 488 (%5 : SwitchStatementTest$Day)boolean -> { 489 %6 : boolean = java.cor 490 ()boolean -> { 491 %7 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::MON()SwitchStatementTest$Day"; 492 %8 : boolean = invoke %5 %7 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 493 yield %8; 494 } 495 ()boolean -> { 496 %9 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::FRI()SwitchStatementTest$Day"; 497 %10 : boolean = invoke %5 %9 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 498 yield %10; 499 } 500 ()boolean -> { 501 %11 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::SUN()SwitchStatementTest$Day"; 502 %12 : boolean = invoke %5 %11 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 503 yield %12; 504 }; 505 yield %6; 506 } 507 ()void -> { 508 %13 : java.lang.String = var.load %3; 509 %14 : int = constant @"6"; 510 %15 : java.lang.Integer = invoke %14 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 511 %16 : java.lang.String = concat %13 %15; 512 var.store %3 %16; 513 yield; 514 } 515 (%17 : SwitchStatementTest$Day)boolean -> { 516 %18 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::TUE()SwitchStatementTest$Day"; 517 %19 : boolean = invoke %17 %18 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 518 yield %19; 519 } 520 ()void -> { 521 %20 : java.lang.String = var.load %3; 522 %21 : int = constant @"7"; 523 %22 : java.lang.Integer = invoke %21 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 524 %23 : java.lang.String = concat %20 %22; 525 var.store %3 %23; 526 yield; 527 } 528 (%24 : SwitchStatementTest$Day)boolean -> { 529 %25 : boolean = java.cor 530 ()boolean -> { 531 %26 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::THU()SwitchStatementTest$Day"; 532 %27 : boolean = invoke %24 %26 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 533 yield %27; 534 } 535 ()boolean -> { 536 %28 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::SAT()SwitchStatementTest$Day"; 537 %29 : boolean = invoke %24 %28 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 538 yield %29; 539 }; 540 yield %25; 541 } 542 ()void -> { 543 %30 : java.lang.String = var.load %3; 544 %31 : int = constant @"8"; 545 %32 : java.lang.Integer = invoke %31 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 546 %33 : java.lang.String = concat %30 %32; 547 var.store %3 %33; 548 yield; 549 } 550 (%34 : SwitchStatementTest$Day)boolean -> { 551 %35 : SwitchStatementTest$Day = field.load @"SwitchStatementTest$Day::WED()SwitchStatementTest$Day"; 552 %36 : boolean = invoke %34 %35 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 553 yield %36; 554 } 555 ()void -> { 556 %37 : java.lang.String = var.load %3; 557 %38 : int = constant @"9"; 558 %39 : java.lang.Integer = invoke %38 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 559 %40 : java.lang.String = concat %37 %39; 560 var.store %3 %40; 561 yield; 562 }; 563 %41 : java.lang.String = var.load %3; 564 return %41; 565 }; 566 """) 567 @CodeReflection 568 private static String caseConstantEnum(Day d) { 569 String r = ""; 570 switch (d) { 571 // @@@ concat of String and int is modeled as: add str Integer 572 case MON, FRI, SUN -> r += 6; 573 case TUE -> r += 7; 574 case THU, SAT -> r += 8; 575 case WED -> r += 9; 576 } 577 return r; 578 } 579 580 static class Constants { 581 static final int c1 = 12; 582 } 583 @IR(""" 584 func @"caseConstantOtherKindsOfExpr" (%0 : int)java.lang.String -> { 585 %1 : Var<int> = var %0 @"i"; 586 %2 : java.lang.String = constant @""; 587 %3 : Var<java.lang.String> = var %2 @"r"; 588 %4 : int = constant @"11"; 589 %5 : Var<int> = var %4 @"eleven"; 590 %6 : int = var.load %1; 591 java.switch.statement %6 592 (%7 : int)boolean -> { 593 %8 : int = constant @"1"; 594 %9 : int = constant @"15"; 595 %10 : int = and %8 %9; 596 %11 : boolean = eq %7 %10; 597 yield %11; 598 } 599 ()void -> { 600 %12 : java.lang.String = var.load %3; 601 %13 : int = constant @"1"; 602 %14 : java.lang.Integer = invoke %13 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 603 %15 : java.lang.String = concat %12 %14; 604 var.store %3 %15; 605 yield; 606 } 607 (%16 : int)boolean -> { 608 %17 : int = constant @"4"; 609 %18 : int = constant @"1"; 610 %19 : int = ashr %17 %18; 611 %20 : boolean = eq %16 %19; 612 yield %20; 613 } 614 ()void -> { 615 %21 : java.lang.String = var.load %3; 616 %22 : java.lang.String = constant @"2"; 617 %23 : java.lang.String = concat %21 %22; 618 var.store %3 %23; 619 yield; 620 } 621 (%24 : int)boolean -> { 622 %25 : long = constant @"3"; 623 %26 : int = conv %25; 624 %27 : boolean = eq %24 %26; 625 yield %27; 626 } 627 ()void -> { 628 %28 : java.lang.String = var.load %3; 629 %29 : int = constant @"3"; 630 %30 : java.lang.Integer = invoke %29 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 631 %31 : java.lang.String = concat %28 %30; 632 var.store %3 %31; 633 yield; 634 } 635 (%32 : int)boolean -> { 636 %33 : int = constant @"2"; 637 %34 : int = constant @"1"; 638 %35 : int = lshl %33 %34; 639 %36 : boolean = eq %32 %35; 640 yield %36; 641 } 642 ()void -> { 643 %37 : java.lang.String = var.load %3; 644 %38 : int = constant @"4"; 645 %39 : java.lang.Integer = invoke %38 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 646 %40 : java.lang.String = concat %37 %39; 647 var.store %3 %40; 648 yield; 649 } 650 (%41 : int)boolean -> { 651 %42 : int = constant @"10"; 652 %43 : int = constant @"2"; 653 %44 : int = div %42 %43; 654 %45 : boolean = eq %41 %44; 655 yield %45; 656 } 657 ()void -> { 658 %46 : java.lang.String = var.load %3; 659 %47 : int = constant @"5"; 660 %48 : java.lang.Integer = invoke %47 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 661 %49 : java.lang.String = concat %46 %48; 662 var.store %3 %49; 663 yield; 664 } 665 (%50 : int)boolean -> { 666 %51 : int = constant @"12"; 667 %52 : int = constant @"6"; 668 %53 : int = sub %51 %52; 669 %54 : boolean = eq %50 %53; 670 yield %54; 671 } 672 ()void -> { 673 %55 : java.lang.String = var.load %3; 674 %56 : int = constant @"6"; 675 %57 : java.lang.Integer = invoke %56 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 676 %58 : java.lang.String = concat %55 %57; 677 var.store %3 %58; 678 yield; 679 } 680 (%59 : int)boolean -> { 681 %60 : int = constant @"3"; 682 %61 : int = constant @"4"; 683 %62 : int = add %60 %61; 684 %63 : boolean = eq %59 %62; 685 yield %63; 686 } 687 ()void -> { 688 %64 : java.lang.String = var.load %3; 689 %65 : int = constant @"7"; 690 %66 : java.lang.Integer = invoke %65 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 691 %67 : java.lang.String = concat %64 %66; 692 var.store %3 %67; 693 yield; 694 } 695 (%68 : int)boolean -> { 696 %69 : int = constant @"2"; 697 %70 : int = constant @"2"; 698 %71 : int = mul %69 %70; 699 %72 : int = constant @"2"; 700 %73 : int = mul %71 %72; 701 %74 : boolean = eq %68 %73; 702 yield %74; 703 } 704 ()void -> { 705 %75 : java.lang.String = var.load %3; 706 %76 : int = constant @"8"; 707 %77 : java.lang.Integer = invoke %76 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 708 %78 : java.lang.String = concat %75 %77; 709 var.store %3 %78; 710 yield; 711 } 712 (%79 : int)boolean -> { 713 %80 : int = constant @"8"; 714 %81 : int = constant @"1"; 715 %82 : int = or %80 %81; 716 %83 : boolean = eq %79 %82; 717 yield %83; 718 } 719 ()void -> { 720 %84 : java.lang.String = var.load %3; 721 %85 : int = constant @"9"; 722 %86 : java.lang.Integer = invoke %85 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 723 %87 : java.lang.String = concat %84 %86; 724 var.store %3 %87; 725 yield; 726 } 727 (%88 : int)boolean -> { 728 %89 : int = constant @"10"; 729 %90 : boolean = eq %88 %89; 730 yield %90; 731 } 732 ()void -> { 733 %91 : java.lang.String = var.load %3; 734 %92 : int = constant @"10"; 735 %93 : java.lang.Integer = invoke %92 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 736 %94 : java.lang.String = concat %91 %93; 737 var.store %3 %94; 738 yield; 739 } 740 (%95 : int)boolean -> { 741 %96 : int = var.load %5; 742 %97 : boolean = eq %95 %96; 743 yield %97; 744 } 745 ()void -> { 746 %98 : java.lang.String = var.load %3; 747 %99 : int = constant @"11"; 748 %100 : java.lang.Integer = invoke %99 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 749 %101 : java.lang.String = concat %98 %100; 750 var.store %3 %101; 751 yield; 752 } 753 (%102 : int)boolean -> { 754 %103 : int = field.load @"SwitchStatementTest$Constants::c1()int"; 755 %104 : boolean = eq %102 %103; 756 yield %104; 757 } 758 ()void -> { 759 %105 : java.lang.String = var.load %3; 760 %106 : int = field.load @"SwitchStatementTest$Constants::c1()int"; 761 %107 : java.lang.Integer = invoke %106 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 762 %108 : java.lang.String = concat %105 %107; 763 var.store %3 %108; 764 yield; 765 } 766 (%109 : int)boolean -> { 767 %110 : int = java.cexpression 768 ()boolean -> { 769 %111 : int = constant @"1"; 770 %112 : int = constant @"0"; 771 %113 : boolean = gt %111 %112; 772 yield %113; 773 } 774 ()int -> { 775 %114 : int = constant @"13"; 776 yield %114; 777 } 778 ()int -> { 779 %115 : int = constant @"133"; 780 yield %115; 781 }; 782 %116 : boolean = eq %109 %110; 783 yield %116; 784 } 785 ()void -> { 786 %117 : java.lang.String = var.load %3; 787 %118 : int = constant @"13"; 788 %119 : java.lang.Integer = invoke %118 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 789 %120 : java.lang.String = concat %117 %119; 790 var.store %3 %120; 791 yield; 792 } 793 ()boolean -> { 794 %17 : boolean = constant @"true"; 795 yield %17; 796 } 797 ()void -> { 798 %121 : java.lang.String = var.load %3; 799 %122 : java.lang.String = constant @"an int"; 800 %123 : java.lang.String = concat %121 %122; 801 var.store %3 %123; 802 yield; 803 }; 804 %124 : java.lang.String = var.load %3; 805 return %124; 806 }; 807 """) 808 @CodeReflection 809 private static String caseConstantOtherKindsOfExpr(int i) { 810 String r = ""; 811 final int eleven = 11; 812 switch (i) { 813 case 1 & 0xF -> r += 1; 814 case 4>>1 -> r += "2"; 815 case (int) 3L -> r += 3; 816 case 2<<1 -> r += 4; 817 case 10 / 2 -> r += 5; 818 case 12 - 6 -> r += 6; 819 case 3 + 4 -> r += 7; 820 case 2 * 2 * 2 -> r += 8; 821 case 8 | 1 -> r += 9; 822 case (10) -> r += 10; 823 case eleven -> r += 11; 824 case Constants.c1 -> r += Constants.c1; 825 case 1 > 0 ? 13 : 133 -> r += 13; 826 default -> r += "an int"; 827 } 828 return r; 829 } 830 831 @IR(""" 832 func @"caseConstantConv" (%0 : short)java.lang.String -> { 833 %1 : Var<short> = var %0 @"a"; 834 %2 : int = constant @"1"; 835 %3 : short = conv %2; 836 %4 : Var<short> = var %3 @"s"; 837 %5 : int = constant @"2"; 838 %6 : byte = conv %5; 839 %7 : Var<byte> = var %6 @"b"; 840 %8 : java.lang.String = constant @""; 841 %9 : Var<java.lang.String> = var %8 @"r"; 842 %10 : short = var.load %1; 843 java.switch.statement %10 844 (%11 : short)boolean -> { 845 %12 : short = var.load %4; 846 %13 : boolean = eq %11 %12; 847 yield %13; 848 } 849 ()void -> { 850 %14 : java.lang.String = var.load %9; 851 %15 : java.lang.String = constant @"one"; 852 %16 : java.lang.String = concat %14 %15; 853 var.store %9 %16; 854 yield; 855 } 856 (%17 : short)boolean -> { 857 %18 : byte = var.load %7; 858 %19 : short = conv %18; 859 %20 : boolean = eq %17 %19; 860 yield %20; 861 } 862 ()void -> { 863 %21 : java.lang.String = var.load %9; 864 %22 : java.lang.String = constant @"two"; 865 %23 : java.lang.String = concat %21 %22; 866 var.store %9 %23; 867 yield; 868 } 869 (%24 : short)boolean -> { 870 %25 : int = constant @"3"; 871 %26 : short = conv %25; 872 %27 : boolean = eq %24 %26; 873 yield %27; 874 } 875 ()void -> { 876 %28 : java.lang.String = var.load %9; 877 %29 : java.lang.String = constant @"three"; 878 %30 : java.lang.String = concat %28 %29; 879 var.store %9 %30; 880 yield; 881 } 882 ()boolean -> { 883 %17 : boolean = constant @"true"; 884 yield %17; 885 } 886 ()void -> { 887 %31 : java.lang.String = var.load %9; 888 %32 : java.lang.String = constant @"else"; 889 %33 : java.lang.String = concat %31 %32; 890 var.store %9 %33; 891 yield; 892 }; 893 %34 : java.lang.String = var.load %9; 894 return %34; 895 }; 896 """) 897 @CodeReflection 898 static String caseConstantConv(short a) { 899 final short s = 1; 900 final byte b = 2; 901 String r = ""; 902 switch (a) { 903 case s -> r += "one"; // identity, short -> short 904 case b -> r += "two"; // widening primitive conversion, byte -> short 905 case 3 -> r += "three"; // narrowing primitive conversion, int -> short 906 default -> r += "else"; 907 } 908 return r; 909 } 910 911 @IR(""" 912 func @"caseConstantConv2" (%0 : java.lang.Byte)java.lang.String -> { 913 %1 : Var<java.lang.Byte> = var %0 @"a"; 914 %2 : int = constant @"2"; 915 %3 : byte = conv %2; 916 %4 : Var<byte> = var %3 @"b"; 917 %5 : java.lang.String = constant @""; 918 %6 : Var<java.lang.String> = var %5 @"r"; 919 %7 : java.lang.Byte = var.load %1; 920 java.switch.statement %7 921 (%8 : java.lang.Byte)boolean -> { 922 %9 : int = constant @"1"; 923 %10 : byte = conv %9; 924 %11 : java.lang.Byte = invoke %10 @"java.lang.Byte::valueOf(byte)java.lang.Byte"; 925 %12 : boolean = invoke %8 %11 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 926 yield %12; 927 } 928 ()void -> { 929 %13 : java.lang.String = var.load %6; 930 %14 : java.lang.String = constant @"one"; 931 %15 : java.lang.String = concat %13 %14; 932 var.store %6 %15; 933 yield; 934 } 935 (%16 : java.lang.Byte)boolean -> { 936 %17 : byte = var.load %4; 937 %18 : java.lang.Byte = invoke %17 @"java.lang.Byte::valueOf(byte)java.lang.Byte"; 938 %19 : boolean = invoke %16 %18 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 939 yield %19; 940 } 941 ()void -> { 942 %20 : java.lang.String = var.load %6; 943 %21 : java.lang.String = constant @"two"; 944 %22 : java.lang.String = concat %20 %21; 945 var.store %6 %22; 946 yield; 947 } 948 ()boolean -> { 949 %17 : boolean = constant @"true"; 950 yield %17; 951 } 952 ()void -> { 953 %23 : java.lang.String = var.load %6; 954 %24 : java.lang.String = constant @"default"; 955 %25 : java.lang.String = concat %23 %24; 956 var.store %6 %25; 957 yield; 958 }; 959 %26 : java.lang.String = var.load %6; 960 return %26; 961 }; 962 """) 963 @CodeReflection 964 static String caseConstantConv2(Byte a) { 965 final byte b = 2; 966 String r = ""; 967 switch (a) { 968 case 1 -> r+= "one"; // narrowing primitive conversion followed by a boxing conversion, int -> bye -> Byte 969 case b -> r+= "two"; // boxing, byte -> Byte 970 default -> r+= "default"; 971 } 972 return r; 973 } 974 975 @IR(""" 976 func @"nonEnhancedSwStatNoDefault" (%0 : int)java.lang.String -> { 977 %1 : Var<int> = var %0 @"a"; 978 %2 : java.lang.String = constant @""; 979 %3 : Var<java.lang.String> = var %2 @"r"; 980 %4 : int = var.load %1; 981 java.switch.statement %4 982 (%5 : int)boolean -> { 983 %6 : int = constant @"1"; 984 %7 : boolean = eq %5 %6; 985 yield %7; 986 } 987 ()void -> { 988 %8 : java.lang.String = var.load %3; 989 %9 : java.lang.String = constant @"1"; 990 %10 : java.lang.String = concat %8 %9; 991 var.store %3 %10; 992 yield; 993 } 994 (%11 : int)boolean -> { 995 %12 : int = constant @"2"; 996 %13 : boolean = eq %11 %12; 997 yield %13; 998 } 999 ()void -> { 1000 %14 : java.lang.String = var.load %3; 1001 %15 : int = constant @"2"; 1002 %16 : java.lang.Integer = invoke %15 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 1003 %17 : java.lang.String = concat %14 %16; 1004 var.store %3 %17; 1005 yield; 1006 }; 1007 %18 : java.lang.String = var.load %3; 1008 return %18; 1009 }; 1010 """) 1011 @CodeReflection 1012 static String nonEnhancedSwStatNoDefault(int a) { 1013 String r = ""; 1014 switch (a) { 1015 case 1 -> r += "1"; 1016 case 2 -> r += 2; 1017 } 1018 return r; 1019 } 1020 1021 enum E {A, B} 1022 @IR(""" 1023 func @"enhancedSwStatNoDefault1" (%0 : SwitchStatementTest$E)java.lang.String -> { 1024 %1 : Var<SwitchStatementTest$E> = var %0 @"e"; 1025 %2 : java.lang.String = constant @""; 1026 %3 : Var<java.lang.String> = var %2 @"r"; 1027 %4 : SwitchStatementTest$E = var.load %1; 1028 java.switch.statement %4 1029 (%5 : SwitchStatementTest$E)boolean -> { 1030 %6 : SwitchStatementTest$E = field.load @"SwitchStatementTest$E::A()SwitchStatementTest$E"; 1031 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1032 yield %7; 1033 } 1034 ()void -> { 1035 %8 : java.lang.String = var.load %3; 1036 %9 : SwitchStatementTest$E = field.load @"SwitchStatementTest$E::A()SwitchStatementTest$E"; 1037 %10 : java.lang.String = cast %9 @"java.lang.String"; 1038 %11 : java.lang.String = concat %8 %10; 1039 var.store %3 %11; 1040 yield; 1041 } 1042 (%12 : SwitchStatementTest$E)boolean -> { 1043 %13 : SwitchStatementTest$E = field.load @"SwitchStatementTest$E::B()SwitchStatementTest$E"; 1044 %14 : boolean = invoke %12 %13 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1045 yield %14; 1046 } 1047 ()void -> { 1048 %15 : java.lang.String = var.load %3; 1049 %16 : SwitchStatementTest$E = field.load @"SwitchStatementTest$E::B()SwitchStatementTest$E"; 1050 %17 : java.lang.String = cast %16 @"java.lang.String"; 1051 %18 : java.lang.String = concat %15 %17; 1052 var.store %3 %18; 1053 yield; 1054 } 1055 (%19 : SwitchStatementTest$E)boolean -> { 1056 %20 : java.lang.Object = constant @null; 1057 %21 : boolean = invoke %19 %20 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1058 yield %21; 1059 } 1060 ()void -> { 1061 %22 : java.lang.String = var.load %3; 1062 %23 : java.lang.String = constant @"null"; 1063 %24 : java.lang.String = concat %22 %23; 1064 var.store %3 %24; 1065 yield; 1066 } 1067 ()boolean -> { 1068 %17 : boolean = constant @"true"; 1069 yield %17; 1070 } 1071 ()void -> { 1072 %25 : java.lang.MatchException = new @"func<java.lang.MatchException>"; 1073 throw %25; 1074 }; 1075 %26 : java.lang.String = var.load %3; 1076 return %26; 1077 }; 1078 """) 1079 @CodeReflection 1080 static String enhancedSwStatNoDefault1(E e) { 1081 String r = ""; 1082 switch (e) { 1083 case A -> r += E.A; 1084 case B -> r += E.B; 1085 case null -> r += "null"; 1086 } 1087 return r; 1088 } 1089 1090 sealed interface I permits K, J {} 1091 record K() implements I {} 1092 static final class J implements I {} 1093 @IR(""" 1094 func @"enhancedSwStatNoDefault2" (%0 : SwitchStatementTest$I)java.lang.String -> { 1095 %1 : Var<SwitchStatementTest$I> = var %0 @"i"; 1096 %2 : java.lang.String = constant @""; 1097 %3 : Var<java.lang.String> = var %2 @"r"; 1098 %4 : SwitchStatementTest$I = var.load %1; 1099 %5 : SwitchStatementTest$K = constant @null; 1100 %6 : Var<SwitchStatementTest$K> = var %5 @"k"; 1101 %7 : SwitchStatementTest$J = constant @null; 1102 %8 : Var<SwitchStatementTest$J> = var %7 @"j"; 1103 java.switch.statement %4 1104 (%9 : SwitchStatementTest$I)boolean -> { 1105 %10 : boolean = pattern.match %9 1106 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<SwitchStatementTest$K> -> { 1107 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<SwitchStatementTest$K> = pattern.binding @"k"; 1108 yield %11; 1109 } 1110 (%12 : SwitchStatementTest$K)void -> { 1111 var.store %6 %12; 1112 yield; 1113 }; 1114 yield %10; 1115 } 1116 ()void -> { 1117 %13 : java.lang.String = var.load %3; 1118 %14 : java.lang.String = constant @"K"; 1119 %15 : java.lang.String = concat %13 %14; 1120 var.store %3 %15; 1121 yield; 1122 } 1123 (%16 : SwitchStatementTest$I)boolean -> { 1124 %17 : boolean = pattern.match %16 1125 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<SwitchStatementTest$J> -> { 1126 %18 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<SwitchStatementTest$J> = pattern.binding @"j"; 1127 yield %18; 1128 } 1129 (%19 : SwitchStatementTest$J)void -> { 1130 var.store %8 %19; 1131 yield; 1132 }; 1133 yield %17; 1134 } 1135 ()void -> { 1136 %20 : java.lang.String = var.load %3; 1137 %21 : java.lang.String = constant @"J"; 1138 %22 : java.lang.String = concat %20 %21; 1139 var.store %3 %22; 1140 yield; 1141 } 1142 ()boolean -> { 1143 %17 : boolean = constant @"true"; 1144 yield %17; 1145 } 1146 ()void -> { 1147 %23 : java.lang.MatchException = new @"func<java.lang.MatchException>"; 1148 throw %23; 1149 }; 1150 %24 : java.lang.String = var.load %3; 1151 return %24; 1152 }; 1153 """) 1154 @CodeReflection 1155 static String enhancedSwStatNoDefault2(I i) { 1156 String r = ""; 1157 switch (i) { 1158 case K k -> r += "K"; 1159 case J j -> r += "J"; 1160 } 1161 return r; 1162 } 1163 1164 @IR(""" 1165 func @"enhancedSwStatUnconditionalPattern" (%0 : java.lang.String)java.lang.String -> { 1166 %1 : Var<java.lang.String> = var %0 @"s"; 1167 %2 : java.lang.String = constant @""; 1168 %3 : Var<java.lang.String> = var %2 @"r"; 1169 %4 : java.lang.String = var.load %1; 1170 %5 : java.lang.Object = constant @null; 1171 %6 : Var<java.lang.Object> = var %5 @"o"; 1172 java.switch.statement %4 1173 (%7 : java.lang.String)boolean -> { 1174 %8 : java.lang.String = constant @"A"; 1175 %9 : boolean = invoke %7 %8 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1176 yield %9; 1177 } 1178 ()void -> { 1179 %10 : java.lang.String = var.load %3; 1180 %11 : java.lang.String = constant @"A"; 1181 %12 : java.lang.String = concat %10 %11; 1182 var.store %3 %12; 1183 yield; 1184 } 1185 (%13 : java.lang.String)boolean -> { 1186 %14 : boolean = pattern.match %13 1187 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Object> -> { 1188 %15 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Object> = pattern.binding @"o"; 1189 yield %15; 1190 } 1191 (%16 : java.lang.Object)void -> { 1192 var.store %6 %16; 1193 yield; 1194 }; 1195 yield %14; 1196 } 1197 ()void -> { 1198 %17 : java.lang.String = var.load %3; 1199 %18 : java.lang.String = constant @"obj"; 1200 %19 : java.lang.String = concat %17 %18; 1201 var.store %3 %19; 1202 yield; 1203 }; 1204 %20 : java.lang.String = var.load %3; 1205 return %20; 1206 }; 1207 """) 1208 @CodeReflection 1209 static String enhancedSwStatUnconditionalPattern(String s) { 1210 String r = ""; 1211 switch (s) { 1212 case "A" -> r += "A"; 1213 case Object o -> r += "obj"; 1214 } 1215 return r; 1216 } 1217 1218 @IR(""" 1219 func @"casePatternRuleExpression" (%0 : java.lang.Object)java.lang.String -> { 1220 %1 : Var<java.lang.Object> = var %0 @"o"; 1221 %2 : java.lang.String = constant @""; 1222 %3 : Var<java.lang.String> = var %2 @"r"; 1223 %4 : java.lang.Object = var.load %1; 1224 %5 : java.lang.Integer = constant @null; 1225 %6 : Var<java.lang.Integer> = var %5 @"i"; 1226 %7 : java.lang.String = constant @null; 1227 %8 : Var<java.lang.String> = var %7 @"s"; 1228 java.switch.statement %4 1229 (%9 : java.lang.Object)boolean -> { 1230 %10 : boolean = pattern.match %9 1231 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> -> { 1232 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> = pattern.binding @"i"; 1233 yield %11; 1234 } 1235 (%12 : java.lang.Integer)void -> { 1236 var.store %6 %12; 1237 yield; 1238 }; 1239 yield %10; 1240 } 1241 ()void -> { 1242 %13 : java.lang.String = var.load %3; 1243 %14 : java.lang.String = constant @"integer"; 1244 %15 : java.lang.String = concat %13 %14; 1245 var.store %3 %15; 1246 yield; 1247 } 1248 (%16 : java.lang.Object)boolean -> { 1249 %17 : boolean = pattern.match %16 1250 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1251 %18 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 1252 yield %18; 1253 } 1254 (%19 : java.lang.String)void -> { 1255 var.store %8 %19; 1256 yield; 1257 }; 1258 yield %17; 1259 } 1260 ()void -> { 1261 %20 : java.lang.String = var.load %3; 1262 %21 : java.lang.String = constant @"string"; 1263 %22 : java.lang.String = concat %20 %21; 1264 var.store %3 %22; 1265 yield; 1266 } 1267 ()boolean -> { 1268 %17 : boolean = constant @"true"; 1269 yield %17; 1270 } 1271 ()void -> { 1272 %23 : java.lang.String = var.load %3; 1273 %24 : java.lang.String = constant @"else"; 1274 %25 : java.lang.String = concat %23 %24; 1275 var.store %3 %25; 1276 yield; 1277 }; 1278 %26 : java.lang.String = var.load %3; 1279 return %26; 1280 }; 1281 """) 1282 @CodeReflection 1283 private static String casePatternRuleExpression(Object o) { 1284 String r = ""; 1285 switch (o) { 1286 case Integer i -> r += "integer"; 1287 case String s -> r+= "string"; 1288 default -> r+= "else"; 1289 } 1290 return r; 1291 } 1292 1293 @IR(""" 1294 func @"casePatternRuleBlock" (%0 : java.lang.Object)java.lang.String -> { 1295 %1 : Var<java.lang.Object> = var %0 @"o"; 1296 %2 : java.lang.String = constant @""; 1297 %3 : Var<java.lang.String> = var %2 @"r"; 1298 %4 : java.lang.Object = var.load %1; 1299 %5 : java.lang.Integer = constant @null; 1300 %6 : Var<java.lang.Integer> = var %5 @"i"; 1301 %7 : java.lang.String = constant @null; 1302 %8 : Var<java.lang.String> = var %7 @"s"; 1303 java.switch.statement %4 1304 (%9 : java.lang.Object)boolean -> { 1305 %10 : boolean = pattern.match %9 1306 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> -> { 1307 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> = pattern.binding @"i"; 1308 yield %11; 1309 } 1310 (%12 : java.lang.Integer)void -> { 1311 var.store %6 %12; 1312 yield; 1313 }; 1314 yield %10; 1315 } 1316 ()void -> { 1317 %13 : java.lang.String = var.load %3; 1318 %14 : java.lang.String = constant @"integer"; 1319 %15 : java.lang.String = concat %13 %14; 1320 var.store %3 %15; 1321 yield; 1322 } 1323 (%16 : java.lang.Object)boolean -> { 1324 %17 : boolean = pattern.match %16 1325 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1326 %18 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 1327 yield %18; 1328 } 1329 (%19 : java.lang.String)void -> { 1330 var.store %8 %19; 1331 yield; 1332 }; 1333 yield %17; 1334 } 1335 ()void -> { 1336 %20 : java.lang.String = var.load %3; 1337 %21 : java.lang.String = constant @"string"; 1338 %22 : java.lang.String = concat %20 %21; 1339 var.store %3 %22; 1340 yield; 1341 } 1342 ()boolean -> { 1343 %17 : boolean = constant @"true"; 1344 yield %17; 1345 } 1346 ()void -> { 1347 %23 : java.lang.String = var.load %3; 1348 %24 : java.lang.String = constant @"else"; 1349 %25 : java.lang.String = concat %23 %24; 1350 var.store %3 %25; 1351 yield; 1352 }; 1353 %26 : java.lang.String = var.load %3; 1354 return %26; 1355 }; 1356 """) 1357 @CodeReflection 1358 private static String casePatternRuleBlock(Object o) { 1359 String r = ""; 1360 switch (o) { 1361 case Integer i -> { 1362 r += "integer"; 1363 } 1364 case String s -> { 1365 r += "string"; 1366 } 1367 default -> { 1368 r += "else"; 1369 } 1370 } 1371 return r; 1372 } 1373 1374 @IR(""" 1375 func @"casePatternStatement" (%0 : java.lang.Object)java.lang.String -> { 1376 %1 : Var<java.lang.Object> = var %0 @"o"; 1377 %2 : java.lang.String = constant @""; 1378 %3 : Var<java.lang.String> = var %2 @"r"; 1379 %4 : java.lang.Object = var.load %1; 1380 %5 : java.lang.Integer = constant @null; 1381 %6 : Var<java.lang.Integer> = var %5 @"i"; 1382 %7 : java.lang.String = constant @null; 1383 %8 : Var<java.lang.String> = var %7 @"s"; 1384 java.switch.statement %4 1385 (%9 : java.lang.Object)boolean -> { 1386 %10 : boolean = pattern.match %9 1387 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> -> { 1388 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> = pattern.binding @"i"; 1389 yield %11; 1390 } 1391 (%12 : java.lang.Integer)void -> { 1392 var.store %6 %12; 1393 yield; 1394 }; 1395 yield %10; 1396 } 1397 ()void -> { 1398 %13 : java.lang.String = var.load %3; 1399 %14 : java.lang.String = constant @"integer"; 1400 %15 : java.lang.String = concat %13 %14; 1401 var.store %3 %15; 1402 java.break; 1403 } 1404 (%16 : java.lang.Object)boolean -> { 1405 %17 : boolean = pattern.match %16 1406 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1407 %18 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 1408 yield %18; 1409 } 1410 (%19 : java.lang.String)void -> { 1411 var.store %8 %19; 1412 yield; 1413 }; 1414 yield %17; 1415 } 1416 ()void -> { 1417 %20 : java.lang.String = var.load %3; 1418 %21 : java.lang.String = constant @"string"; 1419 %22 : java.lang.String = concat %20 %21; 1420 var.store %3 %22; 1421 java.break; 1422 } 1423 ()boolean -> { 1424 %17 : boolean = constant @"true"; 1425 yield %17; 1426 } 1427 ()void -> { 1428 %23 : java.lang.String = var.load %3; 1429 %24 : java.lang.String = constant @"else"; 1430 %25 : java.lang.String = concat %23 %24; 1431 var.store %3 %25; 1432 yield; 1433 }; 1434 %26 : java.lang.String = var.load %3; 1435 return %26; 1436 }; 1437 """) 1438 @CodeReflection 1439 private static String casePatternStatement(Object o) { 1440 String r = ""; 1441 switch (o) { 1442 case Integer i: 1443 r += "integer"; 1444 break; 1445 case String s: 1446 r += "string"; 1447 break; 1448 default: 1449 r += "else"; 1450 } 1451 return r; 1452 } 1453 1454 @IR(""" 1455 func @"casePatternThrow" (%0 : java.lang.Object)java.lang.String -> { 1456 %1 : Var<java.lang.Object> = var %0 @"o"; 1457 %2 : java.lang.String = constant @""; 1458 %3 : Var<java.lang.String> = var %2 @"r"; 1459 %4 : java.lang.Object = var.load %1; 1460 %5 : java.lang.Number = constant @null; 1461 %6 : Var<java.lang.Number> = var %5 @"n"; 1462 %7 : java.lang.String = constant @null; 1463 %8 : Var<java.lang.String> = var %7 @"s"; 1464 java.switch.statement %4 1465 (%9 : java.lang.Object)boolean -> { 1466 %10 : boolean = pattern.match %9 1467 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> -> { 1468 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> = pattern.binding @"n"; 1469 yield %11; 1470 } 1471 (%12 : java.lang.Number)void -> { 1472 var.store %6 %12; 1473 yield; 1474 }; 1475 yield %10; 1476 } 1477 ()void -> { 1478 %13 : java.lang.IllegalArgumentException = new @"func<java.lang.IllegalArgumentException>"; 1479 throw %13; 1480 } 1481 (%14 : java.lang.Object)boolean -> { 1482 %15 : boolean = pattern.match %14 1483 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1484 %16 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 1485 yield %16; 1486 } 1487 (%17 : java.lang.String)void -> { 1488 var.store %8 %17; 1489 yield; 1490 }; 1491 yield %15; 1492 } 1493 ()void -> { 1494 %18 : java.lang.String = var.load %3; 1495 %19 : java.lang.String = constant @"a string"; 1496 %20 : java.lang.String = concat %18 %19; 1497 var.store %3 %20; 1498 yield; 1499 } 1500 ()boolean -> { 1501 %17 : boolean = constant @"true"; 1502 yield %17; 1503 } 1504 ()void -> { 1505 %21 : java.lang.String = var.load %3; 1506 %22 : java.lang.Object = var.load %1; 1507 %23 : java.lang.Class<+<java.lang.Object>> = invoke %22 @"java.lang.Object::getClass()java.lang.Class"; 1508 %24 : java.lang.String = invoke %23 @"java.lang.Class::getName()java.lang.String"; 1509 %25 : java.lang.String = concat %21 %24; 1510 var.store %3 %25; 1511 yield; 1512 }; 1513 %26 : java.lang.String = var.load %3; 1514 return %26; 1515 }; 1516 """) 1517 @CodeReflection 1518 private static String casePatternThrow(Object o) { 1519 String r = ""; 1520 switch (o) { 1521 case Number n -> throw new IllegalArgumentException(); 1522 case String s -> r += "a string"; 1523 default -> r += o.getClass().getName(); 1524 } 1525 return r; 1526 } 1527 1528 // @@@ code model for such as code is not supported 1529 // @CodeReflection 1530 private static String casePatternMultiLabel(Object o) { 1531 String r = ""; 1532 switch (o) { 1533 case Integer _, Long _, Character _, Byte _, Short _-> r += "integral type"; 1534 default -> r += "non integral type"; 1535 } 1536 return r; 1537 } 1538 1539 @IR(""" 1540 func @"casePatternWithCaseConstant" (%0 : java.lang.Integer)java.lang.String -> { 1541 %1 : Var<java.lang.Integer> = var %0 @"a"; 1542 %2 : java.lang.String = constant @""; 1543 %3 : Var<java.lang.String> = var %2 @"r"; 1544 %4 : java.lang.Integer = var.load %1; 1545 %5 : java.lang.Integer = constant @null; 1546 %6 : Var<java.lang.Integer> = var %5 @"i"; 1547 %7 : java.lang.Integer = constant @null; 1548 %8 : Var<java.lang.Integer> = var %7 @"i"; 1549 java.switch.statement %4 1550 (%9 : java.lang.Integer)boolean -> { 1551 %10 : int = constant @"42"; 1552 %11 : java.lang.Integer = invoke %10 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 1553 %12 : boolean = invoke %9 %11 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1554 yield %12; 1555 } 1556 ()void -> { 1557 %13 : java.lang.String = var.load %3; 1558 %14 : java.lang.String = constant @"forty two"; 1559 %15 : java.lang.String = concat %13 %14; 1560 var.store %3 %15; 1561 yield; 1562 } 1563 (%16 : java.lang.Integer)boolean -> { 1564 %17 : boolean = java.cand 1565 ()boolean -> { 1566 %18 : boolean = pattern.match %16 1567 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> -> { 1568 %19 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> = pattern.binding @"i"; 1569 yield %19; 1570 } 1571 (%20 : java.lang.Integer)void -> { 1572 var.store %6 %20; 1573 yield; 1574 }; 1575 yield %18; 1576 } 1577 ()boolean -> { 1578 %21 : java.lang.Integer = var.load %6; 1579 %22 : int = invoke %21 @"java.lang.Integer::intValue()int"; 1580 %23 : int = constant @"0"; 1581 %24 : boolean = gt %22 %23; 1582 yield %24; 1583 }; 1584 yield %17; 1585 } 1586 ()void -> { 1587 %25 : java.lang.String = var.load %3; 1588 %26 : java.lang.String = constant @"positive int"; 1589 %27 : java.lang.String = concat %25 %26; 1590 var.store %3 %27; 1591 yield; 1592 } 1593 (%28 : java.lang.Integer)boolean -> { 1594 %29 : boolean = java.cand 1595 ()boolean -> { 1596 %30 : boolean = pattern.match %28 1597 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> -> { 1598 %31 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Integer> = pattern.binding @"i"; 1599 yield %31; 1600 } 1601 (%32 : java.lang.Integer)void -> { 1602 var.store %8 %32; 1603 yield; 1604 }; 1605 yield %30; 1606 } 1607 ()boolean -> { 1608 %33 : java.lang.Integer = var.load %8; 1609 %34 : int = invoke %33 @"java.lang.Integer::intValue()int"; 1610 %35 : int = constant @"0"; 1611 %36 : boolean = lt %34 %35; 1612 yield %36; 1613 }; 1614 yield %29; 1615 } 1616 ()void -> { 1617 %37 : java.lang.String = var.load %3; 1618 %38 : java.lang.String = constant @"negative int"; 1619 %39 : java.lang.String = concat %37 %38; 1620 var.store %3 %39; 1621 yield; 1622 } 1623 ()boolean -> { 1624 %17 : boolean = constant @"true"; 1625 yield %17; 1626 } 1627 ()void -> { 1628 %40 : java.lang.String = var.load %3; 1629 %41 : java.lang.String = constant @"zero"; 1630 %42 : java.lang.String = concat %40 %41; 1631 var.store %3 %42; 1632 yield; 1633 }; 1634 %43 : java.lang.String = var.load %3; 1635 return %43; 1636 }; 1637 """) 1638 @CodeReflection 1639 static String casePatternWithCaseConstant(Integer a) { 1640 String r = ""; 1641 switch (a) { 1642 case 42 -> r += "forty two"; 1643 // @@@ case int will not match, because of the way InstanceOfOp is interpreted 1644 case Integer i when i > 0 -> r += "positive int"; 1645 case Integer i when i < 0 -> r += "negative int"; 1646 default -> r += "zero"; 1647 } 1648 return r; 1649 } 1650 1651 @IR(""" 1652 func @"caseTypePattern" (%0 : java.lang.Object)java.lang.String -> { 1653 %1 : Var<java.lang.Object> = var %0 @"o"; 1654 %2 : java.lang.String = constant @""; 1655 %3 : Var<java.lang.String> = var %2 @"r"; 1656 %4 : java.lang.Object = var.load %1; 1657 %5 : java.lang.String = constant @null; 1658 %6 : Var<java.lang.String> = var %5 @""; 1659 %7 : java.util.RandomAccess = constant @null; 1660 %8 : Var<java.util.RandomAccess> = var %7 @""; 1661 %9 : int[] = constant @null; 1662 %10 : Var<int[]> = var %9 @""; 1663 %11 : java.util.Stack[][] = constant @null; 1664 %12 : Var<java.util.Stack[][]> = var %11 @""; 1665 %13 : java.util.Collection[][][] = constant @null; 1666 %14 : Var<java.util.Collection[][][]> = var %13 @""; 1667 %15 : java.lang.Number = constant @null; 1668 %16 : Var<java.lang.Number> = var %15 @"n"; 1669 java.switch.statement %4 1670 (%17 : java.lang.Object)boolean -> { 1671 %18 : boolean = pattern.match %17 1672 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1673 %19 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @""; 1674 yield %19; 1675 } 1676 (%20 : java.lang.String)void -> { 1677 var.store %6 %20; 1678 yield; 1679 }; 1680 yield %18; 1681 } 1682 ()void -> { 1683 %21 : java.lang.String = var.load %3; 1684 %22 : java.lang.String = constant @"String"; 1685 %23 : java.lang.String = concat %21 %22; 1686 var.store %3 %23; 1687 yield; 1688 } 1689 (%24 : java.lang.Object)boolean -> { 1690 %25 : boolean = pattern.match %24 1691 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.RandomAccess> -> { 1692 %26 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.RandomAccess> = pattern.binding @""; 1693 yield %26; 1694 } 1695 (%27 : java.util.RandomAccess)void -> { 1696 var.store %8 %27; 1697 yield; 1698 }; 1699 yield %25; 1700 } 1701 ()void -> { 1702 %28 : java.lang.String = var.load %3; 1703 %29 : java.lang.String = constant @"RandomAccess"; 1704 %30 : java.lang.String = concat %28 %29; 1705 var.store %3 %30; 1706 yield; 1707 } 1708 (%31 : java.lang.Object)boolean -> { 1709 %32 : boolean = pattern.match %31 1710 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<int[]> -> { 1711 %33 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<int[]> = pattern.binding @""; 1712 yield %33; 1713 } 1714 (%34 : int[])void -> { 1715 var.store %10 %34; 1716 yield; 1717 }; 1718 yield %32; 1719 } 1720 ()void -> { 1721 %35 : java.lang.String = var.load %3; 1722 %36 : java.lang.String = constant @"int[]"; 1723 %37 : java.lang.String = concat %35 %36; 1724 var.store %3 %37; 1725 yield; 1726 } 1727 (%38 : java.lang.Object)boolean -> { 1728 %39 : boolean = pattern.match %38 1729 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.Stack[][]> -> { 1730 %40 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.Stack[][]> = pattern.binding @""; 1731 yield %40; 1732 } 1733 (%41 : java.util.Stack[][])void -> { 1734 var.store %12 %41; 1735 yield; 1736 }; 1737 yield %39; 1738 } 1739 ()void -> { 1740 %42 : java.lang.String = var.load %3; 1741 %43 : java.lang.String = constant @"Stack[][]"; 1742 %44 : java.lang.String = concat %42 %43; 1743 var.store %3 %44; 1744 yield; 1745 } 1746 (%45 : java.lang.Object)boolean -> { 1747 %46 : boolean = pattern.match %45 1748 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.Collection[][][]> -> { 1749 %47 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.util.Collection[][][]> = pattern.binding @""; 1750 yield %47; 1751 } 1752 (%48 : java.util.Collection[][][])void -> { 1753 var.store %14 %48; 1754 yield; 1755 }; 1756 yield %46; 1757 } 1758 ()void -> { 1759 %49 : java.lang.String = var.load %3; 1760 %50 : java.lang.String = constant @"Collection[][][]"; 1761 %51 : java.lang.String = concat %49 %50; 1762 var.store %3 %51; 1763 yield; 1764 } 1765 (%52 : java.lang.Object)boolean -> { 1766 %53 : boolean = pattern.match %52 1767 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> -> { 1768 %54 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> = pattern.binding @"n"; 1769 yield %54; 1770 } 1771 (%55 : java.lang.Number)void -> { 1772 var.store %16 %55; 1773 yield; 1774 }; 1775 yield %53; 1776 } 1777 ()void -> { 1778 %56 : java.lang.String = var.load %3; 1779 %57 : java.lang.String = constant @"Number"; 1780 %58 : java.lang.String = concat %56 %57; 1781 var.store %3 %58; 1782 yield; 1783 } 1784 ()boolean -> { 1785 %17 : boolean = constant @"true"; 1786 yield %17; 1787 } 1788 ()void -> { 1789 %59 : java.lang.String = var.load %3; 1790 %60 : java.lang.String = constant @"something else"; 1791 %61 : java.lang.String = concat %59 %60; 1792 var.store %3 %61; 1793 yield; 1794 }; 1795 %62 : java.lang.String = var.load %3; 1796 return %62; 1797 }; 1798 """) 1799 @CodeReflection 1800 static String caseTypePattern(Object o) { 1801 String r = ""; 1802 switch (o) { 1803 case String _ -> r+= "String"; // class 1804 case RandomAccess _ -> r+= "RandomAccess"; // interface 1805 case int[] _ -> r+= "int[]"; // array primitive 1806 case Stack[][] _ -> r+= "Stack[][]"; // array class 1807 case Collection[][][] _ -> r+= "Collection[][][]"; // array interface 1808 case final Number n -> r+= "Number"; // final modifier 1809 default -> r+= "something else"; 1810 } 1811 return r; 1812 } 1813 1814 record R(Number n) {} 1815 @IR(""" 1816 func @"caseRecordPattern" (%0 : java.lang.Object)java.lang.String -> { 1817 %1 : Var<java.lang.Object> = var %0 @"o"; 1818 %2 : java.lang.String = constant @""; 1819 %3 : Var<java.lang.String> = var %2 @"r"; 1820 %4 : java.lang.Object = var.load %1; 1821 %5 : java.lang.Number = constant @null; 1822 %6 : Var<java.lang.Number> = var %5 @"n"; 1823 java.switch.statement %4 1824 (%7 : java.lang.Object)boolean -> { 1825 %8 : boolean = pattern.match %7 1826 ()java.lang.reflect.code.ExtendedOp$Pattern$Record<SwitchStatementTest$R> -> { 1827 %9 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> = pattern.binding @"n"; 1828 %10 : java.lang.reflect.code.ExtendedOp$Pattern$Record<SwitchStatementTest$R> = pattern.record %9 @"(java.lang.Number n)SwitchStatementTest$R"; 1829 yield %10; 1830 } 1831 (%11 : java.lang.Number)void -> { 1832 var.store %6 %11; 1833 yield; 1834 }; 1835 yield %8; 1836 } 1837 ()void -> { 1838 %12 : java.lang.String = var.load %3; 1839 %13 : java.lang.String = constant @"R(_)"; 1840 %14 : java.lang.String = concat %12 %13; 1841 var.store %3 %14; 1842 yield; 1843 } 1844 ()boolean -> { 1845 %17 : boolean = constant @"true"; 1846 yield %17; 1847 } 1848 ()void -> { 1849 %15 : java.lang.String = var.load %3; 1850 %16 : java.lang.String = constant @"else"; 1851 %17 : java.lang.String = concat %15 %16; 1852 var.store %3 %17; 1853 yield; 1854 }; 1855 %18 : java.lang.String = var.load %3; 1856 return %18; 1857 }; 1858 """) 1859 @CodeReflection 1860 static String caseRecordPattern(Object o) { 1861 String r = ""; 1862 switch (o) { 1863 case R(Number n) -> r += "R(_)"; 1864 default -> r+= "else"; 1865 } 1866 return r; 1867 } 1868 1869 @IR(""" 1870 func @"casePatternGuard" (%0 : java.lang.Object)java.lang.String -> { 1871 %1 : Var<java.lang.Object> = var %0 @"obj"; 1872 %2 : java.lang.String = constant @""; 1873 %3 : Var<java.lang.String> = var %2 @"r"; 1874 %4 : java.lang.Object = var.load %1; 1875 %5 : java.lang.String = constant @null; 1876 %6 : Var<java.lang.String> = var %5 @"s"; 1877 %7 : java.lang.Number = constant @null; 1878 %8 : Var<java.lang.Number> = var %7 @"n"; 1879 java.switch.statement %4 1880 (%9 : java.lang.Object)boolean -> { 1881 %10 : boolean = java.cand 1882 ()boolean -> { 1883 %11 : boolean = pattern.match %9 1884 ()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 1885 %12 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 1886 yield %12; 1887 } 1888 (%13 : java.lang.String)void -> { 1889 var.store %6 %13; 1890 yield; 1891 }; 1892 yield %11; 1893 } 1894 ()boolean -> { 1895 %14 : java.lang.String = var.load %6; 1896 %15 : int = invoke %14 @"java.lang.String::length()int"; 1897 %16 : int = constant @"3"; 1898 %17 : boolean = gt %15 %16; 1899 yield %17; 1900 }; 1901 yield %10; 1902 } 1903 ()void -> { 1904 %18 : java.lang.String = var.load %3; 1905 %19 : java.lang.String = constant @"str with length > %d"; 1906 %20 : java.lang.String = var.load %6; 1907 %21 : int = invoke %20 @"java.lang.String::length()int"; 1908 %22 : java.lang.Integer = invoke %21 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 1909 %23 : java.lang.String = invoke %19 %22 @"java.lang.String::formatted(java.lang.Object[])java.lang.String"; 1910 %24 : java.lang.String = concat %18 %23; 1911 var.store %3 %24; 1912 yield; 1913 } 1914 (%25 : java.lang.Object)boolean -> { 1915 %26 : boolean = java.cand 1916 ()boolean -> { 1917 %27 : boolean = pattern.match %25 1918 ()java.lang.reflect.code.ExtendedOp$Pattern$Record<SwitchStatementTest$R> -> { 1919 %28 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> = pattern.binding @"n"; 1920 %29 : java.lang.reflect.code.ExtendedOp$Pattern$Record<SwitchStatementTest$R> = pattern.record %28 @"(java.lang.Number n)SwitchStatementTest$R"; 1921 yield %29; 1922 } 1923 (%30 : java.lang.Number)void -> { 1924 var.store %8 %30; 1925 yield; 1926 }; 1927 yield %27; 1928 } 1929 ()boolean -> { 1930 %31 : java.lang.Number = var.load %8; 1931 %32 : java.lang.Class<+<java.lang.Object>> = invoke %31 @"java.lang.Object::getClass()java.lang.Class"; 1932 %33 : java.lang.Class = constant @"java.lang.Double"; 1933 %34 : boolean = invoke %32 %33 @"java.lang.Object::equals(java.lang.Object)boolean"; 1934 yield %34; 1935 }; 1936 yield %26; 1937 } 1938 ()void -> { 1939 %35 : java.lang.String = var.load %3; 1940 %36 : java.lang.String = constant @"R(Double)"; 1941 %37 : java.lang.String = concat %35 %36; 1942 var.store %3 %37; 1943 yield; 1944 } 1945 ()boolean -> { 1946 %17 : boolean = constant @"true"; 1947 yield %17; 1948 } 1949 ()void -> { 1950 %38 : java.lang.String = var.load %3; 1951 %39 : java.lang.String = constant @"else"; 1952 %40 : java.lang.String = concat %38 %39; 1953 var.store %3 %40; 1954 yield; 1955 }; 1956 %41 : java.lang.String = var.load %3; 1957 return %41; 1958 }; 1959 """) 1960 @CodeReflection 1961 static String casePatternGuard(Object obj) { 1962 String r = ""; 1963 switch (obj) { 1964 case String s when s.length() > 3 -> r += "str with length > %d".formatted(s.length()); 1965 case R(Number n) when n.getClass().equals(Double.class) -> r += "R(Double)"; 1966 default -> r += "else"; 1967 } 1968 return r; 1969 } 1970 1971 @IR(""" 1972 func @"defaultCaseNotTheLast" (%0 : java.lang.String)java.lang.String -> { 1973 %1 : Var<java.lang.String> = var %0 @"s"; 1974 %2 : java.lang.String = constant @""; 1975 %3 : Var<java.lang.String> = var %2 @"r"; 1976 %4 : java.lang.String = var.load %1; 1977 java.switch.statement %4 1978 (%5 : java.lang.String)boolean -> { 1979 %6 : java.lang.String = constant @"M"; 1980 %7 : boolean = invoke %5 %6 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1981 yield %7; 1982 } 1983 ()void -> { 1984 %8 : java.lang.String = var.load %3; 1985 %9 : java.lang.String = constant @"Mow"; 1986 %10 : java.lang.String = concat %8 %9; 1987 var.store %3 %10; 1988 yield; 1989 } 1990 (%11 : java.lang.String)boolean -> { 1991 %12 : java.lang.String = constant @"A"; 1992 %13 : boolean = invoke %11 %12 @"java.util.Objects::equals(java.lang.Object, java.lang.Object)boolean"; 1993 yield %13; 1994 } 1995 ()void -> { 1996 %14 : java.lang.String = var.load %3; 1997 %15 : java.lang.String = constant @"Aow"; 1998 %16 : java.lang.String = concat %14 %15; 1999 var.store %3 %16; 2000 yield; 2001 } 2002 ()boolean -> { 2003 %17 : boolean = constant @"true"; 2004 yield %17; 2005 } 2006 ()void -> { 2007 %17 : java.lang.String = var.load %3; 2008 %18 : java.lang.String = constant @"else"; 2009 %19 : java.lang.String = concat %17 %18; 2010 var.store %3 %19; 2011 yield; 2012 }; 2013 %20 : java.lang.String = var.load %3; 2014 return %20; 2015 }; 2016 """) 2017 @CodeReflection 2018 static String defaultCaseNotTheLast(String s) { 2019 String r = ""; 2020 switch (s) { 2021 default -> r += "else"; 2022 case "M" -> r += "Mow"; 2023 case "A" -> r += "Aow"; 2024 } 2025 return r; 2026 } 2027 }