1 /* 2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import jdk.incubator.code.CodeReflection; 25 26 27 /* 28 * @test 29 * @summary Smoke test for code reflection with patterns. 30 * @modules jdk.incubator.code 31 * @enablePreview 32 * @build PatternsTest 33 * @build CodeReflectionTester 34 * @run main CodeReflectionTester PatternsTest 35 */ 36 37 public class PatternsTest { 38 39 @CodeReflection 40 @IR(""" 41 func @"test1" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"void" -> { 42 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 43 %3 : java.type:"java.lang.Object" = var.load %2; 44 %4 : java.type:"java.lang.String" = constant @null; 45 %5 : Var<java.type:"java.lang.String"> = var %4 @"s"; 46 %6 : java.type:"boolean" = pattern.match %3 47 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 48 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type @"s"; 49 yield %7; 50 } 51 (%8 : java.type:"java.lang.String")java.type:"void" -> { 52 var.store %5 %8; 53 yield; 54 }; 55 %9 : Var<java.type:"boolean"> = var %6 @"x"; 56 return; 57 }; 58 """) 59 void test1(Object o) { 60 boolean x = o instanceof String s; 61 } 62 63 @CodeReflection 64 @IR(""" 65 func @"test2" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"java.lang.String" -> { 66 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 67 %3 : java.type:"java.lang.String" = constant @null; 68 %4 : Var<java.type:"java.lang.String"> = var %3 @"s"; 69 java.if 70 ()java.type:"boolean" -> { 71 %5 : java.type:"java.lang.Object" = var.load %2; 72 %6 : java.type:"boolean" = pattern.match %5 73 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 74 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type @"s"; 75 yield %7; 76 } 77 (%8 : java.type:"java.lang.String")java.type:"void" -> { 78 var.store %4 %8; 79 yield; 80 }; 81 yield %6; 82 } 83 ()java.type:"void" -> { 84 %9 : java.type:"java.lang.String" = var.load %4; 85 return %9; 86 } 87 ()java.type:"void" -> { 88 %10 : java.type:"java.lang.String" = constant @""; 89 return %10; 90 }; 91 unreachable; 92 }; 93 """) 94 String test2(Object o) { 95 if (o instanceof String s) { 96 return s; 97 } else { 98 return ""; 99 } 100 } 101 102 @CodeReflection 103 @IR(""" 104 func @"test3" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"java.lang.String" -> { 105 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 106 %3 : java.type:"java.lang.String" = constant @null; 107 %4 : Var<java.type:"java.lang.String"> = var %3 @"s"; 108 java.if 109 ()java.type:"boolean" -> { 110 %5 : java.type:"java.lang.Object" = var.load %2; 111 %6 : java.type:"boolean" = pattern.match %5 112 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 113 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type @"s"; 114 yield %7; 115 } 116 (%8 : java.type:"java.lang.String")java.type:"void" -> { 117 var.store %4 %8; 118 yield; 119 }; 120 %9 : java.type:"boolean" = not %6; 121 yield %9; 122 } 123 ()java.type:"void" -> { 124 %10 : java.type:"java.lang.String" = constant @""; 125 return %10; 126 } 127 ()java.type:"void" -> { 128 yield; 129 }; 130 %11 : java.type:"java.lang.String" = var.load %4; 131 return %11; 132 }; 133 """) 134 String test3(Object o) { 135 if (!(o instanceof String s)) { 136 return ""; 137 } 138 return s; 139 } 140 141 interface Point { 142 } 143 144 record ConcretePoint(int x, int y) implements Point { 145 } 146 147 enum Color {RED, GREEN, BLUE} 148 149 record ColoredPoint(ConcretePoint p, Color c) implements Point { 150 } 151 152 record Rectangle(Point upperLeft, Point lowerRight) { 153 } 154 155 156 @CodeReflection 157 @IR(""" 158 func @"test4" (%0 : java.type:"PatternsTest", %1 : java.type:"PatternsTest$Rectangle")java.type:"void" -> { 159 %2 : Var<java.type:"PatternsTest$Rectangle"> = var %1 @"r"; 160 %3 : java.type:"PatternsTest$ConcretePoint" = constant @null; 161 %4 : Var<java.type:"PatternsTest$ConcretePoint"> = var %3 @"p"; 162 %5 : java.type:"PatternsTest$Color" = constant @null; 163 %6 : Var<java.type:"PatternsTest$Color"> = var %5 @"c"; 164 %7 : java.type:"PatternsTest$ColoredPoint" = constant @null; 165 %8 : Var<java.type:"PatternsTest$ColoredPoint"> = var %7 @"lr"; 166 java.if 167 ()java.type:"boolean" -> { 168 %9 : java.type:"PatternsTest$Rectangle" = var.load %2; 169 %10 : java.type:"boolean" = pattern.match %9 170 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle>" -> { 171 %11 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ConcretePoint>" = pattern.type @"p"; 172 %12 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$Color>" = pattern.type @"c"; 173 %13 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$ColoredPoint>" = pattern.record %11 %12 @java.ref:"(PatternsTest$ConcretePoint p, PatternsTest$Color c)PatternsTest$ColoredPoint"; 174 %14 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ColoredPoint>" = pattern.type @"lr"; 175 %15 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle>" = pattern.record %13 %14 @java.ref:"(PatternsTest$Point upperLeft, PatternsTest$Point lowerRight)PatternsTest$Rectangle"; 176 yield %15; 177 } 178 (%16 : java.type:"PatternsTest$ConcretePoint", %17 : java.type:"PatternsTest$Color", %18 : java.type:"PatternsTest$ColoredPoint")java.type:"void" -> { 179 var.store %4 %16; 180 var.store %6 %17; 181 var.store %8 %18; 182 yield; 183 }; 184 yield %10; 185 } 186 ()java.type:"void" -> { 187 %19 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 188 %20 : java.type:"PatternsTest$ConcretePoint" = var.load %4; 189 invoke %19 %20 @java.ref:"java.io.PrintStream::println(java.lang.Object):void"; 190 %21 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 191 %22 : java.type:"PatternsTest$Color" = var.load %6; 192 invoke %21 %22 @java.ref:"java.io.PrintStream::println(java.lang.Object):void"; 193 %23 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 194 %24 : java.type:"PatternsTest$ColoredPoint" = var.load %8; 195 invoke %23 %24 @java.ref:"java.io.PrintStream::println(java.lang.Object):void"; 196 yield; 197 } 198 ()java.type:"void" -> { 199 %25 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 200 %26 : java.type:"java.lang.String" = constant @"NO MATCH"; 201 invoke %25 %26 @java.ref:"java.io.PrintStream::println(java.lang.String):void"; 202 yield; 203 }; 204 return; 205 }; 206 """) 207 void test4(Rectangle r) { 208 if (r instanceof Rectangle( 209 ColoredPoint(ConcretePoint p, Color c), 210 ColoredPoint lr)){ 211 System.out.println(p); 212 System.out.println(c); 213 System.out.println(lr); 214 } 215 else { 216 System.out.println("NO MATCH"); 217 } 218 } 219 220 221 @CodeReflection 222 @IR(""" 223 func @"test5" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"void" -> { 224 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 225 %3 : java.type:"java.lang.String" = constant @null; 226 %4 : Var<java.type:"java.lang.String"> = var %3 @"s"; 227 java.while 228 ()java.type:"boolean" -> { 229 %5 : java.type:"java.lang.Object" = var.load %2; 230 %6 : java.type:"boolean" = pattern.match %5 231 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 232 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type @"s"; 233 yield %7; 234 } 235 (%8 : java.type:"java.lang.String")java.type:"void" -> { 236 var.store %4 %8; 237 yield; 238 }; 239 yield %6; 240 } 241 ()java.type:"void" -> { 242 %9 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 243 %10 : java.type:"java.lang.String" = var.load %4; 244 invoke %9 %10 @java.ref:"java.io.PrintStream::println(java.lang.String):void"; 245 java.continue; 246 }; 247 return; 248 }; 249 """) 250 void test5(Object o) { 251 while (o instanceof String s) { 252 System.out.println(s); 253 } 254 } 255 256 @CodeReflection 257 @IR(""" 258 func @"test6" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"void" -> { 259 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 260 %3 : java.type:"java.lang.String" = constant @null; 261 %4 : Var<java.type:"java.lang.String"> = var %3 @"s"; 262 java.do.while 263 ()java.type:"void" -> { 264 java.continue; 265 } 266 ()java.type:"boolean" -> { 267 %5 : java.type:"java.lang.Object" = var.load %2; 268 %6 : java.type:"boolean" = pattern.match %5 269 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 270 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type @"s"; 271 yield %7; 272 } 273 (%8 : java.type:"java.lang.String")java.type:"void" -> { 274 var.store %4 %8; 275 yield; 276 }; 277 %9 : java.type:"boolean" = not %6; 278 yield %9; 279 }; 280 %10 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 281 %11 : java.type:"java.lang.String" = var.load %4; 282 invoke %10 %11 @java.ref:"java.io.PrintStream::println(java.lang.String):void"; 283 return; 284 }; 285 """) 286 void test6(Object o) { 287 do { 288 } while (!(o instanceof String s)); 289 System.out.println(s); 290 } 291 292 293 @CodeReflection 294 @IR(""" 295 func @"test7" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"void" -> { 296 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 297 %3 : java.type:"java.lang.Number" = constant @null; 298 %4 : Var<java.type:"java.lang.Number"> = var %3 @"n"; 299 java.for 300 ()Var<java.type:"int"> -> { 301 %5 : java.type:"int" = constant @0; 302 %6 : Var<java.type:"int"> = var %5 @"i"; 303 yield %6; 304 } 305 (%7 : Var<java.type:"int">)java.type:"boolean" -> { 306 %8 : java.type:"boolean" = java.cand 307 ()java.type:"boolean" -> { 308 %9 : java.type:"int" = var.load %7; 309 %10 : java.type:"int" = constant @10; 310 %11 : java.type:"boolean" = lt %9 %10; 311 yield %11; 312 } 313 ()java.type:"boolean" -> { 314 %12 : java.type:"java.lang.Object" = var.load %2; 315 %13 : java.type:"boolean" = pattern.match %12 316 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Number>" -> { 317 %14 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Number>" = pattern.type @"n"; 318 yield %14; 319 } 320 (%15 : java.type:"java.lang.Number")java.type:"void" -> { 321 var.store %4 %15; 322 yield; 323 }; 324 yield %13; 325 }; 326 yield %8; 327 } 328 (%16 : Var<java.type:"int">)java.type:"void" -> { 329 %17 : java.type:"int" = var.load %16; 330 %18 : java.type:"java.lang.Number" = var.load %4; 331 %19 : java.type:"int" = invoke %18 @java.ref:"java.lang.Number::intValue():int"; 332 %20 : java.type:"int" = add %17 %19; 333 var.store %16 %20; 334 yield; 335 } 336 (%21 : Var<java.type:"int">)java.type:"void" -> { 337 %22 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 338 %23 : java.type:"java.lang.Number" = var.load %4; 339 invoke %22 %23 @java.ref:"java.io.PrintStream::println(java.lang.Object):void"; 340 java.continue; 341 }; 342 return; 343 }; 344 """) 345 void test7(Object o) { 346 for (int i = 0; 347 i < 10 && o instanceof Number n; i += n.intValue()) { 348 System.out.println(n); 349 } 350 } 351 352 @IR(""" 353 func @"test8" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"boolean" -> { 354 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 355 %3 : java.type:"java.lang.Object" = var.load %2; 356 %4 : java.type:"java.lang.String" = constant @null; 357 %5 : Var<java.type:"java.lang.String"> = var %4; 358 %6 : java.type:"boolean" = pattern.match %3 359 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" -> { 360 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String>" = pattern.type; 361 yield %7; 362 } 363 (%8 : java.type:"java.lang.String")java.type:"void" -> { 364 var.store %5 %8; 365 yield; 366 }; 367 return %6; 368 }; 369 """) 370 @CodeReflection 371 boolean test8(Object o) { 372 return o instanceof String _; 373 } 374 375 @IR(""" 376 func @"test9" (%0 : java.type:"PatternsTest", %1 : java.type:"java.lang.Object")java.type:"boolean" -> { 377 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o"; 378 %3 : java.type:"java.lang.Object" = var.load %2; 379 %4 : java.type:"PatternsTest$ConcretePoint" = constant @null; 380 %5 : Var<java.type:"PatternsTest$ConcretePoint"> = var %4 @"cp"; 381 %6 : java.type:"boolean" = pattern.match %3 382 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle>" -> { 383 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$MatchAll" = pattern.match.all; 384 %8 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ConcretePoint>" = pattern.type @"cp"; 385 %9 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle>" = pattern.record %7 %8 @java.ref:"(PatternsTest$Point upperLeft, PatternsTest$Point lowerRight)PatternsTest$Rectangle"; 386 yield %9; 387 } 388 (%10 : java.type:"PatternsTest$ConcretePoint")java.type:"void" -> { 389 var.store %5 %10; 390 yield; 391 }; 392 return %6; 393 }; 394 """) 395 @CodeReflection 396 boolean test9(Object o) { 397 return o instanceof Rectangle(_, ConcretePoint cp); 398 } 399 400 @IR(""" 401 func @"test10" (%0 : java.type:"int")java.type:"boolean" -> { 402 %1 : Var<java.type:"int"> = var %0 @"i"; 403 %2 : java.type:"int" = var.load %1; 404 %3 : java.type:"int" = constant @0; 405 %4 : java.type:"byte" = conv %3; 406 %5 : Var<java.type:"byte"> = var %4 @"b"; 407 %6 : java.type:"boolean" = pattern.match %2 408 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<byte>" -> { 409 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<byte>" = pattern.type @"b"; 410 yield %7; 411 } 412 (%8 : java.type:"byte")java.type:"void" -> { 413 var.store %5 %8; 414 yield; 415 }; 416 return %6; 417 }; 418 """) 419 @CodeReflection 420 static boolean test10(int i) { 421 return i instanceof byte b; 422 } 423 424 @IR(""" 425 func @"test11" (%0 : java.type:"int")java.type:"boolean" -> { 426 %1 : Var<java.type:"int"> = var %0 @"i"; 427 %2 : java.type:"int" = var.load %1; 428 %3 : java.type:"int" = constant @0; 429 %4 : java.type:"short" = conv %3; 430 %5 : Var<java.type:"short"> = var %4 @"s"; 431 %6 : java.type:"boolean" = pattern.match %2 432 ()java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<short>" -> { 433 %7 : java.type:"jdk.incubator.code.op.ExtendedOp$Pattern$Type<short>" = pattern.type @"s"; 434 yield %7; 435 } 436 (%8 : java.type:"short")java.type:"void" -> { 437 var.store %5 %8; 438 yield; 439 }; 440 return %6; 441 }; 442 """) 443 @CodeReflection 444 static boolean test11(int i) { 445 return i instanceof short s; 446 } 447 }