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