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