1/*
2 * Copyright (c) 2015, 2016, 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 8044537
27 * @summary Checking ACC_SYNTHETIC flag is generated for bridge method
28 *          generated for lambda expressions and method references.
29 * @modules jdk.compiler/com.sun.tools.javac.api
30 *          jdk.compiler/com.sun.tools.javac.main
31 *          jdk.jdeps/com.sun.tools.classfile
32 * @library /tools/lib /tools/javac/lib ../lib
33 * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
34 * @build BridgeMethodsForLambdaTest SyntheticTestDriver ExpectedClass ExpectedClasses
35 * @run main SyntheticTestDriver BridgeMethodsForLambdaTest 1
36 */
37
38import java.util.Comparator;
39import java.util.stream.IntStream;
40
41/**
42 * Synthetic members:
43 * 1. inner class for Inner1.
44 * 2. method for () -> {} in Inner1
45 * 3. method for () -> {} in Inner2
46 * 4. method references to private methods.
47 * 5. method for super::function()
48 * 6. method references to private static methods.
49 * 7. access method for private method function().
50 * 8. access method for private static method staticFunction().
51 * 9. method reference to vararg method.
52 * 10. method reference to array's method.
53 * 11. constructors for Inner1 and Inner2.
54 */
55@ExpectedClass(className = "BridgeMethodsForLambdaTest",
56        expectedMethods = {"<init>()", "<clinit>()", "function(java.lang.Integer[])"},
57        expectedNumberOfSyntheticMethods = 6)
58@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner1",
59        expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()", "run()"},
60        expectedFields = "lambda1",
61        expectedNumberOfSyntheticMethods = 4,
62        expectedNumberOfSyntheticFields = 1)
63@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner2",
64        expectedMethods = {"<init>()", "staticFunction()"},
65        expectedFields = "lambda1",
66        expectedNumberOfSyntheticMethods = 3)
67@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner3",
68        expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"},
69        expectedNumberOfSyntheticMethods = 1,
70        expectedNumberOfSyntheticFields = 1)
71@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner4",
72        expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"},
73        expectedNumberOfSyntheticMethods = 1,
74        expectedNumberOfSyntheticFields = 1)
75public class BridgeMethodsForLambdaTest {
76
77    private class Inner1 implements Runnable {
78        private Inner1() {
79        }
80        private Runnable lambda1 = () -> {
81        };
82        private void function() {
83        }
84        @Override
85        public void run() {
86        }
87    }
88
89    private static class Inner2 {
90        private Runnable lambda1 = () -> {
91        };
92        private static void staticFunction() {
93        }
94    }
95
96    private class Inner3 {
97        public void function() {
98        }
99    }
100
101    private class Inner4 extends Inner3 {
102        @Override
103        public void function() {
104            Runnable r = super::function;
105        }
106    }
107
108    private static int function(Integer...vararg) {
109        return 0;
110    }
111
112    {
113        Inner1 inner = new Inner1();
114        Runnable l1 = inner::function;
115        Runnable l2 = Inner1::new;
116        inner.lambda1 = inner::function;
117        Comparator<Integer> c = BridgeMethodsForLambdaTest::function;
118        IntStream.of(2).mapToObj(int[]::new);
119    }
120
121    static {
122        Inner2 inner = new Inner2();
123        Runnable l1 = Inner2::staticFunction;
124    }
125}
126