1 /*
2  * Copyright (c) 2014, 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  * @bug 8035776
27  * @summary Consistent Lambda construction
28  */
29 
30 import java.lang.invoke.LambdaMetafactory;
31 import java.lang.invoke.LambdaConversionException;
32 import java.lang.invoke.MethodHandle;
33 import java.lang.invoke.MethodHandles;
34 import java.lang.invoke.MethodType;
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 public class LambdaReturn {
39 
40     interface I {
m()41         void m();
42     }
43 
hereV()44     static void hereV() {}
hereS()45     static String hereS() { return "hi"; }
46     static MethodHandles.Lookup l;
mt(Class<?> k)47     private static MethodType mt(Class<?> k) { return MethodType.methodType(k); }
mt(Class<?> k, Class<?> k2)48     private static MethodType mt(Class<?> k, Class<?> k2) { return MethodType.methodType(k, k2); }
amf(List<String> errs, MethodHandle h, MethodType mts, MethodType mtf, MethodType mtb, boolean shouldWork)49     private static void amf(List<String> errs, MethodHandle h, MethodType mts, MethodType mtf, MethodType mtb, boolean shouldWork) {
50         MethodType mti = mt(I.class);
51         try {
52             LambdaMetafactory.altMetafactory(l, "m", mti, mts,h,mtf,
53                                           LambdaMetafactory.FLAG_BRIDGES, 1, mtb);
54         } catch(LambdaConversionException e) {
55             if (shouldWork)  errs.add("Error: Should work h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb + " got: " + e);
56             return;
57         }
58         if (!shouldWork)  errs.add("Error: Should fail h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb);
59     }
60 
main(String[] args)61     public static void main(String[] args) throws Throwable {
62         l = MethodHandles.lookup();
63         MethodHandle hV = l.findStatic(LambdaReturn.class, "hereV", mt(void.class));
64         MethodHandle hS = l.findStatic(LambdaReturn.class, "hereS", mt(String.class));
65         List<String> errs = new ArrayList<>();
66         MethodType V = mt(void.class);
67         MethodType S = mt(String.class);
68         MethodType O = mt(Object.class);
69         MethodType I = mt(int.class);
70         amf(errs, hS, S, S, O, true);
71         amf(errs, hS, S, S, V, false);
72         amf(errs, hS, S, S, I, false);
73         amf(errs, hS, O, S, S, true);
74         amf(errs, hS, V, S, S, false);
75         amf(errs, hS, I, S, S, false);
76         amf(errs, hS, O, O, S, false);
77         amf(errs, hS, S, O, O, false);
78         amf(errs, hV, V, V, O, false);
79         amf(errs, hV, V, V, I, false);
80         amf(errs, hV, V, V, S, false);
81         amf(errs, hV, O, V, V, false);
82         amf(errs, hV, I, V, V, false);
83         amf(errs, hV, S, V, V, false);
84 
85         if (errs.size() > 0) {
86             for (String err : errs) {
87                 System.err.println(err);
88             }
89             throw new AssertionError("Errors: " + errs.size());
90         }
91     }
92 }
93