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
26 /*
27 * @test
28 * @summary Smoke test for code reflection with intersection type conversions.
29 * @modules jdk.incubator.code
30 * @build IntersectionTypeTest
31 * @build CodeReflectionTester
32 * @run main CodeReflectionTester IntersectionTypeTest
33 */
34
35 class IntersectionTypeTest {
36 interface A {
37 Object f_A = 5;
38 void m_A();
39 }
40
41 interface B {
42 Object f_B = 5;
43 void m_B();
44 }
45
46 interface C {
47 Object f_C = 5;
48 void m_C();
49 }
50
51 @CodeReflection
52 @IR("""
53 func @"test1" (%0 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> {
54 %1 : Var<java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>"> = var %0 @"x";
55 %2 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1;
56 invoke %2 @java.ref:"IntersectionTypeTest$A::m_A():void";
57 %3 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1;
58 %4 : java.type:"IntersectionTypeTest$B" = cast %3 @java.type:"IntersectionTypeTest$B";
59 invoke %4 @java.ref:"IntersectionTypeTest$B::m_B():void";
60 %5 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1;
61 %6 : java.type:"IntersectionTypeTest$C" = cast %5 @java.type:"IntersectionTypeTest$C";
62 invoke %6 @java.ref:"IntersectionTypeTest$C::m_C():void";
63 return;
64 };
65 """)
66 static <X extends A & B & C> void test1(X x) {
67 x.m_A();
68 x.m_B();
69 x.m_C();
70 }
71
72 // #X<&m<IntersectionTypeTest, test2, func<void, IntersectionTypeTest$A>>, IntersectionTypeTest$A>
73 // #X<&m<IntersectionTypeTest, test2, func<void, IntersectionTypeTest$A>, IntersectionTypeTest$A>
74 @CodeReflection
75 @IR("""
76 func @"test2" (%0 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> {
77 %1 : Var<java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x";
78 %2 : java.type:"IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
79 %3 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$A::f_A:java.lang.Object";
80 %4 : Var<java.type:"java.lang.Object"> = var %3 @"oA";
81 %5 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
82 %6 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$B::f_B:java.lang.Object";
83 %7 : Var<java.type:"java.lang.Object"> = var %6 @"oB";
84 %8 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
85 %9 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$C::f_C:java.lang.Object";
86 %10 : Var<java.type:"java.lang.Object"> = var %9 @"oC";
87 return;
88 };
89 """)
90 static <X extends A & B & C> void test2(X x) {
91 Object oA = x.f_A;
92 Object oB = x.f_B;
93 Object oC = x.f_C;
94 }
95
96 @CodeReflection
97 @IR("""
98 func @"test3" (%0 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> {
99 %1 : Var<java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x";
100 %2 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
101 %3 : Var<java.type:"IntersectionTypeTest$A"> = var %2 @"rec$";
102 %4 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
103 %5 : java.type:"IntersectionTypeTest$A" = var.load %3;
104 invoke %5 @java.ref:"IntersectionTypeTest$A::m_A():void";
105 return;
106 };
107 %6 : Var<java.type:"java.lang.Runnable"> = var %4 @"rA";
108 %7 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
109 %8 : java.type:"IntersectionTypeTest$B" = cast %7 @java.type:"IntersectionTypeTest$B";
110 %9 : Var<java.type:"IntersectionTypeTest$B"> = var %8 @"rec$";
111 %10 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
112 %11 : java.type:"IntersectionTypeTest$B" = var.load %9;
113 invoke %11 @java.ref:"IntersectionTypeTest$B::m_B():void";
114 return;
115 };
116 %12 : Var<java.type:"java.lang.Runnable"> = var %10 @"rB";
117 %13 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
118 %14 : java.type:"IntersectionTypeTest$C" = cast %13 @java.type:"IntersectionTypeTest$C";
119 %15 : Var<java.type:"IntersectionTypeTest$C"> = var %14 @"rec$";
120 %16 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
121 %17 : java.type:"IntersectionTypeTest$C" = var.load %15;
122 invoke %17 @java.ref:"IntersectionTypeTest$C::m_C():void";
123 return;
124 };
125 %18 : Var<java.type:"java.lang.Runnable"> = var %16 @"rC";
126 return;
127 };
128 """)
129 static <X extends A & B & C> void test3(X x) {
130 Runnable rA = x::m_A;
131 Runnable rB = x::m_B;
132 Runnable rC = x::m_C;
133 }
134
135 static void g_A(A a) { }
136 static void g_B(B a) { }
137 static void g_C(C a) { }
138
139 @CodeReflection
140 @IR("""
141 func @"test4" (%0 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> {
142 %1 : Var<java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x";
143 %2 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
144 invoke %2 @java.ref:"IntersectionTypeTest::g_A(IntersectionTypeTest$A):void";
145 %3 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
146 %4 : java.type:"IntersectionTypeTest$B" = cast %3 @java.type:"IntersectionTypeTest$B";
147 invoke %4 @java.ref:"IntersectionTypeTest::g_B(IntersectionTypeTest$B):void";
148 %5 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1;
149 %6 : java.type:"IntersectionTypeTest$C" = cast %5 @java.type:"IntersectionTypeTest$C";
150 invoke %6 @java.ref:"IntersectionTypeTest::g_C(IntersectionTypeTest$C):void";
151 return;
152 };
153 """)
154 static <X extends A & B & C> void test4(X x) {
155 g_A(x);
156 g_B(x);
157 g_C(x);
158 }
159
160 static <X extends A & B & C> X makeIntersection(X x1, X x2) {
161 return null;
162 }
163
164 static class E1 implements A, B, C {
165 @Override
166 public void m_A() { }
167 @Override
168 public void m_B() { }
169 @Override
170 public void m_C() { }
171 }
172
173 static class E2 implements A, B, C {
174 @Override
175 public void m_A() { }
176 @Override
177 public void m_B() { }
178 @Override
179 public void m_C() { }
180 }
181
182 @CodeReflection
183 @IR("""
184 func @"test5" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> {
185 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1";
186 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2";
187 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2;
188 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3;
189 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A";
190 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x";
191 %8 : java.type:"IntersectionTypeTest$A" = var.load %7;
192 invoke %8 @java.ref:"IntersectionTypeTest$A::m_A():void";
193 %9 : java.type:"IntersectionTypeTest$A" = var.load %7;
194 %10 : java.type:"IntersectionTypeTest$B" = cast %9 @java.type:"IntersectionTypeTest$B";
195 invoke %10 @java.ref:"IntersectionTypeTest$B::m_B():void";
196 %11 : java.type:"IntersectionTypeTest$A" = var.load %7;
197 %12 : java.type:"IntersectionTypeTest$C" = cast %11 @java.type:"IntersectionTypeTest$C";
198 invoke %12 @java.ref:"IntersectionTypeTest$C::m_C():void";
199 return;
200 };
201 """)
202 static void test5(E1 e1, E2 e2) {
203 var x = makeIntersection(e1, e2);
204 x.m_A();
205 x.m_B();
206 x.m_C();
207 }
208
209 @CodeReflection
210 @IR("""
211 func @"test6" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> {
212 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1";
213 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2";
214 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2;
215 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3;
216 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A";
217 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x";
218 %8 : java.type:"IntersectionTypeTest$A" = var.load %7;
219 %9 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$A::f_A:java.lang.Object";
220 %10 : Var<java.type:"java.lang.Object"> = var %9 @"oA";
221 %11 : java.type:"IntersectionTypeTest$A" = var.load %7;
222 %12 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$B::f_B:java.lang.Object";
223 %13 : Var<java.type:"java.lang.Object"> = var %12 @"oB";
224 %14 : java.type:"IntersectionTypeTest$A" = var.load %7;
225 %15 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$C::f_C:java.lang.Object";
226 %16 : Var<java.type:"java.lang.Object"> = var %15 @"oC";
227 return;
228 };
229 """)
230 static void test6(E1 e1, E2 e2) {
231 var x = makeIntersection(e1, e2);
232 Object oA = x.f_A;
233 Object oB = x.f_B;
234 Object oC = x.f_C;
235 }
236
237 @CodeReflection
238 @IR("""
239 func @"test7" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> {
240 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1";
241 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2";
242 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2;
243 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3;
244 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A";
245 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x";
246 %8 : java.type:"IntersectionTypeTest$A" = var.load %7;
247 %9 : Var<java.type:"IntersectionTypeTest$A"> = var %8 @"rec$";
248 %10 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
249 %11 : java.type:"IntersectionTypeTest$A" = var.load %9;
250 invoke %11 @java.ref:"IntersectionTypeTest$A::m_A():void";
251 return;
252 };
253 %12 : Var<java.type:"java.lang.Runnable"> = var %10 @"rA";
254 %13 : java.type:"IntersectionTypeTest$A" = var.load %7;
255 %14 : java.type:"IntersectionTypeTest$B" = cast %13 @java.type:"IntersectionTypeTest$B";
256 %15 : Var<java.type:"IntersectionTypeTest$B"> = var %14 @"rec$";
257 %16 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
258 %17 : java.type:"IntersectionTypeTest$B" = var.load %15;
259 invoke %17 @java.ref:"IntersectionTypeTest$B::m_B():void";
260 return;
261 };
262 %18 : Var<java.type:"java.lang.Runnable"> = var %16 @"rB";
263 %19 : java.type:"IntersectionTypeTest$A" = var.load %7;
264 %20 : java.type:"IntersectionTypeTest$C" = cast %19 @java.type:"IntersectionTypeTest$C";
265 %21 : Var<java.type:"IntersectionTypeTest$C"> = var %20 @"rec$";
266 %22 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> {
267 %23 : java.type:"IntersectionTypeTest$C" = var.load %21;
268 invoke %23 @java.ref:"IntersectionTypeTest$C::m_C():void";
269 return;
270 };
271 %24 : Var<java.type:"java.lang.Runnable"> = var %22 @"rC";
272 return;
273 };
274 """)
275 static void test7(E1 e1, E2 e2) {
276 var x = makeIntersection(e1, e2);
277 Runnable rA = x::m_A;
278 Runnable rB = x::m_B;
279 Runnable rC = x::m_C;
280 }
281
282 @CodeReflection
283 @IR("""
284 func @"test8" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> {
285 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1";
286 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2";
287 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2;
288 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3;
289 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A";
290 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x";
291 %8 : java.type:"IntersectionTypeTest$A" = var.load %7;
292 invoke %8 @java.ref:"IntersectionTypeTest::g_A(IntersectionTypeTest$A):void";
293 %9 : java.type:"IntersectionTypeTest$A" = var.load %7;
294 %10 : java.type:"IntersectionTypeTest$B" = cast %9 @java.type:"IntersectionTypeTest$B";
295 invoke %10 @java.ref:"IntersectionTypeTest::g_B(IntersectionTypeTest$B):void";
296 %11 : java.type:"IntersectionTypeTest$A" = var.load %7;
297 %12 : java.type:"IntersectionTypeTest$C" = cast %11 @java.type:"IntersectionTypeTest$C";
298 invoke %12 @java.ref:"IntersectionTypeTest::g_C(IntersectionTypeTest$C):void";
299 return;
300 };
301 """)
302 static void test8(E1 e1, E2 e2) {
303 var x = makeIntersection(e1, e2);
304 g_A(x);
305 g_B(x);
306 g_C(x);
307 }
308 }