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 import java.util.List;
26
27 /*
28 * @test
29 * @summary Smoke test for code reflection with for loops.
30 * @modules jdk.incubator.code
31 * @build ForLoopTest
32 * @build CodeReflectionTester
33 * @run main CodeReflectionTester ForLoopTest
34 */
35
36 public class ForLoopTest {
37 @CodeReflection
38 @IR("""
39 func @"test1" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.util.List<java.lang.String>>")java.type:"void" -> {
40 %2 : Var<java.type:"java.util.List<java.util.List<java.lang.String>>"> = var %1 @"ll";
41 java.enhancedFor
42 ()java.type:"java.util.List<java.util.List<java.lang.String>>" -> {
43 %3 : java.type:"java.util.List<java.util.List<java.lang.String>>" = var.load %2;
44 yield %3;
45 }
46 (%4 : java.type:"java.util.List<java.lang.String>")Var<java.type:"java.util.List<java.lang.String>"> -> {
47 %5 : Var<java.type:"java.util.List<java.lang.String>"> = var %4 @"l";
48 yield %5;
49 }
50 (%6 : Var<java.type:"java.util.List<java.lang.String>">)java.type:"void" -> {
51 java.enhancedFor
52 ()java.type:"java.util.List<java.lang.String>" -> {
53 %7 : java.type:"java.util.List<java.lang.String>" = var.load %6;
54 yield %7;
55 }
56 (%8 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> {
57 %9 : Var<java.type:"java.lang.String"> = var %8 @"s";
58 yield %9;
59 }
60 (%10 : Var<java.type:"java.lang.String">)java.type:"void" -> {
61 %11 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
62 %12 : java.type:"java.lang.String" = var.load %10;
63 invoke %11 %12 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
64 java.continue;
65 };
66 java.continue;
67 };
68 return;
69 };
70 """)
71 void test1(List<List<String>> ll) {
72 for (List<String> l : ll) {
73 for (String s : l) {
74 System.out.println(s);
75 }
76 }
77 }
78
79 @CodeReflection
80 @IR("""
81 func @"test2" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"void" -> {
82 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l";
83 java.enhancedFor
84 ()java.type:"java.util.List<java.lang.String>" -> {
85 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2;
86 %4 : java.type:"java.util.stream.Stream<java.lang.String>" = invoke %3 @java.ref:"java.util.List::stream():java.util.stream.Stream";
87 %5 : java.type:"java.util.function.Predicate<java.lang.String>" = lambda (%6 : java.type:"java.lang.String")java.type:"boolean" -> {
88 %7 : Var<java.type:"java.lang.String"> = var %6 @"s";
89 %8 : java.type:"java.lang.String" = var.load %7;
90 %9 : java.type:"int" = invoke %8 @java.ref:"java.lang.String::length():int";
91 %10 : java.type:"int" = constant @10;
92 %11 : java.type:"boolean" = lt %9 %10;
93 return %11;
94 };
95 %12 : java.type:"java.util.stream.Stream<java.lang.String>" = invoke %4 %5 @java.ref:"java.util.stream.Stream::filter(java.util.function.Predicate):java.util.stream.Stream";
96 %13 : java.type:"java.util.List<java.lang.String>" = invoke %12 @java.ref:"java.util.stream.Stream::toList():java.util.List";
97 yield %13;
98 }
99 (%14 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> {
100 %15 : Var<java.type:"java.lang.String"> = var %14 @"s";
101 yield %15;
102 }
103 (%16 : Var<java.type:"java.lang.String">)java.type:"void" -> {
104 %17 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
105 %18 : java.type:"java.lang.String" = var.load %16;
106 invoke %17 %18 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
107 java.continue;
108 };
109 return;
110 };
111 """)
112 void test2(List<String> l) {
113 for (String s : l.stream().filter(s -> s.length() < 10).toList()) {
114 System.out.println(s);
115 }
116 }
117
118 @CodeReflection
119 @IR("""
120 func @"test2_1" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"void" -> {
121 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l";
122 java.enhancedFor
123 ()java.type:"java.util.List<java.lang.String>" -> {
124 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2;
125 yield %3;
126 }
127 (%4 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> {
128 %5 : Var<java.type:"java.lang.String"> = var %4 @"s";
129 yield %5;
130 }
131 (%6 : Var<java.type:"java.lang.String">)java.type:"void" -> {
132 java.continue;
133 };
134 return;
135 };
136 """)
137 void test2_1(List<String> l) {
138 for (String s : l);
139 }
140
141 @CodeReflection
142 @IR("""
143 func @"test2_2" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"java.lang.String" -> {
144 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l";
145 java.enhancedFor
146 ()java.type:"java.util.List<java.lang.String>" -> {
147 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2;
148 yield %3;
149 }
150 (%4 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> {
151 %5 : Var<java.type:"java.lang.String"> = var %4 @"s";
152 yield %5;
153 }
154 (%6 : Var<java.type:"java.lang.String">)java.type:"void" -> {
155 %7 : java.type:"java.lang.String" = var.load %6;
156 return %7;
157 };
158 %8 : java.type:"java.lang.String" = constant @"";
159 return %8;
160 };
161 """)
162 String test2_2(List<String> l) {
163 for (String s : l) {
164 return s;
165 }
166 return "";
167 }
168
169 @CodeReflection
170 @IR("""
171 func @"test3" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
172 java.for
173 ()Var<java.type:"int"> -> {
174 %1 : java.type:"int" = constant @0;
175 %2 : Var<java.type:"int"> = var %1 @"i";
176 yield %2;
177 }
178 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
179 %4 : java.type:"int" = var.load %3;
180 %5 : java.type:"int" = constant @10;
181 %6 : java.type:"boolean" = lt %4 %5;
182 yield %6;
183 }
184 (%7 : Var<java.type:"int">)java.type:"void" -> {
185 %8 : java.type:"int" = var.load %7;
186 %9 : java.type:"int" = constant @1;
187 %10 : java.type:"int" = add %8 %9;
188 var.store %7 %10;
189 yield;
190 }
191 (%11 : Var<java.type:"int">)java.type:"void" -> {
192 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
193 %13 : java.type:"int" = var.load %11;
194 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void";
195 java.continue;
196 };
197 return;
198 };
199 """)
200 void test3() {
201 for (int i = 0; i < 10; i++) {
202 System.out.println(i);
203 }
204 }
205
206 @CodeReflection
207 @IR("""
208 func @"test3_1" (%0 : java.type:"ForLoopTest")java.type:"int" -> {
209 java.for
210 ()Var<java.type:"int"> -> {
211 %1 : java.type:"int" = constant @0;
212 %2 : Var<java.type:"int"> = var %1 @"i";
213 yield %2;
214 }
215 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
216 %4 : java.type:"int" = var.load %3;
217 %5 : java.type:"int" = constant @10;
218 %6 : java.type:"boolean" = lt %4 %5;
219 yield %6;
220 }
221 (%7 : Var<java.type:"int">)java.type:"void" -> {
222 %8 : java.type:"int" = var.load %7;
223 %9 : java.type:"int" = constant @1;
224 %10 : java.type:"int" = add %8 %9;
225 var.store %7 %10;
226 yield;
227 }
228 (%11 : Var<java.type:"int">)java.type:"void" -> {
229 %12 : java.type:"int" = var.load %11;
230 return %12;
231 };
232 %13 : java.type:"int" = constant @-1;
233 return %13;
234 };
235 """)
236 int test3_1() {
237 for (int i = 0; i < 10; i++) {
238 return i;
239 }
240 return -1;
241 }
242
243 @CodeReflection
244 @IR("""
245 func @"test4" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
246 java.for
247 ()Var<java.type:"int"> -> {
248 %1 : java.type:"int" = constant @0;
249 %2 : Var<java.type:"int"> = var %1 @"i";
250 yield %2;
251 }
252 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
253 %4 : java.type:"int" = var.load %3;
254 %5 : java.type:"int" = constant @10;
255 %6 : java.type:"boolean" = lt %4 %5;
256 yield %6;
257 }
258 (%7 : Var<java.type:"int">)java.type:"void" -> {
259 %8 : java.type:"int" = var.load %7;
260 %9 : java.type:"int" = constant @1;
261 %10 : java.type:"int" = add %8 %9;
262 var.store %7 %10;
263 yield;
264 }
265 (%11 : Var<java.type:"int">)java.type:"void" -> {
266 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
267 %13 : java.type:"int" = var.load %11;
268 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void";
269 java.continue;
270 };
271 return;
272 };
273 """)
274 void test4() {
275 for (int i = 0; i < 10; i = i + 1)
276 System.out.println(i);
277 }
278
279 @CodeReflection
280 @IR("""
281 func @"test5" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
282 java.for
283 ()Var<java.type:"int"> -> {
284 %1 : java.type:"int" = constant @0;
285 %2 : Var<java.type:"int"> = var %1 @"i";
286 yield %2;
287 }
288 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
289 %4 : java.type:"int" = var.load %3;
290 %5 : java.type:"int" = constant @10;
291 %6 : java.type:"boolean" = lt %4 %5;
292 yield %6;
293 }
294 (%7 : Var<java.type:"int">)java.type:"void" -> {
295 %8 : java.type:"int" = var.load %7;
296 %9 : java.type:"int" = constant @1;
297 %10 : java.type:"int" = add %8 %9;
298 var.store %7 %10;
299 yield;
300 }
301 (%11 : Var<java.type:"int">)java.type:"void" -> {
302 java.continue;
303 };
304 return;
305 };
306 """)
307 void test5() {
308 for (int i = 0; i < 10; i = i + 1);
309 }
310
311 @CodeReflection
312 @IR("""
313 func @"test6" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
314 %1 : java.type:"int" = constant @0;
315 %2 : Var<java.type:"int"> = var %1 @"i";
316 java.for
317 ()java.type:"void" -> {
318 yield;
319 }
320 ()java.type:"boolean" -> {
321 %3 : java.type:"int" = var.load %2;
322 %4 : java.type:"int" = constant @10;
323 %5 : java.type:"boolean" = lt %3 %4;
324 yield %5;
325 }
326 ()java.type:"void" -> {
327 %6 : java.type:"int" = var.load %2;
328 %7 : java.type:"int" = constant @1;
329 %8 : java.type:"int" = add %6 %7;
330 var.store %2 %8;
331 yield;
332 }
333 ()java.type:"void" -> {
334 %9 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
335 %10 : java.type:"int" = var.load %2;
336 invoke %9 %10 @java.ref:"java.io.PrintStream::println(int):void";
337 java.continue;
338 };
339 return;
340 };
341 """)
342 void test6() {
343 int i = 0;
344 for (; i < 10; i = i + 1) {
345 System.out.println(i);
346 }
347 }
348
349 @CodeReflection
350 @IR("""
351 func @"test7" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
352 %1 : java.type:"int" = constant @0;
353 %2 : Var<java.type:"int"> = var %1 @"i";
354 java.for
355 ()java.type:"void" -> {
356 %3 : java.type:"int" = var.load %2;
357 %4 : java.type:"int" = constant @1;
358 %5 : java.type:"int" = add %3 %4;
359 var.store %2 %5;
360 yield;
361 }
362 ()java.type:"boolean" -> {
363 %6 : java.type:"int" = var.load %2;
364 %7 : java.type:"int" = constant @10;
365 %8 : java.type:"boolean" = lt %6 %7;
366 yield %8;
367 }
368 ()java.type:"void" -> {
369 %9 : java.type:"int" = var.load %2;
370 %10 : java.type:"int" = constant @1;
371 %11 : java.type:"int" = add %9 %10;
372 var.store %2 %11;
373 yield;
374 }
375 ()java.type:"void" -> {
376 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
377 %13 : java.type:"int" = var.load %2;
378 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void";
379 java.continue;
380 };
381 return;
382 };
383 """)
384 void test7() {
385 int i = 0;
386 for (i = i + 1; i < 10; i = i + 1) {
387 System.out.println(i);
388 }
389 }
390
391 @CodeReflection
392 @IR("""
393 func @"test8" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
394 java.for
395 ()Var<java.type:"int"> -> {
396 %1 : java.type:"int" = constant @0;
397 %2 : Var<java.type:"int"> = var %1 @"i";
398 yield %2;
399 }
400 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
401 %4 : java.type:"boolean" = constant @true;
402 yield %4;
403 }
404 (%5 : Var<java.type:"int">)java.type:"void" -> {
405 %6 : java.type:"int" = var.load %5;
406 %7 : java.type:"int" = constant @1;
407 %8 : java.type:"int" = add %6 %7;
408 var.store %5 %8;
409 yield;
410 }
411 (%9 : Var<java.type:"int">)java.type:"void" -> {
412 %10 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
413 %11 : java.type:"int" = var.load %9;
414 invoke %10 %11 @java.ref:"java.io.PrintStream::println(int):void";
415 java.continue;
416 };
417 unreachable;
418 };
419 """)
420 void test8() {
421 for (int i = 0; ; i = i + 1) {
422 System.out.println(i);
423 }
424 }
425
426 @CodeReflection
427 @IR("""
428 func @"test9" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
429 java.for
430 ()Var<java.type:"int"> -> {
431 %1 : java.type:"int" = constant @0;
432 %2 : Var<java.type:"int"> = var %1 @"i";
433 yield %2;
434 }
435 (%3 : Var<java.type:"int">)java.type:"boolean" -> {
436 %4 : java.type:"boolean" = constant @true;
437 yield %4;
438 }
439 (%5 : Var<java.type:"int">)java.type:"void" -> {
440 yield;
441 }
442 (%6 : Var<java.type:"int">)java.type:"void" -> {
443 %7 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
444 %8 : java.type:"int" = var.load %6;
445 invoke %7 %8 @java.ref:"java.io.PrintStream::println(int):void";
446 java.continue;
447 };
448 unreachable;
449 };
450 """)
451 void test9() {
452 for (int i = 0; ; ) {
453 System.out.println(i);
454 }
455 }
456
457 @CodeReflection
458 @IR("""
459 func @"test10" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
460 java.for
461 ()java.type:"void" -> {
462 yield;
463 }
464 ()java.type:"boolean" -> {
465 %1 : java.type:"boolean" = constant @true;
466 yield %1;
467 }
468 ()java.type:"void" -> {
469 yield;
470 }
471 ()java.type:"void" -> {
472 java.continue;
473 };
474 unreachable;
475 };
476 """)
477 void test10() {
478 for (; ; ) {
479 }
480 }
481
482 @CodeReflection
483 @IR("""
484 func @"test11" (%0 : java.type:"ForLoopTest")java.type:"void" -> {
485 java.for
486 ()Tuple<Var<java.type:"int">, Var<java.type:"int">> -> {
487 %1 : java.type:"int" = constant @0;
488 %2 : Var<java.type:"int"> = var %1 @"i";
489 %3 : java.type:"int" = constant @0;
490 %4 : Var<java.type:"int"> = var %3 @"j";
491 %5 : Tuple<Var<java.type:"int">, Var<java.type:"int">> = tuple %2 %4;
492 yield %5;
493 }
494 (%6 : Var<java.type:"int">, %7 : Var<java.type:"int">)java.type:"boolean" -> {
495 %8 : java.type:"boolean" = java.cand
496 ()java.type:"boolean" -> {
497 %9 : java.type:"int" = var.load %6;
498 %10 : java.type:"int" = constant @10;
499 %11 : java.type:"boolean" = lt %9 %10;
500 yield %11;
501 }
502 ()java.type:"boolean" -> {
503 %12 : java.type:"int" = var.load %7;
504 %13 : java.type:"int" = constant @20;
505 %14 : java.type:"boolean" = lt %12 %13;
506 yield %14;
507 };
508 yield %8;
509 }
510 (%15 : Var<java.type:"int">, %16 : Var<java.type:"int">)java.type:"void" -> {
511 %17 : java.type:"int" = var.load %15;
512 %18 : java.type:"int" = constant @1;
513 %19 : java.type:"int" = add %17 %18;
514 var.store %15 %19;
515 %20 : java.type:"int" = var.load %16;
516 %21 : java.type:"int" = constant @2;
517 %22 : java.type:"int" = add %20 %21;
518 var.store %16 %22;
519 yield;
520 }
521 (%23 : Var<java.type:"int">, %24 : Var<java.type:"int">)java.type:"void" -> {
522 %25 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
523 %26 : java.type:"int" = var.load %23;
524 invoke %25 %26 @java.ref:"java.io.PrintStream::println(int):void";
525 %27 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
526 %28 : java.type:"int" = var.load %24;
527 invoke %27 %28 @java.ref:"java.io.PrintStream::println(int):void";
528 java.continue;
529 };
530 return;
531 };
532 """)
533 void test11() {
534 for (int i = 0, j = 0; i < 10 && j < 20; i = i + 1, j = j + 2) {
535 System.out.println(i);
536 System.out.println(j);
537 }
538 }
539
540 @CodeReflection
541 @IR("""
542 func @"test12" (%0 : java.type:"ForLoopTest", %1 : java.type:"int")java.type:"void" -> {
543 %2 : Var<java.type:"int"> = var %1 @"r";
544 java.for
545 ()Var<java.type:"int"> -> {
546 %3 : java.type:"int" = constant @0;
547 %4 : Var<java.type:"int"> = var %3 @"i";
548 yield %4;
549 }
550 (%5 : Var<java.type:"int">)java.type:"boolean" -> {
551 %6 : java.type:"int" = var.load %5;
552 %7 : java.type:"int" = constant @10;
553 %8 : java.type:"boolean" = lt %6 %7;
554 yield %8;
555 }
556 (%9 : Var<java.type:"int">)java.type:"void" -> {
557 %10 : java.type:"int" = var.load %9;
558 %11 : java.type:"int" = constant @1;
559 %12 : java.type:"int" = add %10 %11;
560 var.store %9 %12;
561 yield;
562 }
563 (%13 : Var<java.type:"int">)java.type:"void" -> {
564 java.if
565 ()java.type:"boolean" -> {
566 %14 : java.type:"int" = var.load %2;
567 %15 : java.type:"int" = constant @0;
568 %16 : java.type:"boolean" = eq %14 %15;
569 yield %16;
570 }
571 ()java.type:"void" -> {
572 java.break;
573 }
574 ()java.type:"boolean" -> {
575 %17 : java.type:"int" = var.load %2;
576 %18 : java.type:"int" = constant @1;
577 %19 : java.type:"boolean" = eq %17 %18;
578 yield %19;
579 }
580 ()java.type:"void" -> {
581 java.continue;
582 }
583 ()java.type:"void" -> {
584 yield;
585 };
586 java.continue;
587 };
588 return;
589 };
590 """)
591 void test12(int r) {
592 for (int i = 0; i < 10; i++) {
593 if (r == 0) {
594 break;
595 } else if (r == 1) {
596 continue;
597 }
598 }
599 }
600
601 }