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 /*
25 * @test
26 * @summary Smoke test for code reflection with quotable lambdas.
27 * @modules jdk.incubator.code
28 * @build QuotableIntersectionTest
29 * @build CodeReflectionTester
30 * @run main CodeReflectionTester QuotableIntersectionTest
31 */
32
33 import jdk.incubator.code.Quotable;
34 import jdk.incubator.code.CodeReflection;
35 import java.util.function.IntBinaryOperator;
36 import java.util.function.IntFunction;
37 import java.util.function.IntSupplier;
38 import java.util.function.IntUnaryOperator;
39
40 public class QuotableIntersectionTest {
41 @IR("""
42 func @"f" ()java.type:"void" -> {
43 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true ()java.type:"void" -> {
44 return;
45 };
46 return;
47 };
48 """)
49 static final Quotable QUOTED_NO_PARAM_VOID = (Quotable & Runnable) () -> {
50 };
51
52 @IR("""
53 func @"f" ()java.type:"void" -> {
54 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true ()java.type:"int" -> {
55 %1 : java.type:"int" = constant @1;
56 return %1;
57 };
58 return;
59 };
60 """)
61 static final Quotable QUOTED_NO_PARAM_CONST = (Quotable & IntSupplier) () -> 1;
62
63 @IR("""
64 func @"f" ()java.type:"void" -> {
65 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%1 : java.type:"int")java.type:"int" -> {
66 %2 : Var<java.type:"int"> = var %1 @"x";
67 %3 : java.type:"int" = var.load %2;
68 return %3;
69 };
70 return;
71 };
72 """)
73 static final Quotable QUOTED_ID = (Quotable & IntUnaryOperator) x -> x;
74
75 @IR("""
76 func @"f" ()java.type:"void" -> {
77 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%1 : java.type:"int", %2 : java.type:"int")java.type:"int" -> {
78 %3 : Var<java.type:"int"> = var %1 @"x";
79 %4 : Var<java.type:"int"> = var %2 @"y";
80 %5 : java.type:"int" = var.load %3;
81 %6 : java.type:"int" = var.load %4;
82 %7 : java.type:"int" = add %5 %6;
83 return %7;
84 };
85 return;
86 };
87 """)
88 static final Quotable QUOTED_PLUS = (Quotable & IntBinaryOperator) (x, y) -> x + y;
89
90 @IR("""
91 func @"f" ()java.type:"void" -> {
92 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true ()java.type:"void" -> {
93 %1 : java.type:"java.lang.AssertionError" = new @java.ref:"java.lang.AssertionError::()";
94 throw %1;
95 };
96 return;
97 };
98 """)
99 static final Quotable QUOTED_THROW_NO_PARAM = (Quotable & Runnable) () -> {
100 throw new AssertionError();
101 };
102
103 @IR("""
104 func @"f" (%0 : Var<java.type:"int">)java.type:"void" -> {
105 %1 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%2 : java.type:"int")java.type:"int" -> {
106 %3 : Var<java.type:"int"> = var %2 @"y";
107 %4 : java.type:"int" = var.load %0;
108 %5 : java.type:"int" = var.load %3;
109 %6 : java.type:"int" = add %4 %5;
110 return %6;
111 };
112 return;
113 };
114 """)
115 static final Quotable QUOTED_CAPTURE_PARAM = new Object() {
116 Quotable captureContext(int x) {
117 return (Quotable & IntUnaryOperator) y -> x + y;
118 }
119 }.captureContext(42);
120
121 static class Context {
122 int x, y;
123
124 Quotable capture() {
125 return (Quotable & IntUnaryOperator) z -> x + y + z;
126 }
127 }
128
129 @IR("""
130 func @"f" (%0 : java.type:"QuotableIntersectionTest$Context")java.type:"void" -> {
131 %1 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%2 : java.type:"int")java.type:"int" -> {
132 %3 : Var<java.type:"int"> = var %2 @"z";
133 %4 : java.type:"int" = field.load %0 @java.ref:"QuotableIntersectionTest$Context::x:int";
134 %5 : java.type:"int" = field.load %0 @java.ref:"QuotableIntersectionTest$Context::y:int";
135 %6 : java.type:"int" = add %4 %5;
136 %7 : java.type:"int" = var.load %3;
137 %8 : java.type:"int" = add %6 %7;
138 return %8;
139 };
140 return;
141 };
142 """)
143 static final Quotable QUOTED_CAPTURE_FIELD = new Context().capture();
144
145 @CodeReflection
146 @IR("""
147 func @"captureParam" (%0 : java.type:"int")java.type:"void" -> {
148 %1 : Var<java.type:"int"> = var %0 @"x";
149 %2 : java.type:"java.util.function.IntUnaryOperator" = lambda @lambda.isQuotable=true (%3 : java.type:"int")java.type:"int" -> {
150 %4 : Var<java.type:"int"> = var %3 @"y";
151 %5 : java.type:"int" = var.load %1;
152 %6 : java.type:"int" = var.load %4;
153 %7 : java.type:"int" = add %5 %6;
154 return %7;
155 };
156 %8 : Var<java.type:"java.util.function.IntUnaryOperator"> = var %2 @"op";
157 return;
158 };
159 """)
160 static void captureParam(int x) {
161 IntUnaryOperator op = (IntUnaryOperator & Quotable) y -> x + y;
162 }
163
164 int x, y;
165
166 @CodeReflection
167 @IR("""
168 func @"captureField" (%0 : java.type:"QuotableIntersectionTest")java.type:"void" -> {
169 %1 : java.type:"java.util.function.IntUnaryOperator" = lambda @lambda.isQuotable=true (%2 : java.type:"int")java.type:"int" -> {
170 %3 : Var<java.type:"int"> = var %2 @"z";
171 %4 : java.type:"int" = field.load %0 @java.ref:"QuotableIntersectionTest::x:int";
172 %5 : java.type:"int" = field.load %0 @java.ref:"QuotableIntersectionTest::y:int";
173 %6 : java.type:"int" = add %4 %5;
174 %7 : java.type:"int" = var.load %3;
175 %8 : java.type:"int" = add %6 %7;
176 return %8;
177 };
178 %9 : Var<java.type:"java.util.function.IntUnaryOperator"> = var %1 @"op";
179 return;
180 };
181 """)
182 void captureField() {
183 IntUnaryOperator op = (IntUnaryOperator & Quotable) z -> x + y + z;
184 }
185
186 static void m() {
187 }
188
189 @IR("""
190 func @"f" ()java.type:"void" -> {
191 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true ()java.type:"void" -> {
192 invoke @java.ref:"QuotableIntersectionTest::m():void";
193 return;
194 };
195 return;
196 };
197 """)
198 static final Quotable QUOTED_NO_PARAM_VOID_REF = (Quotable & Runnable) QuotableIntersectionTest::m;
199
200 static int g(int i) {
201 return i;
202 }
203
204 @IR("""
205 func @"f" ()java.type:"void" -> {
206 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%1 : java.type:"int")java.type:"int" -> {
207 %2 : Var<java.type:"int"> = var %1 @"x$0";
208 %3 : java.type:"int" = var.load %2;
209 %4 : java.type:"int" = invoke %3 @java.ref:"QuotableIntersectionTest::g(int):int";
210 return %4;
211 };
212 return;
213 };
214 """)
215 static final Quotable QUOTED_INT_PARAM_INT_RET_REF = (Quotable & IntUnaryOperator) QuotableIntersectionTest::g;
216
217 @IR("""
218 func @"f" ()java.type:"void" -> {
219 %0 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%1 : java.type:"int")java.type:"int[]" -> {
220 %2 : Var<java.type:"int"> = var %1 @"x$0";
221 %3 : java.type:"int" = var.load %2;
222 %4 : java.type:"int[]" = new %3 @java.ref:"int[]::(int)";
223 return %4;
224 };
225 return;
226 };
227 """)
228 static final Quotable QUOTED_INT_PARAM_ARR_RET_REF = (Quotable & IntFunction<int[]>) int[]::new;
229
230 static class ContextRef {
231 int g(int i) {
232 return i;
233 }
234
235 Quotable capture() {
236 return (Quotable & IntUnaryOperator) this::g;
237 }
238 }
239
240 @IR("""
241 func @"f" (%0 : java.type:"QuotableIntersectionTest$ContextRef")java.type:"void" -> {
242 %1 : java.type:"jdk.incubator.code.Quotable" = lambda @lambda.isQuotable=true (%2 : java.type:"int")java.type:"int" -> {
243 %3 : Var<java.type:"int"> = var %2 @"x$0";
244 %4 : java.type:"int" = var.load %3;
245 %5 : java.type:"int" = invoke %0 %4 @java.ref:"QuotableIntersectionTest$ContextRef::g(int):int";
246 return %5;
247 };
248 return;
249 };
250 """)
251 static final Quotable QUOTED_CAPTURE_THIS_REF = new ContextRef().capture();
252 }