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.util.function.Consumer;
26 import java.util.function.Predicate;
27 import java.util.function.Supplier;
28
29 /*
30 * @test
31 * @summary Smoke test for code reflection with lambda expressions.
32 * @modules jdk.incubator.code
33 * @build LambdaTest
34 * @build CodeReflectionTester
35 * @run main CodeReflectionTester LambdaTest
36 */
37
38 public class LambdaTest {
39
40 @Reflect
41 @IR("""
42 func @"test1" (%0 : java.type:"LambdaTest")java.type:"void" -> {
43 %1 : java.type:"java.util.function.Consumer<java.lang.String>" = lambda @lambda.isReflectable=true (%2 : java.type:"java.lang.String")java.type:"void" -> {
44 %3 : Var<java.type:"java.lang.String"> = var %2 @"s";
45 %4 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
46 %5 : java.type:"java.lang.String" = var.load %3;
47 invoke %4 %5 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
48 return;
49 };
50 %6 : Var<java.type:"java.util.function.Consumer<java.lang.String>"> = var %1 @"c";
51 %7 : java.type:"java.util.function.Consumer<java.lang.String>" = var.load %6;
52 %8 : java.type:"java.lang.String" = constant @"Hello World";
53 invoke %7 %8 @java.ref:"java.util.function.Consumer::accept(java.lang.Object):void";
54 return;
55 };
56 """)
57 void test1() {
58 Consumer<String> c = s -> {
59 System.out.println(s);
60 };
61 c.accept("Hello World");
62 }
63
64 @Reflect
65 @IR("""
66 func @"test2" (%0 : java.type:"LambdaTest")java.type:"void" -> {
67 %1 : java.type:"java.util.function.Supplier<java.lang.String>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.String" -> {
68 %2 : java.type:"java.lang.String" = constant @"Hello World";
69 return %2;
70 };
71 %3 : Var<java.type:"java.util.function.Supplier<java.lang.String>"> = var %1 @"c";
72 %4 : java.type:"java.util.function.Supplier<java.lang.String>" = var.load %3;
73 %5 : java.type:"java.lang.String" = invoke %4 @java.ref:"java.util.function.Supplier::get():java.lang.Object";
74 %6 : java.type:"java.lang.String" = cast %5 @java.type:"java.lang.String";
75 %7 : Var<java.type:"java.lang.String"> = var %6 @"s";
76 return;
77 };
78 """)
79 void test2() {
80 Supplier<String> c = () -> {
81 return "Hello World";
82 };
83 String s = c.get();
84 }
85
86 @Reflect
87 @IR("""
88 func @"test3" (%0 : java.type:"LambdaTest")java.type:"void" -> {
89 %1 : java.type:"java.util.function.Supplier<java.lang.String>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.String" -> {
90 %2 : java.type:"java.lang.String" = constant @"Hello World";
91 return %2;
92 };
93 %3 : Var<java.type:"java.util.function.Supplier<java.lang.String>"> = var %1 @"c";
94 return;
95 };
96 """)
97 void test3() {
98 Supplier<String> c = () -> "Hello World";
99 }
100
101 String s_f;
102
103 @Reflect
104 @IR("""
105 func @"test4" (%0 : java.type:"LambdaTest")java.type:"void" -> {
106 %1 : java.type:"java.util.function.Supplier<java.lang.String>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.String" -> {
107 %2 : java.type:"java.lang.String" = field.load %0 @java.ref:"LambdaTest::s_f:java.lang.String";
108 return %2;
109 };
110 %3 : Var<java.type:"java.util.function.Supplier<java.lang.String>"> = var %1 @"c";
111 return;
112 };
113 """)
114 void test4() {
115 Supplier<String> c = () -> {
116 return s_f;
117 };
118 }
119
120 @Reflect
121 @IR("""
122 func @"test5" (%0 : java.type:"LambdaTest", %1 : java.type:"int", %2 : java.type:"int")java.type:"void" -> {
123 %3 : Var<java.type:"int"> = var %1 @"i";
124 %4 : Var<java.type:"int"> = var %2 @"j";
125 %5 : java.type:"int" = constant @3;
126 %6 : Var<java.type:"int"> = var %5 @"k";
127 %7 : java.type:"java.util.function.Supplier<java.lang.Integer>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.Integer" -> {
128 %8 : java.type:"int" = constant @4;
129 %9 : Var<java.type:"int"> = var %8 @"l";
130 %10 : java.type:"java.util.function.Supplier<java.lang.Integer>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.Integer" -> {
131 %11 : java.type:"int" = var.load %4;
132 %12 : java.type:"int" = var.load %6;
133 %13 : java.type:"int" = add %11 %12;
134 %14 : java.type:"int" = var.load %9;
135 %15 : java.type:"int" = add %13 %14;
136 %16 : Var<java.type:"int"> = var %15 @"r";
137 %17 : java.type:"int" = var.load %16;
138 %18 : java.type:"java.lang.Integer" = invoke %17 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
139 return %18;
140 };
141 %19 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %10 @"sInner";
142 %20 : java.type:"int" = var.load %3;
143 %21 : java.type:"java.util.function.Supplier<java.lang.Integer>" = var.load %19;
144 %22 : java.type:"java.lang.Integer" = invoke %21 @java.ref:"java.util.function.Supplier::get():java.lang.Object";
145 %23 : java.type:"java.lang.Integer" = cast %22 @java.type:"java.lang.Integer";
146 %24 : java.type:"int" = invoke %23 @java.ref:"java.lang.Integer::intValue():int";
147 %25 : java.type:"int" = add %20 %24;
148 %26 : Var<java.type:"int"> = var %25 @"r";
149 %27 : java.type:"int" = var.load %26;
150 %28 : java.type:"java.lang.Integer" = invoke %27 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
151 return %28;
152 };
153 %29 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %7 @"sOuter";
154 return;
155 };
156 """)
157 void test5(int i, int j) {
158 int k = 3;
159 Supplier<Integer> sOuter = () -> {
160 int l = 4;
161 Supplier<Integer> sInner = () -> {
162 int r = j + k + l;
163 return r;
164 };
165
166 int r = i + sInner.get();
167 return r;
168 };
169 }
170
171 int f;
172
173 @Reflect
174 @IR("""
175 func @"test6" (%0 : java.type:"LambdaTest")java.type:"void" -> {
176 %1 : java.type:"java.util.function.Supplier<java.lang.Integer>" = lambda @lambda.isReflectable=true ()java.type:"java.lang.Integer" -> {
177 %2 : java.type:"int" = field.load %0 @java.ref:"LambdaTest::f:int";
178 %3 : java.type:"java.lang.Integer" = invoke %2 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
179 return %3;
180 };
181 %4 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %1 @"s";
182 return;
183 };
184 """)
185 void test6() {
186 Supplier<Integer> s = () -> f;
187 }
188
189 @Reflect
190 @IR("""
191 func @"test7" (%0 : java.type:"LambdaTest")java.type:"java.util.function.Predicate<java.lang.Object>" -> {
192 %3 : java.type:"java.util.function.Predicate<java.lang.Object>" = lambda @lambda.isReflectable=true (%4 : java.type:"java.lang.Object")java.type:"boolean" -> {
193 %5 : Var<java.type:"java.lang.Object"> = var %4 @"v";
194 %1 : java.type:"java.lang.String" = constant @null;
195 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
196 %6 : java.type:"boolean" = java.cand
197 ()java.type:"boolean" -> {
198 %7 : java.type:"java.lang.Object" = var.load %5;
199 %8 : java.type:"boolean" = pattern.match %7
200 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
201 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
202 yield %9;
203 }
204 (%10 : java.type:"java.lang.String")java.type:"void" -> {
205 var.store %2 %10;
206 yield;
207 };
208 yield %8;
209 }
210 ()java.type:"boolean" -> {
211 %11 : java.type:"java.lang.String" = var.load %2;
212 %12 : java.type:"boolean" = invoke %11 @java.ref:"java.lang.String::isEmpty():boolean";
213 %13 : java.type:"boolean" = not %12;
214 yield %13;
215 };
216 return %6;
217 };
218 return %3;
219 };
220 """)
221 Predicate<Object> test7() {
222 return v -> v instanceof String s && !s.isEmpty();
223 }
224
225 @Reflect
226 @IR("""
227 func @"f" ()java.type:"void" -> {
228 %3 : java.type:"java.util.function.Predicate<java.lang.Object>" = lambda @lambda.isReflectable=true (%4 : java.type:"java.lang.Object")java.type:"boolean" -> {
229 %5 : Var<java.type:"java.lang.Object"> = var %4 @"v";
230 %1 : java.type:"java.lang.String" = constant @null;
231 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
232 %6 : java.type:"boolean" = java.cand
233 ()java.type:"boolean" -> {
234 %7 : java.type:"java.lang.Object" = var.load %5;
235 %8 : java.type:"boolean" = pattern.match %7
236 ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
237 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
238 yield %9;
239 }
240 (%10 : java.type:"java.lang.String")java.type:"void" -> {
241 var.store %2 %10;
242 yield;
243 };
244 yield %8;
245 }
246 ()java.type:"boolean" -> {
247 %11 : java.type:"java.lang.String" = var.load %2;
248 %12 : java.type:"boolean" = invoke %11 @java.ref:"java.lang.String::isEmpty():boolean";
249 %13 : java.type:"boolean" = not %12;
250 yield %13;
251 };
252 return %6;
253 };
254 return;
255 };
256 """)
257 static Predicate<Object> test8 = v -> v instanceof String s && !s.isEmpty();
258 }