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