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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
48 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
74 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
113 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Record<PatternsTest$Rectangle>" -> {
171 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<PatternsTest$ConcretePoint>" = pattern.type @"p";
172 %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<PatternsTest$Color>" = pattern.type @"c";
173 %13 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<PatternsTest$ColoredPoint>" = pattern.type @"lr";
175 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
232 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
270 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" -> {
317 %14 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
360 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Record<PatternsTest$Rectangle>" -> {
383 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$MatchAll" = pattern.match.all;
384 %8 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<PatternsTest$ConcretePoint>" = pattern.type @"cp";
385 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<byte>" -> {
409 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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.dialect.java.JavaOp$Pattern$Type<short>" -> {
433 %7 : java.type:"jdk.incubator.code.dialect.java.JavaOp$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 }