Mon, 21 Jan 2013 11:16:28 -0800
Merge
1 /*
2 * Copyright (c) 2011, 2013, 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 */
24 /*
25 * @test
26 * @bug 7115052
27 * @bug 8003280
28 * @summary Add lambda tests
29 * Add parser support for method references
30 * @library ../lib
31 * @build JavacTestingAbstractThreadedTest
32 * @run main MethodReferenceParserTest
33 */
35 import java.net.URI;
36 import java.util.Arrays;
37 import javax.tools.Diagnostic;
38 import javax.tools.JavaFileObject;
39 import javax.tools.SimpleJavaFileObject;
40 import com.sun.source.util.JavacTask;
42 public class MethodReferenceParserTest
43 extends JavacTestingAbstractThreadedTest
44 implements Runnable {
46 enum ReferenceKind {
47 METHOD_REF("#Q::#Gm"),
48 CONSTRUCTOR_REF("#Q::#Gnew"),
49 FALSE_REF("min < max"),
50 ERR_SUPER("#Q::#Gsuper"),
51 ERR_METH0("#Q::#Gm()"),
52 ERR_METH1("#Q::#Gm(X)"),
53 ERR_CONSTR0("#Q::#Gnew()"),
54 ERR_CONSTR1("#Q::#Gnew(X)");
56 String referenceTemplate;
58 ReferenceKind(String referenceTemplate) {
59 this.referenceTemplate = referenceTemplate;
60 }
62 String getReferenceString(QualifierKind qk, GenericKind gk) {
63 return referenceTemplate
64 .replaceAll("#Q", qk.qualifier)
65 .replaceAll("#G", gk.typeParameters);
66 }
68 boolean erroneous() {
69 switch (this) {
70 case ERR_SUPER:
71 case ERR_METH0:
72 case ERR_METH1:
73 case ERR_CONSTR0:
74 case ERR_CONSTR1:
75 return true;
76 default: return false;
77 }
78 }
79 }
81 enum ContextKind {
82 ASSIGN("SAM s = #E;"),
83 METHOD("m(#E, i);");
85 String contextTemplate;
87 ContextKind(String contextTemplate) {
88 this.contextTemplate = contextTemplate;
89 }
91 String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk,
92 GenericKind gk, SubExprKind sk) {
93 return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
94 }
95 }
97 enum GenericKind {
98 NONE(""),
99 ONE("<X>"),
100 TWO("<X,Y>");
102 String typeParameters;
104 GenericKind(String typeParameters) {
105 this.typeParameters = typeParameters;
106 }
107 }
109 enum QualifierKind {
110 THIS("this"),
111 SUPER("super"),
112 NEW("new Foo()"),
113 METHOD("m()"),
114 FIELD("a.f"),
115 UBOUND_SIMPLE("A"),
116 UNBOUND_ARRAY1("int[]"),
117 UNBOUND_ARRAY2("A<G>[][]"),
118 UNBOUND_GENERIC1("A<X>"),
119 UNBOUND_GENERIC2("A<X, Y>"),
120 UNBOUND_GENERIC3("A<? extends X, ? super Y>"),
121 UNBOUND_GENERIC4("A<int[], short[][]>"),
122 NESTED_GENERIC1("A<A<X,Y>, A<X,Y>>"),
123 NESTED_GENERIC2("A<A<A<X,Y>,A<X,Y>>, A<A<X,Y>,A<X,Y>>>");
125 String qualifier;
127 QualifierKind(String qualifier) {
128 this.qualifier = qualifier;
129 }
130 }
132 enum ExprKind {
133 NONE("#R::S"),
134 SINGLE_PAREN1("(#R#S)"),
135 SINGLE_PAREN2("(#R)#S"),
136 DOUBLE_PAREN1("((#R#S))"),
137 DOUBLE_PAREN2("((#R)#S)"),
138 DOUBLE_PAREN3("((#R))#S");
140 String expressionTemplate;
142 ExprKind(String expressionTemplate) {
143 this.expressionTemplate = expressionTemplate;
144 }
146 String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) {
147 return expressionTemplate
148 .replaceAll("#R", rk.getReferenceString(qk, gk))
149 .replaceAll("#S", sk.subExpression);
150 }
151 }
153 enum SubExprKind {
154 NONE(""),
155 SELECT_FIELD(".f"),
156 SELECT_METHOD(".f()"),
157 SELECT_NEW(".new Foo()"),
158 POSTINC("++"),
159 POSTDEC("--");
161 String subExpression;
163 SubExprKind(String subExpression) {
164 this.subExpression = subExpression;
165 }
166 }
168 public static void main(String... args) throws Exception {
169 for (ReferenceKind rk : ReferenceKind.values()) {
170 for (QualifierKind qk : QualifierKind.values()) {
171 for (GenericKind gk : GenericKind.values()) {
172 for (SubExprKind sk : SubExprKind.values()) {
173 for (ExprKind ek : ExprKind.values()) {
174 for (ContextKind ck : ContextKind.values()) {
175 pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck));
176 }
177 }
178 }
179 }
180 }
181 }
183 checkAfterExec();
184 }
186 ReferenceKind rk;
187 QualifierKind qk;
188 GenericKind gk;
189 SubExprKind sk;
190 ExprKind ek;
191 ContextKind ck;
192 JavaSource source;
193 DiagnosticChecker diagChecker;
195 MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek, ContextKind ck) {
196 this.rk = rk;
197 this.qk = qk;
198 this.gk = gk;
199 this.sk = sk;
200 this.ek = ek;
201 this.ck = ck;
202 this.source = new JavaSource();
203 this.diagChecker = new DiagnosticChecker();
204 }
206 class JavaSource extends SimpleJavaFileObject {
208 String template = "class Test {\n" +
209 " void test() {\n" +
210 " #C\n" +
211 " }" +
212 "}";
214 String source;
216 public JavaSource() {
217 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
218 source = template.replaceAll("#C", ck.contextString(ek, rk, qk, gk, sk));
219 }
221 @Override
222 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
223 return source;
224 }
225 }
227 @Override
228 public void run() {
229 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
230 null, null, Arrays.asList(source));
231 try {
232 ct.parse();
233 } catch (Throwable ex) {
234 processException(ex);
235 return;
236 }
237 check();
238 }
240 void check() {
241 checkCount.incrementAndGet();
243 if (diagChecker.errorFound != rk.erroneous()) {
244 throw new Error("invalid diagnostics for source:\n" +
245 source.getCharContent(true) +
246 "\nFound error: " + diagChecker.errorFound +
247 "\nExpected error: " + rk.erroneous());
248 }
249 }
251 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
253 boolean errorFound;
255 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
256 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
257 errorFound = true;
258 }
259 }
260 }
262 }