Wed, 23 Jan 2013 20:57:40 +0000
8006694: temporarily workaround combo tests are causing time out in several platforms
Reviewed-by: jjg
Contributed-by: maurizio.cimadamore@oracle.com
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 8003280 8006694
27 * @summary Add lambda tests
28 * perform automated checks in type inference in lambda expressions
29 * in different contexts
30 * temporarily workaround combo tests are causing time out in several platforms
31 * @library ../../../lib
32 * @build JavacTestingAbstractThreadedTest
33 * @compile TypeInferenceComboTest.java
34 * @run main/othervm/timeout=360 TypeInferenceComboTest
35 */
37 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
38 // see JDK-8006746
40 import java.net.URI;
41 import java.util.Arrays;
42 import javax.tools.Diagnostic;
43 import javax.tools.JavaFileObject;
44 import javax.tools.SimpleJavaFileObject;
45 import com.sun.source.util.JavacTask;
47 public class TypeInferenceComboTest
48 extends JavacTestingAbstractThreadedTest
49 implements Runnable {
50 enum Context {
51 ASSIGNMENT("SAM#Type s = #LBody;"),
52 METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
53 "void method2() {\n" +
54 " method1(#LBody);\n" +
55 "}"),
56 RETURN_OF_METHOD("SAM#Type method1() {\n" +
57 " return #LBody;\n" +
58 "}"),
59 LAMBDA_RETURN_EXPRESSION("SAM2 s2 = () -> {return (SAM#Type)#LBody;};\n"),
60 ARRAY_INITIALIZER("Object[] oarray = {\"a\", 1, (SAM#Type)#LBody};");
62 String context;
64 Context(String context) {
65 this.context = context;
66 }
68 String getContext(SamKind sk, TypeKind samTargetT, Keyword kw,
69 TypeKind parameterT, TypeKind returnT, LambdaKind lk,
70 ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
71 String result = context;
72 if (sk == SamKind.GENERIC) {
73 if(this == Context.METHOD_CALL) {
74 result = result.replaceAll("#GenericDeclKind",
75 gdk.getGenericDeclKind(samTargetT));
76 if(gdk == GenericDeclKind.NON_GENERIC)
77 result = result.replaceAll("#Type", "<" +
78 samTargetT.typeStr + ">");
79 else //#GenericDeclKind is <T> or <T extends xxx>
80 result = result.replaceAll("#Type", "<T>");
81 }
82 else {
83 if(kw == Keyword.VOID)
84 result = result.replaceAll("#Type", "<" +
85 samTargetT.typeStr + ">");
86 else
87 result = result.replaceAll("#Type", "<? " + kw.keyStr +
88 " " + samTargetT.typeStr + ">");
89 }
90 }
91 else
92 result = result.replaceAll("#Type", "").
93 replaceAll("#GenericDeclKind", "");
95 return result.replaceAll("#LBody",
96 lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
97 }
98 }
100 enum SamKind {
101 GENERIC("interface SAM<T> { #R m(#ARG); }"),
102 NON_GENERIC("interface SAM { #R m(#ARG); }");
104 String sam_str;
106 SamKind(String sam_str) {
107 this.sam_str = sam_str;
108 }
110 String getSam(TypeKind parameterT, TypeKind returnT) {
111 return sam_str.replaceAll("#ARG",
112 parameterT == TypeKind.VOID ?
113 "" : parameterT.typeStr + " arg")
114 .replaceAll("#R", returnT.typeStr);
115 }
116 }
118 enum TypeKind {
119 VOID("void", ""),
120 STRING("String", "\"hello\""),
121 INTEGER("Integer", "1"),
122 INT("int", "0"),
123 COMPARATOR("java.util.Comparator<String>",
124 "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
125 SAM("SAM2", "null"),
126 GENERIC("T", null);
128 String typeStr;
129 String valStr;
131 TypeKind(String typeStr, String valStr) {
132 this.typeStr = typeStr;
133 this.valStr = valStr;
134 }
135 }
137 enum LambdaKind {
138 EXPRESSION("#VAL"),
139 STATEMENT("{return #VAL;}");
141 String stmt;
143 LambdaKind(String stmt) {
144 this.stmt = stmt;
145 }
146 }
148 enum ParameterKind {
149 EXPLICIT("#TYPE"),
150 IMPLICIT("");
152 String paramTemplate;
154 ParameterKind(String paramTemplate) {
155 this.paramTemplate = paramTemplate;
156 }
157 }
159 enum Keyword {
160 SUPER("super"),
161 EXTENDS("extends"),
162 VOID("");
164 String keyStr;
166 Keyword(String keyStr) {
167 this.keyStr = keyStr;
168 }
169 }
171 enum LambdaBody {
172 //no parameters, return type is one of the TypeKind
173 RETURN_VOID("() -> #RET"),
174 //has parameters, return type is one of the TypeKind
175 RETURN_ARG("(#PK arg) -> #RET");
177 String bodyStr;
179 LambdaBody(String bodyStr) {
180 this.bodyStr = bodyStr;
181 }
183 String getLambdaBody(TypeKind samTargetT, TypeKind parameterT,
184 TypeKind returnT, LambdaKind lk, ParameterKind pk) {
185 String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
187 if(result.contains("#TYPE")) {
188 if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
189 result = result.replaceAll("#TYPE",
190 samTargetT == null? "": samTargetT.typeStr);
191 else
192 result = result.replaceAll("#TYPE", parameterT.typeStr);
193 }
194 if (this == RETURN_ARG && parameterT == returnT)
195 return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
196 else {
197 if(returnT != TypeKind.GENERIC)
198 return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL",
199 (returnT==TypeKind.VOID &&
200 lk==LambdaKind.EXPRESSION) ? "{}" : returnT.valStr));
201 else
202 return result.replaceAll("#RET",
203 lk.stmt.replaceAll("#VAL", samTargetT.valStr));
204 }
205 }
206 }
208 enum GenericDeclKind {
209 NON_GENERIC(""),
210 GENERIC_NOBOUND("<T>"),
211 GENERIC_BOUND("<T extends #ExtendedType>");
212 String typeStr;
214 GenericDeclKind(String typeStr) {
215 this.typeStr = typeStr;
216 }
218 String getGenericDeclKind(TypeKind et) {
219 return typeStr.replaceAll("#ExtendedType", et==null? "":et.typeStr);
220 }
221 }
223 boolean checkTypeInference() {
224 if (parameterType == TypeKind.VOID) {
225 if (lambdaBodyType != LambdaBody.RETURN_VOID)
226 return false;
227 }
228 else if (lambdaBodyType != LambdaBody.RETURN_ARG)
229 return false;
230 if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND ||
231 genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
232 if ( parameterType == TypeKind.GENERIC &&
233 parameterKind == ParameterKind.IMPLICIT) //cyclic inference
234 return false;
235 }
236 return true;
237 }
239 String templateStr = "#C\n" +
240 "interface SAM2 {\n" +
241 " SAM m();\n" +
242 "}\n";
243 SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
244 public String toString() {
245 return template.replaceAll("#C",
246 samKind.getSam(parameterType, returnType));
247 }
248 };
250 SourceFile clientSourceFile = new SourceFile("Client.java",
251 "class Client { \n" +
252 " #Context\n" +
253 "}") {
254 public String toString() {
255 return template.replaceAll("#Context",
256 context.getContext(samKind, samTargetType, keyword,
257 parameterType, returnType, lambdaKind, parameterKind,
258 genericDeclKind, lambdaBodyType));
259 }
260 };
262 public void run() {
263 DiagnosticChecker dc = new DiagnosticChecker();
264 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), dc,
265 null, null, Arrays.asList(samSourceFile, clientSourceFile));
266 try {
267 ct.analyze();
268 } catch (Throwable t) {
269 processException(t);
270 }
271 if (dc.errorFound == checkTypeInference()) {
272 throw new AssertionError(samSourceFile + "\n\n" +
273 clientSourceFile + "\n" + parameterType + " " + returnType);
274 }
275 }
277 abstract class SourceFile extends SimpleJavaFileObject {
279 protected String template;
281 public SourceFile(String filename, String template) {
282 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
283 this.template = template;
284 }
286 @Override
287 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
288 return toString();
289 }
291 public abstract String toString();
292 }
294 static class DiagnosticChecker
295 implements javax.tools.DiagnosticListener<JavaFileObject> {
297 boolean errorFound = false;
299 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
300 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
301 errorFound = true;
302 }
303 }
304 }
306 SamKind samKind;
307 TypeKind samTargetType;
308 TypeKind parameterType;
309 TypeKind returnType;
310 Context context;
311 LambdaBody lambdaBodyType;
312 LambdaKind lambdaKind;
313 ParameterKind parameterKind;
314 Keyword keyword;
315 GenericDeclKind genericDeclKind;
317 TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT,
318 TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk,
319 ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
320 samKind = sk;
321 samTargetType = samTargetT;
322 parameterType = parameterT;
323 returnType = returnT;
324 context = c;
325 lambdaKind = lk;
326 parameterKind = pk;
327 keyword = kw;
328 lambdaBodyType = lb;
329 genericDeclKind = gdk;
330 }
332 public static void main(String[] args) throws Exception {
333 for(Context ct : Context.values()) {
334 for (TypeKind returnT : TypeKind.values()) {
335 for (TypeKind parameterT : TypeKind.values()) {
336 for(LambdaBody lb : LambdaBody.values()) {
337 for (ParameterKind parameterK : ParameterKind.values()) {
338 for(LambdaKind lambdaK : LambdaKind.values()) {
339 for (SamKind sk : SamKind.values()) {
340 if (sk == SamKind.NON_GENERIC) {
341 generateNonGenericSAM(ct, returnT,
342 parameterT, lb, parameterK,
343 lambdaK, sk);
344 }
345 else if (sk == SamKind.GENERIC) {
346 generateGenericSAM(ct, returnT,
347 parameterT, lb, parameterK,
348 lambdaK, sk);
349 }
350 }
351 }
352 }
353 }
354 }
355 }
356 }
358 checkAfterExec(false);
359 }
361 static void generateNonGenericSAM(Context ct, TypeKind returnT,
362 TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
363 LambdaKind lambdaK, SamKind sk) {
364 if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC ) {
365 pool.execute(new TypeInferenceComboTest(sk, null, parameterT,
366 returnT, lb, ct, lambdaK, parameterK, null, null));
367 }
368 }
370 static void generateGenericSAM(Context ct, TypeKind returnT,
371 TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
372 LambdaKind lambdaK, SamKind sk) {
373 for (Keyword kw : Keyword.values()) {
374 for (TypeKind samTargetT : TypeKind.values()) {
375 if(samTargetT != TypeKind.VOID &&
376 samTargetT != TypeKind.INT &&
377 samTargetT != TypeKind.GENERIC &&
378 (parameterT == TypeKind.GENERIC ||
379 returnT == TypeKind.GENERIC)) {
380 if(ct != Context.METHOD_CALL) {
381 pool.execute(
382 new TypeInferenceComboTest(sk, samTargetT, parameterT,
383 returnT, lb, ct, lambdaK, parameterK, kw, null));
384 } else {//Context.METHOD_CALL
385 for (GenericDeclKind gdk :
386 GenericDeclKind.values())
387 pool.execute(
388 new TypeInferenceComboTest(sk, samTargetT,
389 parameterT, returnT, lb, ct, lambdaK,
390 parameterK, kw, gdk));
391 }
392 }
393 }
394 }
395 }
397 }