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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * @test
28 * @summary Smoke test for code reflection with local class creation expressions.
29 * @modules jdk.incubator.code
30 * @build LocalClassTest
31 * @build CodeReflectionTester
32 * @run main CodeReflectionTester LocalClassTest
33 */
34
35 import jdk.incubator.code.CodeReflection;
36
37 public class LocalClassTest {
38
39 final static String CONST_STRING = "Hello!";
40 String nonConstString = "Hello!";
41
42 @CodeReflection
43 @IR("""
44 func @"testLocalNoCapture" (%0 : java.type:"LocalClassTest")java.type:"void" -> {
45 %1 : java.type:"LocalClassTest::$1Foo" = new %0 @java.ref:"LocalClassTest::$1Foo::(LocalClassTest)";
46 invoke %1 @java.ref:"LocalClassTest::$1Foo::m():void";
47 return;
48 };
49 """)
50 void testLocalNoCapture() {
51 class Foo {
52 void m() { }
53 }
54 new Foo().m();
55 }
56
57 @CodeReflection
58 @IR("""
59 func @"testAnonNoCapture" (%0 : java.type:"LocalClassTest")java.type:"void" -> {
60 %1 : java.type:"LocalClassTest::$1" = new %0 @java.ref:"LocalClassTest::$1::(LocalClassTest)";
61 invoke %1 @java.ref:"LocalClassTest::$1::m():void";
62 return;
63 };
64 """)
65 void testAnonNoCapture() {
66 new Object() {
67 void m() { }
68 }.m();
69 }
70
71 @CodeReflection
72 @IR("""
73 func @"testLocalCaptureParam" (%0 : java.type:"LocalClassTest", %1 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
74 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
75 %3 : java.type:"java.lang.String" = var.load %2;
76 %4 : java.type:"LocalClassTest::$2Foo" = new %0 %3 @java.ref:"LocalClassTest::$2Foo::(LocalClassTest, java.lang.String)";
77 %5 : java.type:"java.lang.String" = invoke %4 @java.ref:"LocalClassTest::$2Foo::m():java.lang.String";
78 return %5;
79 };
80 """)
81 String testLocalCaptureParam(String s) {
82 class Foo {
83 String m() { return s; }
84 }
85 return new Foo().m();
86 }
87
88 @CodeReflection
89 @IR("""
90 func @"testAnonCaptureParam" (%0 : java.type:"LocalClassTest", %1 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
91 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
92 %3 : java.type:"java.lang.String" = var.load %2;
93 %4 : java.type:"LocalClassTest::$2" = new %0 %3 @java.ref:"LocalClassTest::$2::(LocalClassTest, java.lang.String)";
94 %5 : java.type:"java.lang.String" = invoke %4 @java.ref:"LocalClassTest::$2::m():java.lang.String";
95 return %5;
96 };
97 """)
98 String testAnonCaptureParam(String s) {
99 return new Object() {
100 String m() { return s; }
101 }.m();
102 }
103
104 @CodeReflection
105 @IR("""
106 func @"testLocalCaptureParamAndField" (%0 : java.type:"LocalClassTest", %1 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
107 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
108 %3 : java.type:"java.lang.String" = constant @"Hello!";
109 %4 : Var<java.type:"java.lang.String"> = var %3 @"localConst";
110 %5 : java.type:"java.lang.String" = var.load %2;
111 %6 : java.type:"LocalClassTest::$3Foo" = new %0 %5 @java.ref:"LocalClassTest::$3Foo::(LocalClassTest, java.lang.String)";
112 %7 : java.type:"java.lang.String" = invoke %6 @java.ref:"LocalClassTest::$3Foo::m():java.lang.String";
113 return %7;
114 };
115 """)
116 String testLocalCaptureParamAndField(String s) {
117 final String localConst = "Hello!";
118 class Foo {
119 String m() { return localConst + s + nonConstString + CONST_STRING; }
120 }
121 return new Foo().m();
122 }
123
124 @CodeReflection
125 @IR("""
126 func @"testAnonCaptureParamAndField" (%0 : java.type:"LocalClassTest", %1 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
127 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
128 %3 : java.type:"java.lang.String" = constant @"Hello!";
129 %4 : Var<java.type:"java.lang.String"> = var %3 @"localConst";
130 %5 : java.type:"java.lang.String" = var.load %2;
131 %6 : java.type:"LocalClassTest::$3" = new %0 %5 @java.ref:"LocalClassTest::$3::(LocalClassTest, java.lang.String)";
132 %7 : java.type:"java.lang.String" = invoke %6 @java.ref:"LocalClassTest::$3::m():java.lang.String";
133 return %7;
134 };
135 """)
136 String testAnonCaptureParamAndField(String s) {
137 final String localConst = "Hello!";
138 return new Object() {
139 String m() { return localConst + s + nonConstString + CONST_STRING; }
140 }.m();
141 }
142
143 @CodeReflection
144 @IR("""
145 func @"testLocalDependency" (%0 : java.type:"LocalClassTest", %1 : java.type:"int", %2 : java.type:"int")java.type:"void" -> {
146 %3 : Var<java.type:"int"> = var %1 @"s";
147 %4 : Var<java.type:"int"> = var %2 @"i";
148 %5 : java.type:"int" = var.load %3;
149 %6 : java.type:"int" = var.load %4;
150 %7 : java.type:"LocalClassTest::$1Bar" = new %0 %5 %6 @java.ref:"LocalClassTest::$1Bar::(LocalClassTest, int, int)";
151 return;
152 };
153 """)
154 void testLocalDependency(int s, int i) {
155 class Foo {
156 int i() { return i; }
157 }
158 class Bar {
159 int s() { return s; }
160 Foo foo() { return new Foo(); }
161 }
162 new Bar();
163 }
164
165 @CodeReflection
166 @IR("""
167 func @"testAnonDependency" (%0 : java.type:"LocalClassTest", %1 : java.type:"int", %2 : java.type:"int")java.type:"void" -> {
168 %3 : Var<java.type:"int"> = var %1 @"s";
169 %4 : Var<java.type:"int"> = var %2 @"i";
170 %5 : java.type:"int" = var.load %3;
171 %6 : java.type:"int" = var.load %4;
172 %7 : java.type:"LocalClassTest::$4" = new %0 %5 %6 @java.ref:"LocalClassTest::$4::(LocalClassTest, int, int)";
173 return;
174 };
175 """)
176 void testAnonDependency(int s, int i) {
177 class Foo {
178 int i() { return i; }
179 }
180 new Object() {
181 int s() { return s; }
182 Foo foo() { return new Foo(); }
183 };
184 }
185 }