1 /*
2  * Copyright (c) 2011, 2015, 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 7115052 8003280 8006694 8129962
27  * @summary Add lambda tests
28  *  Add parser support for method references
29  *  temporarily workaround combo tests are causing time out in several platforms
30  * @library /tools/javac/lib
31  * @modules jdk.compiler/com.sun.tools.javac.api
32  *          jdk.compiler/com.sun.tools.javac.code
33  *          jdk.compiler/com.sun.tools.javac.comp
34  *          jdk.compiler/com.sun.tools.javac.main
35  *          jdk.compiler/com.sun.tools.javac.tree
36  *          jdk.compiler/com.sun.tools.javac.util
37  * @build combo.ComboTestHelper
38  * @run main MethodReferenceParserTest
39  */
40 
41 import java.io.IOException;
42 
43 import combo.ComboInstance;
44 import combo.ComboParameter;
45 import combo.ComboTask.Result;
46 import combo.ComboTestHelper;
47 
48 public class MethodReferenceParserTest extends ComboInstance<MethodReferenceParserTest> {
49 
50     enum ReferenceKind implements ComboParameter {
51         METHOD_REF("#{QUAL}::#{TARGS}m"),
52         CONSTRUCTOR_REF("#{QUAL}::#{TARGS}new"),
53         FALSE_REF("min < max"),
54         ERR_SUPER("#{QUAL}::#{TARGS}super"),
55         ERR_METH0("#{QUAL}::#{TARGS}m()"),
56         ERR_METH1("#{QUAL}::#{TARGS}m(X)"),
57         ERR_CONSTR0("#{QUAL}::#{TARGS}new()"),
58         ERR_CONSTR1("#{QUAL}::#{TARGS}new(X)");
59 
60         String referenceTemplate;
61 
ReferenceKind(String referenceTemplate)62         ReferenceKind(String referenceTemplate) {
63             this.referenceTemplate = referenceTemplate;
64         }
65 
erroneous()66         boolean erroneous() {
67             switch (this) {
68                 case ERR_SUPER:
69                 case ERR_METH0:
70                 case ERR_METH1:
71                 case ERR_CONSTR0:
72                 case ERR_CONSTR1:
73                     return true;
74                 default: return false;
75             }
76         }
77 
78         @Override
expand(String optParameter)79         public String expand(String optParameter) {
80             return referenceTemplate;
81         }
82     }
83 
84     enum ContextKind implements ComboParameter {
85         ASSIGN("SAM s = #{EXPR};"),
86         METHOD("m(#{EXPR}, i);");
87 
88         String contextTemplate;
89 
ContextKind(String contextTemplate)90         ContextKind(String contextTemplate) {
91             this.contextTemplate = contextTemplate;
92         }
93 
94         @Override
expand(String optParameter)95         public String expand(String optParameter) {
96             return contextTemplate;
97         }
98     }
99 
100     enum GenericKind implements ComboParameter {
101         NONE(""),
102         ONE("<X>"),
103         TWO("<X,Y>");
104 
105         String typeParameters;
106 
GenericKind(String typeParameters)107         GenericKind(String typeParameters) {
108             this.typeParameters = typeParameters;
109         }
110 
111         @Override
expand(String optParameter)112         public String expand(String optParameter) {
113             return typeParameters;
114         }
115     }
116 
117     enum QualifierKind implements ComboParameter {
118         THIS("this"),
119         SUPER("super"),
120         NEW("new Foo()"),
121         METHOD("m()"),
122         FIELD("a.f"),
123         UBOUND_SIMPLE("A"),
124         UNBOUND_ARRAY1("int[]"),
125         UNBOUND_ARRAY2("A<G>[][]"),
126         UNBOUND_GENERIC1("A<X>"),
127         UNBOUND_GENERIC2("A<X, Y>"),
128         UNBOUND_GENERIC3("A<? extends X, ? super Y>"),
129         UNBOUND_GENERIC4("A<int[], short[][]>"),
130         NESTED_GENERIC1("A<A<X,Y>, A<X,Y>>"),
131         NESTED_GENERIC2("A<A<A<X,Y>,A<X,Y>>, A<A<X,Y>,A<X,Y>>>");
132 
133         String qualifier;
134 
QualifierKind(String qualifier)135         QualifierKind(String qualifier) {
136             this.qualifier = qualifier;
137         }
138 
139         @Override
expand(String optParameter)140         public String expand(String optParameter) {
141             return qualifier;
142         }
143     }
144 
145     enum ExprKind implements ComboParameter {
146         NONE("#{MREF}"),
147         SINGLE_PAREN1("(#{MREF}#{SUBEXPR})"),
148         SINGLE_PAREN2("(#{MREF})#{SUBEXPR}"),
149         DOUBLE_PAREN1("((#{MREF}#{SUBEXPR}))"),
150         DOUBLE_PAREN2("((#{MREF})#{SUBEXPR})"),
151         DOUBLE_PAREN3("((#{MREF}))#{SUBEXPR}");
152 
153         String expressionTemplate;
154 
ExprKind(String expressionTemplate)155         ExprKind(String expressionTemplate) {
156             this.expressionTemplate = expressionTemplate;
157         }
158 
159         @Override
expand(String optParameter)160         public String expand(String optParameter) {
161             return expressionTemplate;
162         }
163     }
164 
165     enum SubExprKind implements ComboParameter {
166         NONE(""),
167         SELECT_FIELD(".f"),
168         SELECT_METHOD(".f()"),
169         SELECT_NEW(".new Foo()"),
170         POSTINC("++"),
171         POSTDEC("--");
172 
173         String subExpression;
174 
SubExprKind(String subExpression)175         SubExprKind(String subExpression) {
176             this.subExpression = subExpression;
177         }
178 
179         @Override
expand(String optParameter)180         public String expand(String optParameter) {
181             return subExpression;
182         }
183     }
184 
main(String... args)185     public static void main(String... args) throws Exception {
186         new ComboTestHelper<MethodReferenceParserTest>()
187                 .withDimension("MREF", (x, ref) -> x.rk = ref, ReferenceKind.values())
188                 .withDimension("QUAL", QualifierKind.values())
189                 .withDimension("TARGS", GenericKind.values())
190                 .withDimension("EXPR", ExprKind.values())
191                 .withDimension("SUBEXPR", SubExprKind.values())
192                 .withDimension("CTX", ContextKind.values())
193                 .run(MethodReferenceParserTest::new);
194     }
195 
196     ReferenceKind rk;
197 
198     String template = "class Test {\n" +
199                       "   void test() {\n" +
200                       "      #{CTX}\n" +
201                       "   }" +
202                       "}";
203 
204     @Override
doWork()205     public void doWork() throws IOException {
206         newCompilationTask()
207                 .withSourceFromTemplate(template)
208                 .parse(this::check);
209     }
210 
check(Result<?> res)211     void check(Result<?> res) {
212         if (res.hasErrors() != rk.erroneous()) {
213             fail("invalid diagnostics for source:\n" +
214                 res.compilationInfo() +
215                 "\nFound error: " + res.hasErrors() +
216                 "\nExpected error: " + rk.erroneous());
217         }
218     }
219 }
220