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