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