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.type:"java.lang.String")java.type:"java.lang.String" -> { 15 %1 : Var<java.type:"java.lang.String"> = var %0 @"r"; 16 %2 : java.type:"java.lang.String" = var.load %1; 17 %3 : java.type:"java.lang.String" = java.switch.expression %2 18 (%4 : java.type:"java.lang.String")java.type:"boolean" -> { 19 %5 : java.type:"java.lang.String" = constant @"FOO"; 20 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 21 yield %6; 22 } 23 ()java.type:"java.lang.String" -> { 24 %7 : java.type:"java.lang.String" = constant @"BAR"; 25 yield %7; 26 } 27 (%8 : java.type:"java.lang.String")java.type:"boolean" -> { 28 %9 : java.type:"java.lang.String" = constant @"BAR"; 29 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 30 yield %10; 31 } 32 ()java.type:"java.lang.String" -> { 33 %11 : java.type:"java.lang.String" = constant @"BAZ"; 34 yield %11; 35 } 36 (%12 : java.type:"java.lang.String")java.type:"boolean" -> { 37 %13 : java.type:"java.lang.String" = constant @"BAZ"; 38 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 39 yield %14; 40 } 41 ()java.type:"java.lang.String" -> { 42 %15 : java.type:"java.lang.String" = constant @"FOO"; 43 yield %15; 44 } 45 ()java.type:"boolean" -> { 46 %16 : java.type:"boolean" = constant @true; 47 yield %16; 48 } 49 ()java.type:"java.lang.String" -> { 50 %17 : java.type:"java.lang.String" = constant @""; 51 yield %17; 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.type:"java.lang.String")java.type:"java.lang.String" -> { 68 %1 : Var<java.type:"java.lang.String"> = var %0 @"r"; 69 %2 : java.type:"java.lang.String" = var.load %1; 70 %3 : java.type:"java.lang.String" = java.switch.expression %2 71 (%4 : java.type:"java.lang.String")java.type:"boolean" -> { 72 %5 : java.type:"java.lang.String" = constant @"FOO"; 73 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 74 yield %6; 75 } 76 ()java.type:"java.lang.String" -> { 77 %7 : java.type:"java.lang.String" = constant @"BAR"; 78 java.yield %7; 79 } 80 (%8 : java.type:"java.lang.String")java.type:"boolean" -> { 81 %9 : java.type:"java.lang.String" = constant @"BAR"; 82 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 83 yield %10; 84 } 85 ()java.type:"java.lang.String" -> { 86 %11 : java.type:"java.lang.String" = constant @"BAZ"; 87 java.yield %11; 88 } 89 (%12 : java.type:"java.lang.String")java.type:"boolean" -> { 90 %13 : java.type:"java.lang.String" = constant @"BAZ"; 91 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 92 yield %14; 93 } 94 ()java.type:"java.lang.String" -> { 95 %15 : java.type:"java.lang.String" = constant @"FOO"; 96 java.yield %15; 97 } 98 ()java.type:"boolean" -> { 99 %16 : java.type:"boolean" = constant @true; 100 yield %16; 101 } 102 ()java.type:"java.lang.String" -> { 103 %17 : java.type:"java.lang.String" = constant @""; 104 java.yield %17; 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.type:"java.lang.String")java.type:"java.lang.String" -> { 129 %1 : Var<java.type:"java.lang.String"> = var %0 @"s"; 130 %2 : java.type:"java.lang.String" = var.load %1; 131 %3 : java.type:"java.lang.String" = java.switch.expression %2 132 (%4 : java.type:"java.lang.String")java.type:"boolean" -> { 133 %5 : java.type:"java.lang.String" = constant @"FOO"; 134 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 135 yield %6; 136 } 137 ()java.type:"java.lang.String" -> { 138 %7 : java.type:"java.lang.String" = constant @"BAR"; 139 java.yield %7; 140 } 141 (%8 : java.type:"java.lang.String")java.type:"boolean" -> { 142 %9 : java.type:"java.lang.String" = constant @"BAR"; 143 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 144 yield %10; 145 } 146 ()java.type:"java.lang.String" -> { 147 %11 : java.type:"java.lang.String" = constant @"BAZ"; 148 java.yield %11; 149 } 150 (%12 : java.type:"java.lang.String")java.type:"boolean" -> { 151 %13 : java.type:"java.lang.String" = constant @"BAZ"; 152 %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 153 yield %14; 154 } 155 ()java.type:"java.lang.String" -> { 156 %15 : java.type:"java.lang.String" = constant @"FOO"; 157 java.yield %15; 158 } 159 ()java.type:"boolean" -> { 160 %16 : java.type:"boolean" = constant @true; 161 yield %16; 162 } 163 ()java.type:"java.lang.String" -> { 164 %17 : java.type:"java.lang.String" = constant @""; 165 java.yield %17; 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 : java.type:"char")java.type:"java.lang.String" -> { 182 %1 : Var<java.type:"char"> = var %0 @"c"; 183 %2 : java.type:"char" = var.load %1; 184 %3 : java.type:"char" = invoke %2 @java.ref:"java.lang.Character::toLowerCase(char):char"; 185 %4 : java.type:"java.lang.String" = java.switch.expression %3 186 (%5 : java.type:"char")java.type:"boolean" -> { 187 %6 : java.type:"boolean" = java.cor 188 ()java.type:"boolean" -> { 189 %7 : java.type:"char" = constant @'a'; 190 %8 : java.type:"boolean" = eq %5 %7; 191 yield %8; 192 } 193 ()java.type:"boolean" -> { 194 %9 : java.type:"char" = constant @'e'; 195 %10 : java.type:"boolean" = eq %5 %9; 196 yield %10; 197 } 198 ()java.type:"boolean" -> { 199 %11 : java.type:"char" = constant @'i'; 200 %12 : java.type:"boolean" = eq %5 %11; 201 yield %12; 202 } 203 ()java.type:"boolean" -> { 204 %13 : java.type:"char" = constant @'o'; 205 %14 : java.type:"boolean" = eq %5 %13; 206 yield %14; 207 } 208 ()java.type:"boolean" -> { 209 %15 : java.type:"char" = constant @'u'; 210 %16 : java.type:"boolean" = eq %5 %15; 211 yield %16; 212 }; 213 yield %6; 214 } 215 ()java.type:"java.lang.String" -> { 216 %17 : java.type:"java.lang.String" = constant @"vowel"; 217 java.yield %17; 218 } 219 ()java.type:"boolean" -> { 220 %18 : java.type:"boolean" = constant @true; 221 yield %18; 222 } 223 ()java.type:"java.lang.String" -> { 224 %19 : java.type:"java.lang.String" = constant @"consonant"; 225 java.yield %19; 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.type:"java.lang.Integer")java.type:"java.lang.String" -> { 240 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i"; 241 %2 : java.type:"java.lang.Integer" = var.load %1; 242 %3 : java.type:"java.lang.String" = java.switch.expression %2 243 (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> { 244 %5 : java.type:"int" = constant @8; 245 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer"; 246 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 247 yield %7; 248 } 249 ()java.type:"java.lang.String" -> { 250 %8 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()"; 251 throw %8; 252 } 253 (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> { 254 %10 : java.type:"int" = constant @9; 255 %11 : java.type:"java.lang.Integer" = invoke %10 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer"; 256 %12 : java.type:"boolean" = invoke %9 %11 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 257 yield %12; 258 } 259 ()java.type:"java.lang.String" -> { 260 %13 : java.type:"java.lang.String" = constant @"NINE"; 261 yield %13; 262 } 263 ()java.type:"boolean" -> { 264 %14 : java.type:"boolean" = constant @true; 265 yield %14; 266 } 267 ()java.type:"java.lang.String" -> { 268 %15 : java.type:"java.lang.String" = constant @"An integer"; 269 yield %15; 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.type:"java.lang.String")java.type:"java.lang.String" -> { 285 %1 : Var<java.type:"java.lang.String"> = var %0 @"s"; 286 %2 : java.type:"java.lang.String" = var.load %1; 287 %3 : java.type:"java.lang.String" = java.switch.expression %2 288 (%4 : java.type:"java.lang.String")java.type:"boolean" -> { 289 %5 : java.type:"java.lang.Object" = constant @null; 290 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 291 yield %6; 292 } 293 ()java.type:"java.lang.String" -> { 294 %7 : java.type:"java.lang.String" = constant @"null"; 295 yield %7; 296 } 297 ()java.type:"boolean" -> { 298 %8 : java.type:"boolean" = constant @true; 299 yield %8; 300 } 301 ()java.type:"java.lang.String" -> { 302 %9 : java.type:"java.lang.String" = constant @"non null"; 303 yield %9; 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 : java.type:"char")java.type:"java.lang.String" -> { 328 %1 : Var<java.type:"char"> = var %0 @"c"; 329 %2 : java.type:"char" = var.load %1; 330 %3 : java.type:"java.lang.String" = java.switch.expression %2 331 (%4 : java.type:"char")java.type:"boolean" -> { 332 %5 : java.type:"char" = constant @'A'; 333 %6 : java.type:"boolean" = eq %4 %5; 334 yield %6; 335 } 336 ()java.type:"java.lang.String" -> { 337 java.switch.fallthrough; 338 } 339 (%7 : java.type:"char")java.type:"boolean" -> { 340 %8 : java.type:"char" = constant @'B'; 341 %9 : java.type:"boolean" = eq %7 %8; 342 yield %9; 343 } 344 ()java.type:"java.lang.String" -> { 345 %10 : java.type:"java.lang.String" = constant @"A or B"; 346 java.yield %10; 347 } 348 ()java.type:"boolean" -> { 349 %11 : java.type:"boolean" = constant @true; 350 yield %11; 351 } 352 ()java.type:"java.lang.String" -> { 353 %12 : java.type:"java.lang.String" = constant @"Neither A nor B"; 354 java.yield %12; 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 : java.type:"SwitchExpressionTest2$Day")java.type:"int" -> { 375 %1 : Var<java.type:"SwitchExpressionTest2$Day"> = var %0 @"d"; 376 %2 : java.type:"SwitchExpressionTest2$Day" = var.load %1; 377 %3 : java.type:"int" = java.switch.expression %2 378 (%4 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> { 379 %5 : java.type:"boolean" = java.cor 380 ()java.type:"boolean" -> { 381 %6 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::MON:SwitchExpressionTest2$Day"; 382 %7 : java.type:"boolean" = invoke %4 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 383 yield %7; 384 } 385 ()java.type:"boolean" -> { 386 %8 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::FRI:SwitchExpressionTest2$Day"; 387 %9 : java.type:"boolean" = invoke %4 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 388 yield %9; 389 } 390 ()java.type:"boolean" -> { 391 %10 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SUN:SwitchExpressionTest2$Day"; 392 %11 : java.type:"boolean" = invoke %4 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 393 yield %11; 394 }; 395 yield %5; 396 } 397 ()java.type:"int" -> { 398 %12 : java.type:"int" = constant @6; 399 yield %12; 400 } 401 (%13 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> { 402 %14 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::TUE:SwitchExpressionTest2$Day"; 403 %15 : java.type:"boolean" = invoke %13 %14 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 404 yield %15; 405 } 406 ()java.type:"int" -> { 407 %16 : java.type:"int" = constant @7; 408 yield %16; 409 } 410 (%17 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> { 411 %18 : java.type:"boolean" = java.cor 412 ()java.type:"boolean" -> { 413 %19 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::THU:SwitchExpressionTest2$Day"; 414 %20 : java.type:"boolean" = invoke %17 %19 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 415 yield %20; 416 } 417 ()java.type:"boolean" -> { 418 %21 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SAT:SwitchExpressionTest2$Day"; 419 %22 : java.type:"boolean" = invoke %17 %21 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 420 yield %22; 421 }; 422 yield %18; 423 } 424 ()java.type:"int" -> { 425 %23 : java.type:"int" = constant @8; 426 yield %23; 427 } 428 (%24 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> { 429 %25 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::WED:SwitchExpressionTest2$Day"; 430 %26 : java.type:"boolean" = invoke %24 %25 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 431 yield %26; 432 } 433 ()java.type:"int" -> { 434 %27 : java.type:"int" = constant @9; 435 yield %27; 436 } 437 ()java.type:"boolean" -> { 438 %28 : java.type:"boolean" = constant @true; 439 yield %28; 440 } 441 ()java.type:"int" -> { 442 %29 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()"; 443 throw %29; 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 : java.type:"int")java.type:"java.lang.String" -> { 463 %1 : Var<java.type:"int"> = var %0 @"i"; 464 %2 : java.type:"int" = constant @11; 465 %3 : Var<java.type:"int"> = var %2 @"eleven"; 466 %4 : java.type:"int" = var.load %1; 467 %5 : java.type:"java.lang.String" = java.switch.expression %4 468 (%6 : java.type:"int")java.type:"boolean" -> { 469 %7 : java.type:"int" = constant @1; 470 %8 : java.type:"int" = constant @15; 471 %9 : java.type:"int" = and %7 %8; 472 %10 : java.type:"boolean" = eq %6 %9; 473 yield %10; 474 } 475 ()java.type:"java.lang.String" -> { 476 %11 : java.type:"java.lang.String" = constant @"1"; 477 yield %11; 478 } 479 (%12 : java.type:"int")java.type:"boolean" -> { 480 %13 : java.type:"int" = constant @4; 481 %14 : java.type:"int" = constant @1; 482 %15 : java.type:"int" = ashr %13 %14; 483 %16 : java.type:"boolean" = eq %12 %15; 484 yield %16; 485 } 486 ()java.type:"java.lang.String" -> { 487 %17 : java.type:"java.lang.String" = constant @"2"; 488 yield %17; 489 } 490 (%18 : java.type:"int")java.type:"boolean" -> { 491 %19 : java.type:"long" = constant @3; 492 %20 : java.type:"int" = conv %19; 493 %21 : java.type:"boolean" = eq %18 %20; 494 yield %21; 495 } 496 ()java.type:"java.lang.String" -> { 497 %22 : java.type:"java.lang.String" = constant @"3"; 498 yield %22; 499 } 500 (%23 : java.type:"int")java.type:"boolean" -> { 501 %24 : java.type:"int" = constant @2; 502 %25 : java.type:"int" = constant @1; 503 %26 : java.type:"int" = lshl %24 %25; 504 %27 : java.type:"boolean" = eq %23 %26; 505 yield %27; 506 } 507 ()java.type:"java.lang.String" -> { 508 %28 : java.type:"java.lang.String" = constant @"4"; 509 yield %28; 510 } 511 (%29 : java.type:"int")java.type:"boolean" -> { 512 %30 : java.type:"int" = constant @10; 513 %31 : java.type:"int" = constant @2; 514 %32 : java.type:"int" = div %30 %31; 515 %33 : java.type:"boolean" = eq %29 %32; 516 yield %33; 517 } 518 ()java.type:"java.lang.String" -> { 519 %34 : java.type:"java.lang.String" = constant @"5"; 520 yield %34; 521 } 522 (%35 : java.type:"int")java.type:"boolean" -> { 523 %36 : java.type:"int" = constant @12; 524 %37 : java.type:"int" = constant @6; 525 %38 : java.type:"int" = sub %36 %37; 526 %39 : java.type:"boolean" = eq %35 %38; 527 yield %39; 528 } 529 ()java.type:"java.lang.String" -> { 530 %40 : java.type:"java.lang.String" = constant @"6"; 531 yield %40; 532 } 533 (%41 : java.type:"int")java.type:"boolean" -> { 534 %42 : java.type:"int" = constant @3; 535 %43 : java.type:"int" = constant @4; 536 %44 : java.type:"int" = add %42 %43; 537 %45 : java.type:"boolean" = eq %41 %44; 538 yield %45; 539 } 540 ()java.type:"java.lang.String" -> { 541 %46 : java.type:"java.lang.String" = constant @"7"; 542 yield %46; 543 } 544 (%47 : java.type:"int")java.type:"boolean" -> { 545 %48 : java.type:"int" = constant @2; 546 %49 : java.type:"int" = constant @2; 547 %50 : java.type:"int" = mul %48 %49; 548 %51 : java.type:"int" = constant @2; 549 %52 : java.type:"int" = mul %50 %51; 550 %53 : java.type:"boolean" = eq %47 %52; 551 yield %53; 552 } 553 ()java.type:"java.lang.String" -> { 554 %54 : java.type:"java.lang.String" = constant @"8"; 555 yield %54; 556 } 557 (%55 : java.type:"int")java.type:"boolean" -> { 558 %56 : java.type:"int" = constant @8; 559 %57 : java.type:"int" = constant @1; 560 %58 : java.type:"int" = or %56 %57; 561 %59 : java.type:"boolean" = eq %55 %58; 562 yield %59; 563 } 564 ()java.type:"java.lang.String" -> { 565 %60 : java.type:"java.lang.String" = constant @"9"; 566 yield %60; 567 } 568 (%61 : java.type:"int")java.type:"boolean" -> { 569 %62 : java.type:"int" = constant @10; 570 %63 : java.type:"boolean" = eq %61 %62; 571 yield %63; 572 } 573 ()java.type:"java.lang.String" -> { 574 %64 : java.type:"java.lang.String" = constant @"10"; 575 yield %64; 576 } 577 (%65 : java.type:"int")java.type:"boolean" -> { 578 %66 : java.type:"int" = var.load %3; 579 %67 : java.type:"boolean" = eq %65 %66; 580 yield %67; 581 } 582 ()java.type:"java.lang.String" -> { 583 %68 : java.type:"java.lang.String" = constant @"11"; 584 yield %68; 585 } 586 (%69 : java.type:"int")java.type:"boolean" -> { 587 %70 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int"; 588 %71 : java.type:"boolean" = eq %69 %70; 589 yield %71; 590 } 591 ()java.type:"java.lang.String" -> { 592 %72 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int"; 593 %73 : java.type:"java.lang.String" = invoke %72 @java.ref:"java.lang.String::valueOf(int):java.lang.String"; 594 yield %73; 595 } 596 (%74 : java.type:"int")java.type:"boolean" -> { 597 %75 : java.type:"int" = java.cexpression 598 ()java.type:"boolean" -> { 599 %76 : java.type:"int" = constant @1; 600 %77 : java.type:"int" = constant @0; 601 %78 : java.type:"boolean" = gt %76 %77; 602 yield %78; 603 } 604 ()java.type:"int" -> { 605 %79 : java.type:"int" = constant @13; 606 yield %79; 607 } 608 ()java.type:"int" -> { 609 %80 : java.type:"int" = constant @133; 610 yield %80; 611 }; 612 %81 : java.type:"boolean" = eq %74 %75; 613 yield %81; 614 } 615 ()java.type:"java.lang.String" -> { 616 %82 : java.type:"java.lang.String" = constant @"13"; 617 yield %82; 618 } 619 ()java.type:"boolean" -> { 620 %83 : java.type:"boolean" = constant @true; 621 yield %83; 622 } 623 ()java.type:"java.lang.String" -> { 624 %84 : java.type:"java.lang.String" = constant @"an int"; 625 yield %84; 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 : java.type:"short")java.type:"java.lang.String" -> { 655 %1 : Var<java.type:"short"> = var %0 @"a"; 656 %2 : java.type:"int" = constant @1; 657 %3 : java.type:"short" = conv %2; 658 %4 : Var<java.type:"short"> = var %3 @"s"; 659 %5 : java.type:"int" = constant @2; 660 %6 : java.type:"byte" = conv %5; 661 %7 : Var<java.type:"byte"> = var %6 @"b"; 662 %8 : java.type:"short" = var.load %1; 663 %9 : java.type:"java.lang.String" = java.switch.expression %8 664 (%10 : java.type:"short")java.type:"boolean" -> { 665 %11 : java.type:"short" = var.load %4; 666 %12 : java.type:"boolean" = eq %10 %11; 667 yield %12; 668 } 669 ()java.type:"java.lang.String" -> { 670 %13 : java.type:"java.lang.String" = constant @"one"; 671 yield %13; 672 } 673 (%14 : java.type:"short")java.type:"boolean" -> { 674 %15 : java.type:"byte" = var.load %7; 675 %16 : java.type:"short" = conv %15; 676 %17 : java.type:"boolean" = eq %14 %16; 677 yield %17; 678 } 679 ()java.type:"java.lang.String" -> { 680 %18 : java.type:"java.lang.String" = constant @"three"; 681 yield %18; 682 } 683 (%19 : java.type:"short")java.type:"boolean" -> { 684 %20 : java.type:"int" = constant @3; 685 %21 : java.type:"short" = conv %20; 686 %22 : java.type:"boolean" = eq %19 %21; 687 yield %22; 688 } 689 ()java.type:"java.lang.String" -> { 690 %23 : java.type:"java.lang.String" = constant @"two"; 691 yield %23; 692 } 693 ()java.type:"boolean" -> { 694 %24 : java.type:"boolean" = constant @true; 695 yield %24; 696 } 697 ()java.type:"java.lang.String" -> { 698 %25 : java.type:"java.lang.String" = constant @"default"; 699 yield %25; 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.type:"java.lang.Byte")java.type:"java.lang.String" -> { 718 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a"; 719 %2 : java.type:"int" = constant @2; 720 %3 : java.type:"byte" = conv %2; 721 %4 : Var<java.type:"byte"> = var %3 @"b"; 722 %5 : java.type:"java.lang.Byte" = var.load %1; 723 %6 : java.type:"java.lang.String" = java.switch.expression %5 724 (%7 : java.type:"java.lang.Byte")java.type:"boolean" -> { 725 %8 : java.type:"int" = constant @1; 726 %9 : java.type:"byte" = conv %8; 727 %10 : java.type:"java.lang.Byte" = invoke %9 @java.ref:"java.lang.Byte::valueOf(byte):java.lang.Byte"; 728 %11 : java.type:"boolean" = invoke %7 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 729 yield %11; 730 } 731 ()java.type:"java.lang.String" -> { 732 %12 : java.type:"java.lang.String" = constant @"one"; 733 yield %12; 734 } 735 (%13 : java.type:"java.lang.Byte")java.type:"boolean" -> { 736 %14 : java.type:"byte" = var.load %4; 737 %15 : java.type:"java.lang.Byte" = invoke %14 @java.ref:"java.lang.Byte::valueOf(byte):java.lang.Byte"; 738 %16 : java.type:"boolean" = invoke %13 %15 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 739 yield %16; 740 } 741 ()java.type:"java.lang.String" -> { 742 %17 : java.type:"java.lang.String" = constant @"two"; 743 yield %17; 744 } 745 ()java.type:"boolean" -> { 746 %18 : java.type:"boolean" = constant @true; 747 yield %18; 748 } 749 ()java.type:"java.lang.String" -> { 750 %19 : java.type:"java.lang.String" = constant @"default"; 751 yield %19; 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 : java.type:"SwitchExpressionTest2$E")java.type:"java.lang.String" -> { 770 %1 : Var<java.type:"SwitchExpressionTest2$E"> = var %0 @"e"; 771 %2 : java.type:"SwitchExpressionTest2$E" = var.load %1; 772 %3 : java.type:"java.lang.String" = java.switch.expression %2 773 (%4 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> { 774 %5 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::F:SwitchExpressionTest2$E"; 775 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 776 yield %6; 777 } 778 ()java.type:"java.lang.String" -> { 779 %7 : java.type:"java.lang.String" = constant @"f"; 780 yield %7; 781 } 782 (%8 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> { 783 %9 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::G:SwitchExpressionTest2$E"; 784 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 785 yield %10; 786 } 787 ()java.type:"java.lang.String" -> { 788 %11 : java.type:"java.lang.String" = constant @"g"; 789 yield %11; 790 } 791 ()java.type:"boolean" -> { 792 %12 : java.type:"boolean" = constant @true; 793 yield %12; 794 } 795 ()java.type:"java.lang.String" -> { 796 %13 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()"; 797 throw %13; 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.type:"java.lang.String")java.type:"java.lang.String" -> { 812 %1 : Var<java.type:"java.lang.String"> = var %0 @"s"; 813 %2 : java.type:"java.lang.String" = var.load %1; 814 %3 : java.type:"java.lang.Object" = constant @null; 815 %4 : Var<java.type:"java.lang.Object"> = var %3 @"o"; 816 %5 : java.type:"java.lang.String" = java.switch.expression %2 817 (%6 : java.type:"java.lang.String")java.type:"boolean" -> { 818 %7 : java.type:"java.lang.String" = constant @"A"; 819 %8 : java.type:"boolean" = invoke %6 %7 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 820 yield %8; 821 } 822 ()java.type:"java.lang.String" -> { 823 %9 : java.type:"java.lang.String" = constant @"Alphabet"; 824 yield %9; 825 } 826 (%10 : java.type:"java.lang.String")java.type:"boolean" -> { 827 %11 : java.type:"boolean" = pattern.match %10 828 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Object>" -> { 829 %12 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Object>" = pattern.type @"o"; 830 yield %12; 831 } 832 (%13 : java.type:"java.lang.Object")java.type:"void" -> { 833 var.store %4 %13; 834 yield; 835 }; 836 yield %11; 837 } 838 ()java.type:"java.lang.String" -> { 839 %14 : java.type:"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 : java.type:"SwitchExpressionTest2$A")java.type:"java.lang.String" -> { 858 %1 : Var<java.type:"SwitchExpressionTest2$A"> = var %0 @"a"; 859 %2 : java.type:"SwitchExpressionTest2$A" = var.load %1; 860 %3 : java.type:"SwitchExpressionTest2$B" = constant @null; 861 %4 : Var<java.type:"SwitchExpressionTest2$B"> = var %3 @"b"; 862 %5 : java.type:"SwitchExpressionTest2::C" = constant @null; 863 %6 : Var<java.type:"SwitchExpressionTest2::C"> = var %5 @"c"; 864 %7 : java.type:"java.lang.String" = java.switch.expression %2 865 (%8 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> { 866 %9 : java.type:"boolean" = pattern.match %8 867 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<SwitchExpressionTest2$B>" -> { 868 %10 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<SwitchExpressionTest2$B>" = pattern.type @"b"; 869 yield %10; 870 } 871 (%11 : java.type:"SwitchExpressionTest2$B")java.type:"void" -> { 872 var.store %4 %11; 873 yield; 874 }; 875 yield %9; 876 } 877 ()java.type:"java.lang.String" -> { 878 %12 : java.type:"java.lang.String" = constant @"B"; 879 yield %12; 880 } 881 (%13 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> { 882 %14 : java.type:"boolean" = pattern.match %13 883 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<SwitchExpressionTest2::C>" -> { 884 %15 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<SwitchExpressionTest2::C>" = pattern.type @"c"; 885 yield %15; 886 } 887 (%16 : java.type:"SwitchExpressionTest2::C")java.type:"void" -> { 888 var.store %6 %16; 889 yield; 890 }; 891 yield %14; 892 } 893 ()java.type:"java.lang.String" -> { 894 %17 : java.type:"java.lang.String" = constant @"C"; 895 yield %17; 896 } 897 ()java.type:"boolean" -> { 898 %18 : java.type:"boolean" = constant @true; 899 yield %18; 900 } 901 ()java.type:"java.lang.String" -> { 902 %19 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()"; 903 throw %19; 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.type:"java.lang.String")java.type:"java.lang.String" -> { 918 %1 : Var<java.type:"java.lang.String"> = var %0 @"s"; 919 %2 : java.type:"java.lang.String" = var.load %1; 920 %3 : java.type:"java.lang.String" = java.switch.expression %2 921 (%4 : java.type:"java.lang.String")java.type:"boolean" -> { 922 %5 : java.type:"java.lang.String" = constant @"M"; 923 %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 924 yield %6; 925 } 926 ()java.type:"java.lang.String" -> { 927 %7 : java.type:"java.lang.String" = constant @"Mow"; 928 yield %7; 929 } 930 (%8 : java.type:"java.lang.String")java.type:"boolean" -> { 931 %9 : java.type:"java.lang.String" = constant @"A"; 932 %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean"; 933 yield %10; 934 } 935 ()java.type:"java.lang.String" -> { 936 %11 : java.type:"java.lang.String" = constant @"Aow"; 937 yield %11; 938 } 939 ()java.type:"boolean" -> { 940 %12 : java.type:"boolean" = constant @true; 941 yield %12; 942 } 943 ()java.type:"java.lang.String" -> { 944 %13 : java.type:"java.lang.String" = constant @"else"; 945 yield %13; 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 }