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

Wed, 23 Jan 2013 20:57:40 +0000

author
vromero
date
Wed, 23 Jan 2013 20:57:40 +0000
changeset 1520
5c956be64b9e
parent 1482
954541f13717
child 2000
4a6acc42c3a1
permissions
-rw-r--r--

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 }

mercurial