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.math.BigDecimal;
 26 import java.util.List;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with new expressions.
 31  * @build NewTest
 32  * @build CodeReflectionTester
 33  * @run main CodeReflectionTester NewTest
 34  */
 35 
 36 public class NewTest {
 37 
 38     @CodeReflection
 39     @IR("""
 40             func @"test0" (%0 : NewTest)void -> {
 41                 %1 : java.lang.String = constant @"1";
 42                 %2 : java.math.BigDecimal = new %1 @"func<java.math.BigDecimal, java.lang.String>";
 43                 %3 : Var<java.math.BigDecimal> = var %2 @"a";
 44                 return;
 45             };
 46             """)
 47     void test0() {
 48         BigDecimal a = new BigDecimal("1");
 49     }
 50 
 51     static class A {
 52         A() {}
 53 
 54         A(int i, int j) {}
 55     }
 56 
 57     @CodeReflection
 58     @IR("""
 59             func @"test1" (%0 : NewTest)void -> {
 60                 %1 : NewTest$A = new @"func<NewTest$A>";
 61                 %2 : Var<NewTest$A> = var %1 @"a";
 62                 return;
 63             };
 64             """)
 65     void test1() {
 66         A a = new A();
 67     }
 68 
 69     @CodeReflection
 70     @IR("""
 71             func @"test2" (%0 : NewTest)void -> {
 72                 %1 : int = constant @"1";
 73                 %2 : int = constant @"2";
 74                 %3 : NewTest$A = new %1 %2 @"func<NewTest$A, int, int>";
 75                 %4 : Var<NewTest$A> = var %3 @"a";
 76                 return;
 77             };
 78             """)
 79     void test2() {
 80         A a = new A(1, 2);
 81     }
 82 
 83     class B {
 84         B() {}
 85 
 86         B(int i, int j) {}
 87 
 88         class C {
 89         }
 90     }
 91 
 92     B f;
 93 
 94     B b() { return f; }
 95 
 96     @CodeReflection
 97     @IR("""
 98             func @"test3" (%0 : NewTest)void -> {
 99                 %1 : NewTest$B = new %0 @"func<NewTest$B>";
100                 %2 : Var<NewTest$B> = var %1 @"b";
101                 return;
102             };
103             """)
104     void test3() {
105         B b = new B();
106     }
107 
108     @CodeReflection
109     @IR("""
110             func @"test4" (%0 : NewTest)void -> {
111                 %1 : int = constant @"1";
112                 %2 : int = constant @"2";
113                 %3 : NewTest$B = new %0 %1 %2 @"func<NewTest$B, int, int>";
114                 %4 : Var<NewTest$B> = var %3 @"b";
115                 return;
116             };
117             """)
118     void test4() {
119         B b = new B(1, 2);
120     }
121 
122     @CodeReflection
123     @IR("""
124             func @"test5" (%0 : NewTest)void -> {
125                 %1 : NewTest$B = new %0 @"func<NewTest$B>";
126                 %2 : Var<NewTest$B> = var %1 @"b";
127                 return;
128             };
129             """)
130     void test5() {
131         B b = this.new B();
132     }
133 
134     @CodeReflection
135     @IR("""
136             func @"test6" (%0 : NewTest)void -> {
137                 %1 : NewTest$B = field.load %0 @"NewTest::f()NewTest$B";
138                 %2 : NewTest$B$C = new %1 @"func<NewTest$B$C>";
139                 %3 : Var<NewTest$B$C> = var %2 @"c";
140                 return;
141             };
142             """)
143     void test6() {
144         B.C c = f.new C();
145     }
146 
147     @CodeReflection
148     @IR("""
149             func @"test7" (%0 : NewTest)void -> {
150                 %1 : NewTest$B = invoke %0 @"NewTest::b()NewTest$B";
151                 %2 : NewTest$B$C = new %1 @"func<NewTest$B$C>";
152                 %3 : Var<NewTest$B$C> = var %2 @"c";
153                 return;
154             };
155             """)
156     void test7() {
157         B.C c = b().new C();
158     }
159 
160     static class AG<T> {
161         AG(List<T> l) {}
162     }
163 
164     @CodeReflection
165     @IR("""
166             func @"test8" (%0 : NewTest, %1 : java.util.List<java.lang.String>)void -> {
167                 %2 : Var<java.util.List<java.lang.String>> = var %1 @"l";
168                 %3 : java.util.List<java.lang.String> = var.load %2;
169                 %4 : NewTest$AG<java.lang.String> = new %3 @"func<NewTest$AG, java.util.List>";
170                 %5 : Var<NewTest$AG<java.lang.String>> = var %4 @"a";
171                 return;
172             };
173             """)
174     void test8(List<String> l) {
175         AG<String> a = new AG<>(l);
176     }
177 
178     class BG<T> {
179         BG(List<T> l) {}
180 
181         class CG<U> {
182             CG(List<U> l) {}
183         }
184     }
185 
186     // @@@ This produces incorrect type descriptors for generic inner classes
187     // the type argument for type BG is not preserved
188 //    @CodeReflection
189     @IR("""
190             func @"test9" (%0 : NewTest, %1 : java.util.List<java.lang.String>, %2 : java.util.List<java.lang.Number>)void -> {
191                 %3 : Var<java.util.List<java.lang.String>> = var %1 @"l1";
192                 %4 : Var<java.util.List<java.lang.Number>> = var %2 @"l2";
193                 %5 : java.util.List<java.lang.String> = var.load %3;
194                 %6 : NewTest$BG<java.lang.String> = new %0 %5 @"func<NewTest$BG, java.util.List>";
195                 %7 : java.util.List<java.lang.Number> = var.load %4;
196                 %8 : NewTest$BG$CG<java.lang.Number> = new %6 %7 @"func<NewTest$BG$CG, java.util.List>";
197                 %9 : Var<NewTest$BG$CG<java.lang.Number>> = var %8 @"numberCG";
198                 return;
199             };
200             """)
201     void test9(List<String> l1, List<Number> l2) {
202         BG<String>.CG<Number> numberCG = new BG<String>(l1).new CG<Number>(l2);
203     }
204 
205 
206     @CodeReflection
207     @IR("""
208             func @"test10" (%0 : NewTest)void -> {
209                 %1 : int = constant @"10";
210                 %2 : int[] = new %1 @"func<int[], int>";
211                 %3 : Var<int[]> = var %2 @"i";
212                 return;
213             };
214             """)
215     void test10() {
216         int[] i = new int[10];
217     }
218 
219     @CodeReflection
220     @IR("""
221             func @"test11" (%0 : NewTest, %1 : int)void -> {
222                 %2 : Var<int> = var %1 @"i";
223                 %3 : int = var.load %2;
224                 %4 : int = var.load %2;
225                 %5 : int = constant @"1";
226                 %6 : int = add %4 %5;
227                 %7 : int = var.load %2;
228                 %8 : int = constant @"2";
229                 %9 : int = add %7 %8;
230                 %10 : java.lang.String[][][] = new %3 %6 %9 @"func<java.lang.String[][][], int, int, int>";
231                 %11 : Var<java.lang.String[][][]> = var %10 @"s";
232                 return;
233             };
234             """)
235     void test11(int i) {
236         String[][][] s = new String[i][i + 1][i + 2];
237     }
238 }