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 import java.util.function.Consumer;
 26 import java.util.function.Supplier;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with lambda expressions.
 31  * @modules jdk.incubator.code
 32  * @build LambdaTest
 33  * @build CodeReflectionTester
 34  * @run main CodeReflectionTester LambdaTest
 35  */
 36 
 37 public class LambdaTest {
 38 
 39     @CodeReflection
 40     @IR("""
 41             func @"test1" (%0 : LambdaTest)void -> {
 42                 %1 : java.util.function.Consumer<java.lang.String> = lambda (%2 : java.lang.String)void -> {
 43                     %3 : Var<java.lang.String> = var %2 @"s";
 44                     %4 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream";
 45                     %5 : java.lang.String = var.load %3;
 46                     invoke %4 %5 @"java.io.PrintStream::println(java.lang.String)void";
 47                     return;
 48                 };
 49                 %6 : Var<java.util.function.Consumer<java.lang.String>> = var %1 @"c";
 50                 %7 : java.util.function.Consumer<java.lang.String> = var.load %6;
 51                 %8 : java.lang.String = constant @"Hello World";
 52                 invoke %7 %8 @"java.util.function.Consumer::accept(java.lang.Object)void";
 53                 return;
 54             };
 55             """)
 56     void test1() {
 57         Consumer<String> c = s -> {
 58             System.out.println(s);
 59         };
 60         c.accept("Hello World");
 61     }
 62 
 63     @CodeReflection
 64     @IR("""
 65             func @"test2" (%0 : LambdaTest)void -> {
 66                 %1 : java.util.function.Supplier<java.lang.String> = lambda ()java.lang.String -> {
 67                     %2 : java.lang.String = constant @"Hello World";
 68                     return %2;
 69                 };
 70                 %3 : Var<java.util.function.Supplier<java.lang.String>> = var %1 @"c";
 71                 %4 : java.util.function.Supplier<java.lang.String> = var.load %3;
 72                 %5 : java.lang.String = invoke %4 @"java.util.function.Supplier::get()java.lang.Object";
 73                 %6 : Var<java.lang.String> = var %5 @"s";
 74                 return;
 75             };
 76             """)
 77     void test2() {
 78         Supplier<String> c = () -> {
 79             return "Hello World";
 80         };
 81         String s = c.get();
 82     }
 83 
 84     @CodeReflection
 85     @IR("""
 86             func @"test3" (%0 : LambdaTest)void -> {
 87                 %1 : java.util.function.Supplier<java.lang.String> = lambda ()java.lang.String -> {
 88                     %2 : java.lang.String = constant @"Hello World";
 89                     return %2;
 90                 };
 91                 %3 : Var<java.util.function.Supplier<java.lang.String>> = var %1 @"c";
 92                 return;
 93             };
 94             """)
 95     void test3() {
 96         Supplier<String> c = () -> "Hello World";
 97     }
 98 
 99     String s_f;
100 
101     @CodeReflection
102     @IR("""
103             func @"test4" (%0 : LambdaTest)void -> {
104                 %1 : java.util.function.Supplier<java.lang.String> = lambda ()java.lang.String -> {
105                     %2 : java.lang.String = field.load %0 @"LambdaTest::s_f()java.lang.String";
106                     return %2;
107                 };
108                 %3 : Var<java.util.function.Supplier<java.lang.String>> = var %1 @"c";
109                 return;
110             };
111             """)
112     void test4() {
113         Supplier<String> c = () -> {
114             return s_f;
115         };
116     }
117 
118     @CodeReflection
119     @IR("""
120             func @"test5" (%0 : LambdaTest, %1 : int, %2 : int)void -> {
121                 %3 : Var<int> = var %1 @"i";
122                 %4 : Var<int> = var %2 @"j";
123                 %5 : int = constant @"3";
124                 %6 : Var<int> = var %5 @"k";
125                 %7 : java.util.function.Supplier<java.lang.Integer> = lambda ()java.lang.Integer -> {
126                     %8 : int = constant @"4";
127                     %9 : Var<int> = var %8 @"l";
128                     %10 : java.util.function.Supplier<java.lang.Integer> = lambda ()java.lang.Integer -> {
129                         %11 : int = var.load %4;
130                         %12 : int = var.load %6;
131                         %13 : int = add %11 %12;
132                         %14 : int = var.load %9;
133                         %15 : int = add %13 %14;
134                         %16 : Var<int> = var %15 @"r";
135                         %17 : int = var.load %16;
136                         %18 : java.lang.Integer = invoke %17 @"java.lang.Integer::valueOf(int)java.lang.Integer";
137                         return %18;
138                     };
139                     %19 : Var<java.util.function.Supplier<java.lang.Integer>> = var %10 @"sInner";
140                     %20 : int = var.load %3;
141                     %21 : java.util.function.Supplier<java.lang.Integer> = var.load %19;
142                     %22 : java.lang.Integer = invoke %21 @"java.util.function.Supplier::get()java.lang.Object";
143                     %23 : int = invoke %22 @"java.lang.Integer::intValue()int";
144                     %24 : int = add %20 %23;
145                     %25 : Var<int> = var %24 @"r";
146                     %26 : int = var.load %25;
147                     %27 : java.lang.Integer = invoke %26 @"java.lang.Integer::valueOf(int)java.lang.Integer";
148                     return %27;
149                 };
150                 %28 : Var<java.util.function.Supplier<java.lang.Integer>> = var %7 @"sOuter";
151                 return;
152             };
153             """)
154     void test5(int i, int j) {
155         int k = 3;
156         Supplier<Integer> sOuter = () -> {
157             int l = 4;
158             Supplier<Integer> sInner = () -> {
159                 int r = j + k + l;
160                 return r;
161             };
162 
163             int r = i + sInner.get();
164             return r;
165         };
166     }
167 
168     int f;
169 
170     @CodeReflection
171     @IR("""
172             func @"test6" (%0 : LambdaTest)void -> {
173                 %1 : java.util.function.Supplier<java.lang.Integer> = lambda ()java.lang.Integer -> {
174                     %2 : int = field.load %0 @"LambdaTest::f()int";
175                     %3 : java.lang.Integer = invoke %2 @"java.lang.Integer::valueOf(int)java.lang.Integer";
176                     return %3;
177                 };
178                 %4 : Var<java.util.function.Supplier<java.lang.Integer>> = var %1 @"s";
179                 return;
180             };
181             """)
182     void test6() {
183         Supplier<Integer> s = () -> f;
184     }
185 }