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 import java.util.function.Consumer;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with blocks.
 31  * @modules jdk.incubator.code
 32  * @build BlockTest
 33  * @build CodeReflectionTester
 34  * @run main CodeReflectionTester BlockTest
 35  */
 36 
 37 public class BlockTest {
 38     @CodeReflection
 39     @IR("""
 40             func @"test1" (%0 : BlockTest)void -> {
 41                 java.block ()void -> {
 42                     %1 : int = constant @"0";
 43                     %2 : Var<int> = var %1 @"i";
 44                     yield;
 45                 };
 46                 java.block ()void -> {
 47                     %3 : int = constant @"1";
 48                     %4 : Var<int> = var %3 @"i";
 49                     java.block ()void -> {
 50                         %5 : int = constant @"2";
 51                         %6 : Var<int> = var %5 @"j";
 52                         yield;
 53                     };
 54                     yield;
 55                 };
 56                 return;
 57             };
 58             """)
 59     void test1() {
 60         {
 61             int i = 0;
 62         }
 63 
 64         {
 65             int i = 1;
 66 
 67             {
 68                 int j = 2;
 69             }
 70         }
 71     }
 72 
 73     @CodeReflection
 74     @IR("""
 75             func @"test2" (%0 : BlockTest, %1 : int)void -> {
 76                 %2 : Var<int> = var %1 @"i";
 77                 java.if
 78                     ()boolean -> {
 79                         %3 : int = var.load %2;
 80                         %4 : int = constant @"1";
 81                         %5 : boolean = lt %3 %4;
 82                         yield %5;
 83                     }
 84                     ^then()void -> {
 85                         java.block ()void -> {
 86                             %6 : int = var.load %2;
 87                             %7 : int = constant @"1";
 88                             %8 : int = add %6 %7;
 89                             var.store %2 %8;
 90                             yield;
 91                         };
 92                         yield;
 93                     }
 94                     ^else_if()boolean -> {
 95                         %9 : int = var.load %2;
 96                         %10 : int = constant @"2";
 97                         %11 : boolean = lt %9 %10;
 98                         yield %11;
 99                     }
100                     ^then()void -> {
101                         java.block ()void -> {
102                             %12 : int = var.load %2;
103                             %13 : int = constant @"2";
104                             %14 : int = add %12 %13;
105                             var.store %2 %14;
106                             yield;
107                         };
108                         yield;
109                     }
110                     ^else()void -> {
111                         java.block ()void -> {
112                             %15 : int = var.load %2;
113                             %16 : int = constant @"3";
114                             %17 : int = add %15 %16;
115                             var.store %2 %17;
116                             yield;
117                         };
118                         yield;
119                     };
120                 return;
121             };
122             """)
123     void test2(int i) {
124         if (i < 1) {
125             {
126                 i += 1;
127             }
128         } else if (i < 2) {
129             {
130                 i += 2;
131             }
132         } else {
133             {
134                 i += 3;
135             }
136         }
137     }
138 
139     @CodeReflection
140     @IR("""
141             func @"test3" (%0 : BlockTest)void -> {
142                 java.for
143                     ^init()void -> {
144                         yield;
145                     }
146                     ^cond()boolean -> {
147                         %1 : boolean = constant @"true";
148                         yield %1;
149                     }
150                     ^update()void -> {
151                         yield;
152                     }
153                     ^body()void -> {
154                         java.block ()void -> {
155                             %2 : int = constant @"0";
156                             %3 : Var<int> = var %2 @"i";
157                             yield;
158                         };
159                         java.continue;
160                     };
161                 unreachable;
162             };
163             """)
164     void test3() {
165         for (;;) {
166             {
167                 int i = 0;
168             }
169         }
170     }
171 
172     @CodeReflection
173     @IR("""
174             func @"test4" (%0 : BlockTest, %1 : int[])void -> {
175                 %2 : Var<int[]> = var %1 @"ia";
176                 java.enhancedFor
177                     ^expr()int[] -> {
178                         %3 : int[] = var.load %2;
179                         yield %3;
180                     }
181                     ^def(%4 : int)Var<int> -> {
182                         %5 : Var<int> = var %4 @"i";
183                         yield %5;
184                     }
185                     ^body(%6 : Var<int>)void -> {
186                         java.block ()void -> {
187                             %7 : int = var.load %6;
188                             %8 : int = constant @"1";
189                             %9 : int = add %7 %8;
190                             var.store %6 %9;
191                             yield;
192                         };
193                         java.continue;
194                     };
195                 return;
196             };
197             """)
198     void test4(int[] ia) {
199         for (int i : ia) {
200             {
201                 i++;
202             }
203         }
204    }
205 
206     @CodeReflection
207     @IR("""
208             func @"test5" (%0 : BlockTest)void -> {
209                 %1 : java.util.function.Consumer<java.lang.String> = lambda (%2 : java.lang.String)void -> {
210                     %3 : Var<java.lang.String> = var %2 @"s";
211                     java.block ()void -> {
212                         %4 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream";
213                         %5 : java.lang.String = var.load %3;
214                         invoke %4 %5 @"java.io.PrintStream::println(java.lang.String)void";
215                         yield;
216                     };
217                     return;
218                 };
219                 %6 : Var<java.util.function.Consumer<java.lang.String>> = var %1 @"c";
220                 return;
221             };
222             """)
223    void test5() {
224         Consumer<String> c = s -> {
225             {
226                 System.out.println(s);
227             }
228         };
229     }
230 
231 
232     @CodeReflection
233     @IR("""
234             func @"test6" (%0 : BlockTest)void -> {
235                  java.if
236                      ()boolean -> {
237                          %1 : boolean = constant @"true";
238                          yield %1;
239                      }
240                      ^then()void -> {
241                          java.block ()void -> {
242                              return;
243                          };
244                          yield;
245                      }
246                      ^else()void -> {
247                          yield;
248                      };
249                  java.if
250                      ()boolean -> {
251                          %2 : boolean = constant @"true";
252                          yield %2;
253                      }
254                      ^then()void -> {
255                          java.block ()void -> {
256                              %3 : java.lang.RuntimeException = new @"func<java.lang.RuntimeException>";
257                              throw %3;
258                          };
259                          yield;
260                      }
261                      ^else()void -> {
262                          yield;
263                      };
264                  return;
265              };
266              """)
267     void test6() {
268         if (true) {
269             {
270                 return;
271             }
272         }
273 
274         if (true) {
275             {
276                 throw new RuntimeException();
277             }
278         }
279     }
280 }