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