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