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 java.lang.runtime.CodeReflection; 25 26 27 /* 28 * @test 29 * @summary Smoke test for code reflection with patterns. 30 * @enablePreview 31 * @build PatternsTest 32 * @build CodeReflectionTester 33 * @run main CodeReflectionTester PatternsTest 34 */ 35 36 public class PatternsTest { 37 38 @CodeReflection 39 @IR(""" 40 func @"test1" (%0 : PatternsTest, %1 : java.lang.Object)void -> { 41 %2 : Var<java.lang.Object> = var %1 @"o"; 42 %3 : java.lang.Object = var.load %2; 43 %4 : java.lang.String = constant @null; 44 %5 : Var<java.lang.String> = var %4 @"s"; 45 %6 : boolean = pattern.match %3 46 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 47 %7 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 48 yield %7; 49 } 50 ^match(%8 : java.lang.String)void -> { 51 var.store %5 %8; 52 yield; 53 }; 54 %9 : Var<boolean> = var %6 @"x"; 55 return; 56 }; 57 """) 58 void test1(Object o) { 59 boolean x = o instanceof String s; 60 } 61 62 @CodeReflection 63 @IR(""" 64 func @"test2" (%0 : PatternsTest, %1 : java.lang.Object)java.lang.String -> { 65 %2 : Var<java.lang.Object> = var %1 @"o"; 66 %3 : java.lang.String = constant @null; 67 %4 : Var<java.lang.String> = var %3 @"s"; 68 java.if 69 ()boolean -> { 70 %5 : java.lang.Object = var.load %2; 71 %6 : boolean = pattern.match %5 72 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 73 %7 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 74 yield %7; 75 } 76 ^match(%8 : java.lang.String)void -> { 77 var.store %4 %8; 78 yield; 79 }; 80 yield %6; 81 } 82 ^then()void -> { 83 %9 : java.lang.String = var.load %4; 84 return %9; 85 } 86 ^else()void -> { 87 %10 : java.lang.String = constant @""; 88 return %10; 89 }; 90 return; 91 }; 92 """) 93 String test2(Object o) { 94 if (o instanceof String s) { 95 return s; 96 } else { 97 return ""; 98 } 99 } 100 101 @CodeReflection 102 @IR(""" 103 func @"test3" (%0 : PatternsTest, %1 : java.lang.Object)java.lang.String -> { 104 %2 : Var<java.lang.Object> = var %1 @"o"; 105 %3 : java.lang.String = constant @null; 106 %4 : Var<java.lang.String> = var %3 @"s"; 107 java.if 108 ()boolean -> { 109 %5 : java.lang.Object = var.load %2; 110 %6 : boolean = pattern.match %5 111 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 112 %7 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 113 yield %7; 114 } 115 ^match(%8 : java.lang.String)void -> { 116 var.store %4 %8; 117 yield; 118 }; 119 %9 : boolean = not %6; 120 yield %9; 121 } 122 ^then()void -> { 123 %10 : java.lang.String = constant @""; 124 return %10; 125 } 126 ^else()void -> { 127 yield; 128 }; 129 %11 : java.lang.String = var.load %4; 130 return %11; 131 }; 132 """) 133 String test3(Object o) { 134 if (!(o instanceof String s)) { 135 return ""; 136 } 137 return s; 138 } 139 140 interface Point { 141 } 142 143 record ConcretePoint(int x, int y) implements Point { 144 } 145 146 enum Color {RED, GREEN, BLUE} 147 148 record ColoredPoint(ConcretePoint p, Color c) implements Point { 149 } 150 151 record Rectangle(Point upperLeft, Point lowerRight) { 152 } 153 154 155 @CodeReflection 156 @IR(""" 157 func @"test4" (%0 : PatternsTest, %1 : PatternsTest$Rectangle)void -> { 158 %2 : Var<PatternsTest$Rectangle> = var %1 @"r"; 159 %3 : PatternsTest$ConcretePoint = constant @null; 160 %4 : Var<PatternsTest$ConcretePoint> = var %3 @"p"; 161 %5 : PatternsTest$Color = constant @null; 162 %6 : Var<PatternsTest$Color> = var %5 @"c"; 163 %7 : PatternsTest$ColoredPoint = constant @null; 164 %8 : Var<PatternsTest$ColoredPoint> = var %7 @"lr"; 165 java.if 166 ()boolean -> { 167 %9 : PatternsTest$Rectangle = var.load %2; 168 %10 : boolean = pattern.match %9 169 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> -> { 170 %11 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<PatternsTest$ConcretePoint> = pattern.binding @"p"; 171 %12 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<PatternsTest$Color> = pattern.binding @"c"; 172 %13 : java.lang.reflect.code.ExtendedOp$Pattern$Record<PatternsTest$ColoredPoint> = pattern.record %11 %12 @"(PatternsTest$ConcretePoint p, PatternsTest$Color c)PatternsTest$ColoredPoint"; 173 %14 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<PatternsTest$ColoredPoint> = pattern.binding @"lr"; 174 %15 : java.lang.reflect.code.ExtendedOp$Pattern$Record<PatternsTest$Rectangle> = pattern.record %13 %14 @"(PatternsTest$Point upperLeft, PatternsTest$Point lowerRight)PatternsTest$Rectangle"; 175 yield %15; 176 } 177 ^match(%16 : PatternsTest$ConcretePoint, %17 : PatternsTest$Color, %18 : PatternsTest$ColoredPoint)void -> { 178 var.store %4 %16; 179 var.store %6 %17; 180 var.store %8 %18; 181 yield; 182 }; 183 yield %10; 184 } 185 ^then()void -> { 186 %19 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 187 %20 : PatternsTest$ConcretePoint = var.load %4; 188 invoke %19 %20 @"java.io.PrintStream::println(java.lang.Object)void"; 189 %21 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 190 %22 : PatternsTest$Color = var.load %6; 191 invoke %21 %22 @"java.io.PrintStream::println(java.lang.Object)void"; 192 %23 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 193 %24 : PatternsTest$ColoredPoint = var.load %8; 194 invoke %23 %24 @"java.io.PrintStream::println(java.lang.Object)void"; 195 yield; 196 } 197 ^else()void -> { 198 %25 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 199 %26 : java.lang.String = constant @"NO MATCH"; 200 invoke %25 %26 @"java.io.PrintStream::println(java.lang.String)void"; 201 yield; 202 }; 203 return; 204 }; 205 """) 206 void test4(Rectangle r) { 207 if (r instanceof Rectangle( 208 ColoredPoint(ConcretePoint p, Color c), 209 ColoredPoint lr)){ 210 System.out.println(p); 211 System.out.println(c); 212 System.out.println(lr); 213 } 214 else { 215 System.out.println("NO MATCH"); 216 } 217 } 218 219 220 @CodeReflection 221 @IR(""" 222 func @"test5" (%0 : PatternsTest, %1 : java.lang.Object)void -> { 223 %2 : Var<java.lang.Object> = var %1 @"o"; 224 %3 : java.lang.String = constant @null; 225 %4 : Var<java.lang.String> = var %3 @"s"; 226 java.while 227 ^cond()boolean -> { 228 %5 : java.lang.Object = var.load %2; 229 %6 : boolean = pattern.match %5 230 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 231 %7 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 232 yield %7; 233 } 234 ^match(%8 : java.lang.String)void -> { 235 var.store %4 %8; 236 yield; 237 }; 238 yield %6; 239 } 240 ^body()void -> { 241 %9 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 242 %10 : java.lang.String = var.load %4; 243 invoke %9 %10 @"java.io.PrintStream::println(java.lang.String)void"; 244 java.continue; 245 }; 246 return; 247 }; 248 """) 249 void test5(Object o) { 250 while (o instanceof String s) { 251 System.out.println(s); 252 } 253 } 254 255 @CodeReflection 256 @IR(""" 257 func @"test6" (%0 : PatternsTest, %1 : java.lang.Object)void -> { 258 %2 : Var<java.lang.Object> = var %1 @"o"; 259 %3 : java.lang.String = constant @null; 260 %4 : Var<java.lang.String> = var %3 @"s"; 261 java.do.while 262 ^body()void -> { 263 java.continue; 264 } 265 ^cond()boolean -> { 266 %5 : java.lang.Object = var.load %2; 267 %6 : boolean = pattern.match %5 268 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> -> { 269 %7 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.String> = pattern.binding @"s"; 270 yield %7; 271 } 272 ^match(%8 : java.lang.String)void -> { 273 var.store %4 %8; 274 yield; 275 }; 276 %9 : boolean = not %6; 277 yield %9; 278 }; 279 %10 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 280 %11 : java.lang.String = var.load %4; 281 invoke %10 %11 @"java.io.PrintStream::println(java.lang.String)void"; 282 return; 283 }; 284 """) 285 void test6(Object o) { 286 do { 287 } while (!(o instanceof String s)); 288 System.out.println(s); 289 } 290 291 292 @CodeReflection 293 @IR(""" 294 func @"test7" (%0 : PatternsTest, %1 : java.lang.Object)void -> { 295 %2 : Var<java.lang.Object> = var %1 @"o"; 296 %3 : java.lang.Number = constant @null; 297 %4 : Var<java.lang.Number> = var %3 @"n"; 298 java.for 299 ^init()Var<int> -> { 300 %5 : int = constant @"0"; 301 %6 : Var<int> = var %5 @"i"; 302 yield %6; 303 } 304 ^cond(%7 : Var<int>)boolean -> { 305 %8 : boolean = java.cand 306 ()boolean -> { 307 %9 : int = var.load %7; 308 %10 : int = constant @"10"; 309 %11 : boolean = lt %9 %10; 310 yield %11; 311 } 312 ()boolean -> { 313 %12 : java.lang.Object = var.load %2; 314 %13 : boolean = pattern.match %12 315 ^pattern()java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> -> { 316 %14 : java.lang.reflect.code.ExtendedOp$Pattern$Binding<java.lang.Number> = pattern.binding @"n"; 317 yield %14; 318 } 319 ^match(%15 : java.lang.Number)void -> { 320 var.store %4 %15; 321 yield; 322 }; 323 yield %13; 324 }; 325 yield %8; 326 } 327 ^update(%16 : Var<int>)void -> { 328 %17 : int = var.load %16; 329 %18 : java.lang.Number = var.load %4; 330 %19 : int = invoke %18 @"java.lang.Number::intValue()int"; 331 %20 : int = add %17 %19; 332 var.store %16 %20; 333 yield; 334 } 335 ^body(%21 : Var<int>)void -> { 336 %22 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 337 %23 : java.lang.Number = var.load %4; 338 invoke %22 %23 @"java.io.PrintStream::println(java.lang.Object)void"; 339 java.continue; 340 }; 341 return; 342 }; 343 """) 344 void test7(Object o) { 345 for (int i = 0; 346 i < 10 && o instanceof Number n; i += n.intValue()) { 347 System.out.println(n); 348 } 349 } 350 }