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.ArrayList;
 26 import java.util.List;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with method calls.
 31  * @modules jdk.incubator.code
 32  * @build MethodCallTest
 33  * @build CodeReflectionTester
 34  * @run main CodeReflectionTester MethodCallTest
 35  */
 36 
 37 public class MethodCallTest {
 38 
 39     void m() {
 40     }
 41 
 42     int m_int() {
 43         return 0;
 44     }
 45 
 46     @CodeReflection
 47     @IR("""
 48             func @"test1" (%0 : MethodCallTest)void -> {
 49                 invoke %0 @"MethodCallTest::m()void";
 50                 return;
 51             };
 52             """)
 53     void test1() {
 54         m();
 55     }
 56 
 57     @CodeReflection
 58     @IR("""
 59             func @"test2" (%0 : MethodCallTest)void -> {
 60                 invoke %0 @"MethodCallTest::m()void";
 61                 return;
 62             };
 63             """)
 64     void test2() {
 65         this.m();
 66     }
 67 
 68     @CodeReflection
 69     @IR("""
 70             func @"test2_1" (%0 : MethodCallTest)void -> {
 71                 invoke %0 @"MethodCallTest::m()void";
 72                 return;
 73             };
 74             """)
 75     void test2_1() {
 76         MethodCallTest.this.m();
 77     }
 78 
 79     @CodeReflection
 80     @IR("""
 81             func @"test3" (%0 : MethodCallTest)int -> {
 82                 %1 : int = invoke %0 @"MethodCallTest::m_int()int";
 83                 return %1;
 84             };
 85             """)
 86     int test3() {
 87         return m_int();
 88     }
 89 
 90 
 91     static void ms() {
 92     }
 93 
 94     @CodeReflection
 95     @IR("""
 96             func @"test4" (%0 : MethodCallTest)void -> {
 97                 invoke @"MethodCallTest::ms()void";
 98                 return;
 99             };
100             """)
101     void test4() {
102         ms();
103     }
104 
105     @CodeReflection
106     @IR("""
107             func @"test4_1" (%0 : MethodCallTest)void -> {
108                 invoke @"MethodCallTest::ms()void";
109                 return;
110             };
111             """)
112     void test4_1() {
113         MethodCallTest.ms();
114     }
115 
116     @CodeReflection
117     @IR("""
118             func @"test4_2" (%0 : MethodCallTest)java.util.List<java.lang.String> -> {
119                 %1 : java.util.List<java.lang.String> = invoke @"java.util.List::of()java.util.List";
120                 return %1;
121             };
122             """)
123     List<String> test4_2() {
124         return List.of();
125     }
126 
127     String m(int i, String s, List<Number> l) {
128         return s;
129     }
130 
131     @CodeReflection
132     @IR("""
133             func @"test5" (%0 : MethodCallTest, %1 : java.util.List<java.lang.Number>)void -> {
134                 %2 : Var<java.util.List<java.lang.Number>> = var %1 @"l";
135                 %3 : int = constant @"1";
136                 %4 : java.lang.String = constant @"1";
137                 %5 : java.util.List<java.lang.Number> = var.load %2;
138                 %6 : java.lang.String = invoke %0 %3 %4 %5 @"MethodCallTest::m(int, java.lang.String, java.util.List)java.lang.String";
139                 %7 : Var<java.lang.String> = var %6 @"s";
140                 return;
141             };
142             """)
143     void test5(List<Number> l) {
144         String s = m(1, "1", l);
145     }
146 
147 
148     static class A {
149         B b;
150 
151         B m() {
152             return null;
153         }
154     }
155 
156     static class B {
157         C m() {
158             return null;
159         }
160     }
161 
162     static class C {
163         int m() {
164             return 0;
165         }
166     }
167 
168     @CodeReflection
169     @IR("""
170             func @"test6" (%0 : MethodCallTest, %1 : MethodCallTest$A)void -> {
171                 %2 : Var<MethodCallTest$A> = var %1 @"a";
172                 %3 : MethodCallTest$A = var.load %2;
173                 %4 : MethodCallTest$B = invoke %3 @"MethodCallTest$A::m()MethodCallTest$B";
174                 %5 : MethodCallTest$C = invoke %4 @"MethodCallTest$B::m()MethodCallTest$C";
175                 %6 : int = invoke %5 @"MethodCallTest$C::m()int";
176                 return;
177             };
178             """)
179     void test6(A a) {
180         a.m().m().m();
181     }
182 
183     @CodeReflection
184     @IR("""
185             func @"test7" (%0 : MethodCallTest, %1 : MethodCallTest$A)void -> {
186                 %2 : Var<MethodCallTest$A> = var %1 @"a";
187                 %3 : MethodCallTest$A = var.load %2;
188                 %4 : MethodCallTest$B = field.load %3 @"MethodCallTest$A::b()MethodCallTest$B";
189                 %5 : MethodCallTest$C = invoke %4 @"MethodCallTest$B::m()MethodCallTest$C";
190                 return;
191             };
192             """)
193     void test7(A a) {
194         a.b.m();
195     }
196 
197     @CodeReflection
198     @IR("""
199             func @"test8" (%0 : MethodCallTest, %1 : java.lang.String)void -> {
200                 %2 : Var<java.lang.String> = var %1 @"s";
201                 %3 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream";
202                 %4 : java.lang.String = var.load %2;
203                 invoke %3 %4 @"java.io.PrintStream::println(java.lang.String)void";
204                 return;
205             };
206             """)
207     void test8(String s) {
208         System.out.println(s);
209     }
210 
211     static class X {
212         int x;
213         void x() {}
214 
215         static void sx() {}
216     }
217 
218     static class Y extends X {
219         void y() {}
220         static void sy() {}
221 
222         @CodeReflection
223         @IR("""
224                 func @"test" (%0 : MethodCallTest$Y)void -> {
225                     invoke %0 @"MethodCallTest$Y::x()void";
226                     invoke %0 @"MethodCallTest$Y::y()void";
227                     invoke @"MethodCallTest$Y::sx()void";
228                     invoke @"MethodCallTest$Y::sy()void";
229                     invoke @"MethodCallTest$Y::sx()void";
230                     invoke @"MethodCallTest$Y::sy()void";
231                     return;
232                 };
233                 """)
234         void test() {
235             x();
236             y();
237 
238             sx();
239             sy();
240 
241             Y.sx();
242             Y.sy();
243         }
244     }
245 
246     @CodeReflection
247     @IR("""
248             func @"test9" (%0 : MethodCallTest$Y)void -> {
249                 %1 : Var<MethodCallTest$Y> = var %0 @"y";
250                 %2 : MethodCallTest$Y = var.load %1;
251                 invoke %2 @"MethodCallTest$Y::x()void";
252                 %3 : MethodCallTest$Y = var.load %1;
253                 invoke %3 @"MethodCallTest$Y::y()void";
254                 %4 : MethodCallTest$Y = var.load %1;
255                 invoke @"MethodCallTest$Y::sx()void";
256                 %5 : MethodCallTest$Y = var.load %1;
257                 invoke @"MethodCallTest$Y::sy()void";
258                 invoke @"MethodCallTest$Y::sx()void";
259                 invoke @"MethodCallTest$Y::sy()void";
260                 return;
261             };
262             """)
263     static void test9(Y y) {
264         y.x();
265         y.y();
266 
267         y.sx();
268         y.sy();
269 
270         Y.sx();
271         Y.sy();
272     }
273 
274     @CodeReflection
275     @IR("""
276             func @"test10" (%0 : java.util.ArrayList<java.lang.String>)void -> {
277                 %1 : Var<java.util.ArrayList<java.lang.String>> = var %0 @"al";
278                 %2 : java.util.ArrayList<java.lang.String> = var.load %1;
279                 %3 : int = constant @"0";
280                 %4 : java.lang.String = invoke %2 %3 @"java.util.ArrayList::get(int)java.lang.Object";
281                 %5 : Var<java.lang.String> = var %4 @"s";
282                 %6 : java.util.ArrayList<java.lang.String> = var.load %1;
283                 %7 : Var<java.util.List<java.lang.String>> = var %6 @"l";
284                 %8 : java.util.List<java.lang.String> = var.load %7;
285                 %9 : int = constant @"0";
286                 %10 : java.lang.String = invoke %8 %9 @"java.util.List::get(int)java.lang.Object";
287                 var.store %5 %10;
288                 return;
289             };
290             """)
291     static void test10(ArrayList<String> al) {
292         String s = al.get(0);
293         List<String> l = al;
294         s = l.get(0);
295     }
296 }