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 : PatternsTest, %1 : java.lang.Object)void -> { 42 %2 : Var<java.lang.Object> = var %1 @"o"; 43 %3 : java.lang.Object = var.load %2; 44 %4 : java.lang.String = constant @null; 45 %5 : Var<java.lang.String> = var %4 @"s"; 46 %6 : boolean = pattern.match %3 47 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 48 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type @"s"; 49 yield %7; 50 } 51 ^match(%8 : java.lang.String)void -> { 52 var.store %5 %8; 53 yield; 54 }; 55 %9 : Var<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 : PatternsTest, %1 : java.lang.Object)java.lang.String -> { 66 %2 : Var<java.lang.Object> = var %1 @"o"; 67 %3 : java.lang.String = constant @null; 68 %4 : Var<java.lang.String> = var %3 @"s"; 69 java.if 70 ()boolean -> { 71 %5 : java.lang.Object = var.load %2; 72 %6 : boolean = pattern.match %5 73 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 74 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type @"s"; 75 yield %7; 76 } 77 ^match(%8 : java.lang.String)void -> { 78 var.store %4 %8; 79 yield; 80 }; 81 yield %6; 82 } 83 ^then()void -> { 84 %9 : java.lang.String = var.load %4; 85 return %9; 86 } 87 ^else()void -> { 88 %10 : 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 : PatternsTest, %1 : java.lang.Object)java.lang.String -> { 105 %2 : Var<java.lang.Object> = var %1 @"o"; 106 %3 : java.lang.String = constant @null; 107 %4 : Var<java.lang.String> = var %3 @"s"; 108 java.if 109 ()boolean -> { 110 %5 : java.lang.Object = var.load %2; 111 %6 : boolean = pattern.match %5 112 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 113 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type @"s"; 114 yield %7; 115 } 116 ^match(%8 : java.lang.String)void -> { 117 var.store %4 %8; 118 yield; 119 }; 120 %9 : boolean = not %6; 121 yield %9; 122 } 123 ^then()void -> { 124 %10 : java.lang.String = constant @""; 125 return %10; 126 } 127 ^else()void -> { 128 yield; 129 }; 130 %11 : 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 : PatternsTest, %1 : PatternsTest$Rectangle)void -> { 159 %2 : Var<PatternsTest$Rectangle> = var %1 @"r"; 160 %3 : PatternsTest$ConcretePoint = constant @null; 161 %4 : Var<PatternsTest$ConcretePoint> = var %3 @"p"; 162 %5 : PatternsTest$Color = constant @null; 163 %6 : Var<PatternsTest$Color> = var %5 @"c"; 164 %7 : PatternsTest$ColoredPoint = constant @null; 165 %8 : Var<PatternsTest$ColoredPoint> = var %7 @"lr"; 166 java.if 167 ()boolean -> { 168 %9 : PatternsTest$Rectangle = var.load %2; 169 %10 : boolean = pattern.match %9 170 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> -> { 171 %11 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ConcretePoint> = pattern.type @"p"; 172 %12 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$Color> = pattern.type @"c"; 173 %13 : jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$ColoredPoint> = pattern.record %11 %12 @"(PatternsTest$ConcretePoint p, PatternsTest$Color c)PatternsTest$ColoredPoint"; 174 %14 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ColoredPoint> = pattern.type @"lr"; 175 %15 : jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> = pattern.record %13 %14 @"(PatternsTest$Point upperLeft, PatternsTest$Point lowerRight)PatternsTest$Rectangle"; 176 yield %15; 177 } 178 ^match(%16 : PatternsTest$ConcretePoint, %17 : PatternsTest$Color, %18 : PatternsTest$ColoredPoint)void -> { 179 var.store %4 %16; 180 var.store %6 %17; 181 var.store %8 %18; 182 yield; 183 }; 184 yield %10; 185 } 186 ^then()void -> { 187 %19 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 188 %20 : PatternsTest$ConcretePoint = var.load %4; 189 invoke %19 %20 @"java.io.PrintStream::println(java.lang.Object)void"; 190 %21 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 191 %22 : PatternsTest$Color = var.load %6; 192 invoke %21 %22 @"java.io.PrintStream::println(java.lang.Object)void"; 193 %23 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 194 %24 : PatternsTest$ColoredPoint = var.load %8; 195 invoke %23 %24 @"java.io.PrintStream::println(java.lang.Object)void"; 196 yield; 197 } 198 ^else()void -> { 199 %25 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 200 %26 : java.lang.String = constant @"NO MATCH"; 201 invoke %25 %26 @"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 : PatternsTest, %1 : java.lang.Object)void -> { 224 %2 : Var<java.lang.Object> = var %1 @"o"; 225 %3 : java.lang.String = constant @null; 226 %4 : Var<java.lang.String> = var %3 @"s"; 227 java.while 228 ^cond()boolean -> { 229 %5 : java.lang.Object = var.load %2; 230 %6 : boolean = pattern.match %5 231 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 232 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type @"s"; 233 yield %7; 234 } 235 ^match(%8 : java.lang.String)void -> { 236 var.store %4 %8; 237 yield; 238 }; 239 yield %6; 240 } 241 ^body()void -> { 242 %9 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 243 %10 : java.lang.String = var.load %4; 244 invoke %9 %10 @"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 : PatternsTest, %1 : java.lang.Object)void -> { 259 %2 : Var<java.lang.Object> = var %1 @"o"; 260 %3 : java.lang.String = constant @null; 261 %4 : Var<java.lang.String> = var %3 @"s"; 262 java.do.while 263 ^body()void -> { 264 java.continue; 265 } 266 ^cond()boolean -> { 267 %5 : java.lang.Object = var.load %2; 268 %6 : boolean = pattern.match %5 269 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 270 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type @"s"; 271 yield %7; 272 } 273 ^match(%8 : java.lang.String)void -> { 274 var.store %4 %8; 275 yield; 276 }; 277 %9 : boolean = not %6; 278 yield %9; 279 }; 280 %10 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 281 %11 : java.lang.String = var.load %4; 282 invoke %10 %11 @"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 : PatternsTest, %1 : java.lang.Object)void -> { 296 %2 : Var<java.lang.Object> = var %1 @"o"; 297 %3 : java.lang.Number = constant @null; 298 %4 : Var<java.lang.Number> = var %3 @"n"; 299 java.for 300 ^init()Var<int> -> { 301 %5 : int = constant @"0"; 302 %6 : Var<int> = var %5 @"i"; 303 yield %6; 304 } 305 ^cond(%7 : Var<int>)boolean -> { 306 %8 : boolean = java.cand 307 ()boolean -> { 308 %9 : int = var.load %7; 309 %10 : int = constant @"10"; 310 %11 : boolean = lt %9 %10; 311 yield %11; 312 } 313 ()boolean -> { 314 %12 : java.lang.Object = var.load %2; 315 %13 : boolean = pattern.match %12 316 ^pattern()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Number> -> { 317 %14 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.Number> = pattern.type @"n"; 318 yield %14; 319 } 320 ^match(%15 : java.lang.Number)void -> { 321 var.store %4 %15; 322 yield; 323 }; 324 yield %13; 325 }; 326 yield %8; 327 } 328 ^update(%16 : Var<int>)void -> { 329 %17 : int = var.load %16; 330 %18 : java.lang.Number = var.load %4; 331 %19 : int = invoke %18 @"java.lang.Number::intValue()int"; 332 %20 : int = add %17 %19; 333 var.store %16 %20; 334 yield; 335 } 336 ^body(%21 : Var<int>)void -> { 337 %22 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 338 %23 : java.lang.Number = var.load %4; 339 invoke %22 %23 @"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 : PatternsTest, %1 : java.lang.Object)boolean -> { 354 %2 : Var<java.lang.Object> = var %1 @"o"; 355 %3 : java.lang.Object = var.load %2; 356 %4 : java.lang.String = constant @null; 357 %5 : Var<java.lang.String> = var %4; 358 %6 : boolean = pattern.match %3 359 ()jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> -> { 360 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<java.lang.String> = pattern.type; 361 yield %7; 362 } 363 (%8 : java.lang.String)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 : PatternsTest, %1 : java.lang.Object)boolean -> { 377 %2 : Var<java.lang.Object> = var %1 @"o"; 378 %3 : java.lang.Object = var.load %2; 379 %4 : PatternsTest$ConcretePoint = constant @null; 380 %5 : Var<PatternsTest$ConcretePoint> = var %4 @"cp"; 381 %6 : boolean = pattern.match %3 382 ()jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> -> { 383 %7 : jdk.incubator.code.op.ExtendedOp$Pattern$MatchAll = pattern.match.all; 384 %8 : jdk.incubator.code.op.ExtendedOp$Pattern$Type<PatternsTest$ConcretePoint> = pattern.type @"cp"; 385 %9 : jdk.incubator.code.op.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> = pattern.record %7 %8 @"(PatternsTest$Point upperLeft, PatternsTest$Point lowerRight)PatternsTest$Rectangle"; 386 yield %9; 387 } 388 (%10 : PatternsTest$ConcretePoint)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 }