test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java

Mon, 02 Sep 2013 22:38:36 +0100

author
vromero
date
Mon, 02 Sep 2013 22:38:36 +0100
changeset 2000
4a6acc42c3a1
parent 1520
5c956be64b9e
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8016177: structural most specific and stuckness
Reviewed-by: jjg, vromero
Contributed-by: maurizio.cimadamore@oracle.com

mcimadamore@1415 1 /*
vromero@1482 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1415 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1415 4 *
mcimadamore@1415 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1415 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1415 7 * published by the Free Software Foundation.
mcimadamore@1415 8 *
mcimadamore@1415 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1415 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1415 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1415 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1415 13 * accompanied this code).
mcimadamore@1415 14 *
mcimadamore@1415 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1415 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1415 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1415 18 *
mcimadamore@1415 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1415 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1415 21 * questions.
mcimadamore@1415 22 */
mcimadamore@1415 23
mcimadamore@1415 24 /**
mcimadamore@1415 25 * @test
vromero@1520 26 * @bug 8003280 8006694
mcimadamore@1415 27 * @summary Add lambda tests
vromero@1482 28 * perform automated checks in type inference in lambda expressions
vromero@1482 29 * in different contexts
vromero@1520 30 * temporarily workaround combo tests are causing time out in several platforms
vromero@1482 31 * @library ../../../lib
vromero@1482 32 * @build JavacTestingAbstractThreadedTest
mcimadamore@1415 33 * @compile TypeInferenceComboTest.java
vromero@1520 34 * @run main/othervm/timeout=360 TypeInferenceComboTest
mcimadamore@1415 35 */
mcimadamore@1415 36
vromero@1520 37 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
vromero@1520 38 // see JDK-8006746
vromero@1520 39
mcimadamore@1415 40 import java.net.URI;
mcimadamore@1415 41 import java.util.Arrays;
mcimadamore@1415 42 import javax.tools.Diagnostic;
mcimadamore@1415 43 import javax.tools.JavaFileObject;
mcimadamore@1415 44 import javax.tools.SimpleJavaFileObject;
vromero@1482 45 import com.sun.source.util.JavacTask;
mcimadamore@1415 46
vromero@1482 47 public class TypeInferenceComboTest
vromero@1482 48 extends JavacTestingAbstractThreadedTest
vromero@1482 49 implements Runnable {
mcimadamore@1415 50 enum Context {
mcimadamore@1415 51 ASSIGNMENT("SAM#Type s = #LBody;"),
mcimadamore@1415 52 METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
mcimadamore@1415 53 "void method2() {\n" +
mcimadamore@1415 54 " method1(#LBody);\n" +
mcimadamore@1415 55 "}"),
mcimadamore@1415 56 RETURN_OF_METHOD("SAM#Type method1() {\n" +
mcimadamore@1415 57 " return #LBody;\n" +
mcimadamore@1415 58 "}"),
mcimadamore@1415 59 LAMBDA_RETURN_EXPRESSION("SAM2 s2 = () -> {return (SAM#Type)#LBody;};\n"),
mcimadamore@1415 60 ARRAY_INITIALIZER("Object[] oarray = {\"a\", 1, (SAM#Type)#LBody};");
mcimadamore@1415 61
mcimadamore@1415 62 String context;
mcimadamore@1415 63
mcimadamore@1415 64 Context(String context) {
mcimadamore@1415 65 this.context = context;
mcimadamore@1415 66 }
mcimadamore@1415 67
vromero@1482 68 String getContext(SamKind sk, TypeKind samTargetT, Keyword kw,
vromero@1482 69 TypeKind parameterT, TypeKind returnT, LambdaKind lk,
vromero@1482 70 ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
mcimadamore@1415 71 String result = context;
mcimadamore@1415 72 if (sk == SamKind.GENERIC) {
mcimadamore@1415 73 if(this == Context.METHOD_CALL) {
vromero@1482 74 result = result.replaceAll("#GenericDeclKind",
vromero@1482 75 gdk.getGenericDeclKind(samTargetT));
mcimadamore@1415 76 if(gdk == GenericDeclKind.NON_GENERIC)
vromero@1482 77 result = result.replaceAll("#Type", "<" +
vromero@1482 78 samTargetT.typeStr + ">");
mcimadamore@1415 79 else //#GenericDeclKind is <T> or <T extends xxx>
mcimadamore@1415 80 result = result.replaceAll("#Type", "<T>");
mcimadamore@1415 81 }
mcimadamore@1415 82 else {
mcimadamore@1415 83 if(kw == Keyword.VOID)
vromero@1482 84 result = result.replaceAll("#Type", "<" +
vromero@1482 85 samTargetT.typeStr + ">");
mcimadamore@1415 86 else
vromero@1482 87 result = result.replaceAll("#Type", "<? " + kw.keyStr +
vromero@1482 88 " " + samTargetT.typeStr + ">");
mcimadamore@1415 89 }
mcimadamore@1415 90 }
mcimadamore@1415 91 else
vromero@1482 92 result = result.replaceAll("#Type", "").
vromero@1482 93 replaceAll("#GenericDeclKind", "");
mcimadamore@1415 94
vromero@1482 95 return result.replaceAll("#LBody",
vromero@1482 96 lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
mcimadamore@1415 97 }
mcimadamore@1415 98 }
mcimadamore@1415 99
mcimadamore@1415 100 enum SamKind {
mcimadamore@1415 101 GENERIC("interface SAM<T> { #R m(#ARG); }"),
mcimadamore@1415 102 NON_GENERIC("interface SAM { #R m(#ARG); }");
mcimadamore@1415 103
mcimadamore@1415 104 String sam_str;
mcimadamore@1415 105
mcimadamore@1415 106 SamKind(String sam_str) {
mcimadamore@1415 107 this.sam_str = sam_str;
mcimadamore@1415 108 }
mcimadamore@1415 109
mcimadamore@1415 110 String getSam(TypeKind parameterT, TypeKind returnT) {
vromero@1482 111 return sam_str.replaceAll("#ARG",
vromero@1482 112 parameterT == TypeKind.VOID ?
vromero@1482 113 "" : parameterT.typeStr + " arg")
vromero@1482 114 .replaceAll("#R", returnT.typeStr);
mcimadamore@1415 115 }
mcimadamore@1415 116 }
mcimadamore@1415 117
mcimadamore@1415 118 enum TypeKind {
mcimadamore@1415 119 VOID("void", ""),
mcimadamore@1415 120 STRING("String", "\"hello\""),
mcimadamore@1415 121 INTEGER("Integer", "1"),
mcimadamore@1415 122 INT("int", "0"),
vromero@1482 123 COMPARATOR("java.util.Comparator<String>",
vromero@1482 124 "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
mcimadamore@1415 125 SAM("SAM2", "null"),
mcimadamore@1415 126 GENERIC("T", null);
mcimadamore@1415 127
mcimadamore@1415 128 String typeStr;
mcimadamore@1415 129 String valStr;
mcimadamore@1415 130
mcimadamore@1415 131 TypeKind(String typeStr, String valStr) {
mcimadamore@1415 132 this.typeStr = typeStr;
mcimadamore@1415 133 this.valStr = valStr;
mcimadamore@1415 134 }
mcimadamore@1415 135 }
mcimadamore@1415 136
mcimadamore@1415 137 enum LambdaKind {
mcimadamore@1415 138 EXPRESSION("#VAL"),
mcimadamore@1415 139 STATEMENT("{return #VAL;}");
mcimadamore@1415 140
mcimadamore@1415 141 String stmt;
mcimadamore@1415 142
mcimadamore@1415 143 LambdaKind(String stmt) {
mcimadamore@1415 144 this.stmt = stmt;
mcimadamore@1415 145 }
mcimadamore@1415 146 }
mcimadamore@1415 147
mcimadamore@1415 148 enum ParameterKind {
mcimadamore@1415 149 EXPLICIT("#TYPE"),
mcimadamore@1415 150 IMPLICIT("");
mcimadamore@1415 151
mcimadamore@1415 152 String paramTemplate;
mcimadamore@1415 153
mcimadamore@1415 154 ParameterKind(String paramTemplate) {
mcimadamore@1415 155 this.paramTemplate = paramTemplate;
mcimadamore@1415 156 }
mcimadamore@1415 157 }
mcimadamore@1415 158
mcimadamore@1415 159 enum Keyword {
mcimadamore@1415 160 SUPER("super"),
mcimadamore@1415 161 EXTENDS("extends"),
mcimadamore@1415 162 VOID("");
mcimadamore@1415 163
mcimadamore@1415 164 String keyStr;
mcimadamore@1415 165
mcimadamore@1415 166 Keyword(String keyStr) {
mcimadamore@1415 167 this.keyStr = keyStr;
mcimadamore@1415 168 }
mcimadamore@1415 169 }
mcimadamore@1415 170
mcimadamore@1415 171 enum LambdaBody {
vromero@1482 172 //no parameters, return type is one of the TypeKind
vromero@1482 173 RETURN_VOID("() -> #RET"),
vromero@1482 174 //has parameters, return type is one of the TypeKind
vromero@1482 175 RETURN_ARG("(#PK arg) -> #RET");
mcimadamore@1415 176
mcimadamore@1415 177 String bodyStr;
mcimadamore@1415 178
mcimadamore@1415 179 LambdaBody(String bodyStr) {
mcimadamore@1415 180 this.bodyStr = bodyStr;
mcimadamore@1415 181 }
mcimadamore@1415 182
vromero@1482 183 String getLambdaBody(TypeKind samTargetT, TypeKind parameterT,
vromero@1482 184 TypeKind returnT, LambdaKind lk, ParameterKind pk) {
mcimadamore@1415 185 String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
mcimadamore@1415 186
mcimadamore@1415 187 if(result.contains("#TYPE")) {
mcimadamore@1415 188 if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
vromero@1482 189 result = result.replaceAll("#TYPE",
vromero@1482 190 samTargetT == null? "": samTargetT.typeStr);
mcimadamore@1415 191 else
mcimadamore@1415 192 result = result.replaceAll("#TYPE", parameterT.typeStr);
mcimadamore@1415 193 }
mcimadamore@1415 194 if (this == RETURN_ARG && parameterT == returnT)
mcimadamore@1415 195 return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
mcimadamore@1415 196 else {
mcimadamore@1415 197 if(returnT != TypeKind.GENERIC)
vromero@1482 198 return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL",
vromero@1482 199 (returnT==TypeKind.VOID &&
vromero@1482 200 lk==LambdaKind.EXPRESSION) ? "{}" : returnT.valStr));
mcimadamore@1415 201 else
vromero@1482 202 return result.replaceAll("#RET",
vromero@1482 203 lk.stmt.replaceAll("#VAL", samTargetT.valStr));
mcimadamore@1415 204 }
mcimadamore@1415 205 }
mcimadamore@1415 206 }
mcimadamore@1415 207
mcimadamore@1415 208 enum GenericDeclKind {
mcimadamore@1415 209 NON_GENERIC(""),
mcimadamore@1415 210 GENERIC_NOBOUND("<T>"),
mcimadamore@1415 211 GENERIC_BOUND("<T extends #ExtendedType>");
mcimadamore@1415 212 String typeStr;
mcimadamore@1415 213
mcimadamore@1415 214 GenericDeclKind(String typeStr) {
mcimadamore@1415 215 this.typeStr = typeStr;
mcimadamore@1415 216 }
mcimadamore@1415 217
mcimadamore@1415 218 String getGenericDeclKind(TypeKind et) {
mcimadamore@1415 219 return typeStr.replaceAll("#ExtendedType", et==null? "":et.typeStr);
mcimadamore@1415 220 }
mcimadamore@1415 221 }
mcimadamore@1415 222
mcimadamore@1415 223 boolean checkTypeInference() {
mcimadamore@1415 224 if (parameterType == TypeKind.VOID) {
mcimadamore@1415 225 if (lambdaBodyType != LambdaBody.RETURN_VOID)
mcimadamore@1415 226 return false;
mcimadamore@1415 227 }
mcimadamore@1415 228 else if (lambdaBodyType != LambdaBody.RETURN_ARG)
mcimadamore@1415 229 return false;
vromero@2000 230
mcimadamore@1415 231 return true;
mcimadamore@1415 232 }
mcimadamore@1415 233
mcimadamore@1415 234 String templateStr = "#C\n" +
mcimadamore@1415 235 "interface SAM2 {\n" +
mcimadamore@1415 236 " SAM m();\n" +
mcimadamore@1415 237 "}\n";
mcimadamore@1415 238 SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
mcimadamore@1415 239 public String toString() {
vromero@1482 240 return template.replaceAll("#C",
vromero@1482 241 samKind.getSam(parameterType, returnType));
mcimadamore@1415 242 }
mcimadamore@1415 243 };
mcimadamore@1415 244
mcimadamore@1415 245 SourceFile clientSourceFile = new SourceFile("Client.java",
mcimadamore@1415 246 "class Client { \n" +
mcimadamore@1415 247 " #Context\n" +
mcimadamore@1415 248 "}") {
mcimadamore@1415 249 public String toString() {
vromero@1482 250 return template.replaceAll("#Context",
vromero@1482 251 context.getContext(samKind, samTargetType, keyword,
vromero@1482 252 parameterType, returnType, lambdaKind, parameterKind,
vromero@1482 253 genericDeclKind, lambdaBodyType));
mcimadamore@1415 254 }
mcimadamore@1415 255 };
mcimadamore@1415 256
vromero@1482 257 public void run() {
mcimadamore@1415 258 DiagnosticChecker dc = new DiagnosticChecker();
vromero@1482 259 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), dc,
vromero@1482 260 null, null, Arrays.asList(samSourceFile, clientSourceFile));
vromero@1482 261 try {
vromero@1482 262 ct.analyze();
vromero@1482 263 } catch (Throwable t) {
vromero@1482 264 processException(t);
vromero@1482 265 }
mcimadamore@1415 266 if (dc.errorFound == checkTypeInference()) {
vromero@1482 267 throw new AssertionError(samSourceFile + "\n\n" +
vromero@1482 268 clientSourceFile + "\n" + parameterType + " " + returnType);
mcimadamore@1415 269 }
mcimadamore@1415 270 }
mcimadamore@1415 271
mcimadamore@1415 272 abstract class SourceFile extends SimpleJavaFileObject {
mcimadamore@1415 273
mcimadamore@1415 274 protected String template;
mcimadamore@1415 275
mcimadamore@1415 276 public SourceFile(String filename, String template) {
mcimadamore@1415 277 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
mcimadamore@1415 278 this.template = template;
mcimadamore@1415 279 }
mcimadamore@1415 280
mcimadamore@1415 281 @Override
mcimadamore@1415 282 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1415 283 return toString();
mcimadamore@1415 284 }
mcimadamore@1415 285
mcimadamore@1415 286 public abstract String toString();
mcimadamore@1415 287 }
mcimadamore@1415 288
vromero@1482 289 static class DiagnosticChecker
vromero@1482 290 implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1415 291
mcimadamore@1415 292 boolean errorFound = false;
mcimadamore@1415 293
mcimadamore@1415 294 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1415 295 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1415 296 errorFound = true;
mcimadamore@1415 297 }
mcimadamore@1415 298 }
mcimadamore@1415 299 }
mcimadamore@1415 300
mcimadamore@1415 301 SamKind samKind;
mcimadamore@1415 302 TypeKind samTargetType;
mcimadamore@1415 303 TypeKind parameterType;
mcimadamore@1415 304 TypeKind returnType;
mcimadamore@1415 305 Context context;
mcimadamore@1415 306 LambdaBody lambdaBodyType;
mcimadamore@1415 307 LambdaKind lambdaKind;
mcimadamore@1415 308 ParameterKind parameterKind;
mcimadamore@1415 309 Keyword keyword;
mcimadamore@1415 310 GenericDeclKind genericDeclKind;
mcimadamore@1415 311
vromero@1482 312 TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT,
vromero@1482 313 TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk,
vromero@1482 314 ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
mcimadamore@1415 315 samKind = sk;
mcimadamore@1415 316 samTargetType = samTargetT;
mcimadamore@1415 317 parameterType = parameterT;
mcimadamore@1415 318 returnType = returnT;
mcimadamore@1415 319 context = c;
mcimadamore@1415 320 lambdaKind = lk;
mcimadamore@1415 321 parameterKind = pk;
mcimadamore@1415 322 keyword = kw;
mcimadamore@1415 323 lambdaBodyType = lb;
mcimadamore@1415 324 genericDeclKind = gdk;
mcimadamore@1415 325 }
mcimadamore@1415 326
mcimadamore@1415 327 public static void main(String[] args) throws Exception {
mcimadamore@1415 328 for(Context ct : Context.values()) {
mcimadamore@1415 329 for (TypeKind returnT : TypeKind.values()) {
mcimadamore@1415 330 for (TypeKind parameterT : TypeKind.values()) {
mcimadamore@1415 331 for(LambdaBody lb : LambdaBody.values()) {
mcimadamore@1415 332 for (ParameterKind parameterK : ParameterKind.values()) {
mcimadamore@1415 333 for(LambdaKind lambdaK : LambdaKind.values()) {
mcimadamore@1415 334 for (SamKind sk : SamKind.values()) {
mcimadamore@1415 335 if (sk == SamKind.NON_GENERIC) {
vromero@1482 336 generateNonGenericSAM(ct, returnT,
vromero@1482 337 parameterT, lb, parameterK,
vromero@1482 338 lambdaK, sk);
mcimadamore@1415 339 }
mcimadamore@1415 340 else if (sk == SamKind.GENERIC) {
vromero@1482 341 generateGenericSAM(ct, returnT,
vromero@1482 342 parameterT, lb, parameterK,
vromero@1482 343 lambdaK, sk);
mcimadamore@1415 344 }
mcimadamore@1415 345 }
mcimadamore@1415 346 }
mcimadamore@1415 347 }
mcimadamore@1415 348 }
mcimadamore@1415 349 }
mcimadamore@1415 350 }
mcimadamore@1415 351 }
vromero@1482 352
vromero@1482 353 checkAfterExec(false);
mcimadamore@1415 354 }
vromero@1482 355
vromero@1482 356 static void generateNonGenericSAM(Context ct, TypeKind returnT,
vromero@1482 357 TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
vromero@1482 358 LambdaKind lambdaK, SamKind sk) {
vromero@1482 359 if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC ) {
vromero@1482 360 pool.execute(new TypeInferenceComboTest(sk, null, parameterT,
vromero@1482 361 returnT, lb, ct, lambdaK, parameterK, null, null));
vromero@1482 362 }
vromero@1482 363 }
vromero@1482 364
vromero@1482 365 static void generateGenericSAM(Context ct, TypeKind returnT,
vromero@1482 366 TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
vromero@1482 367 LambdaKind lambdaK, SamKind sk) {
vromero@1482 368 for (Keyword kw : Keyword.values()) {
vromero@1482 369 for (TypeKind samTargetT : TypeKind.values()) {
vromero@1482 370 if(samTargetT != TypeKind.VOID &&
vromero@1482 371 samTargetT != TypeKind.INT &&
vromero@1482 372 samTargetT != TypeKind.GENERIC &&
vromero@1482 373 (parameterT == TypeKind.GENERIC ||
vromero@1482 374 returnT == TypeKind.GENERIC)) {
vromero@1482 375 if(ct != Context.METHOD_CALL) {
vromero@1482 376 pool.execute(
vromero@1482 377 new TypeInferenceComboTest(sk, samTargetT, parameterT,
vromero@1482 378 returnT, lb, ct, lambdaK, parameterK, kw, null));
vromero@1482 379 } else {//Context.METHOD_CALL
vromero@1482 380 for (GenericDeclKind gdk :
vromero@1482 381 GenericDeclKind.values())
vromero@1482 382 pool.execute(
vromero@1482 383 new TypeInferenceComboTest(sk, samTargetT,
vromero@1482 384 parameterT, returnT, lb, ct, lambdaK,
vromero@1482 385 parameterK, kw, gdk));
vromero@1482 386 }
vromero@1482 387 }
vromero@1482 388 }
vromero@1482 389 }
vromero@1482 390 }
vromero@1482 391
mcimadamore@1415 392 }

mercurial