test/tools/javac/lambda/LambdaParserTest.java

Tue, 12 Mar 2013 16:02:43 +0000

author
mcimadamore
date
Tue, 12 Mar 2013 16:02:43 +0000
changeset 1628
5ddecb91d843
parent 1520
5c956be64b9e
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8009545: Graph inference: dependencies between inference variables should be set during incorporation
Summary: Move all transitivity checks into the incorporation round
Reviewed-by: jjg

     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 7115050 8003280 8005852 8006694
    27  * @summary Add lambda tests
    28  *  Add parser support for lambda expressions
    29  *  temporarily workaround combo tests are causing time out in several platforms
    30  * @library ../lib
    31  * @build JavacTestingAbstractThreadedTest
    32  * @run main/othervm LambdaParserTest
    33  */
    35 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
    36 // see JDK-8006746
    38 import java.net.URI;
    39 import java.util.Arrays;
    40 import javax.tools.Diagnostic;
    41 import javax.tools.JavaFileObject;
    42 import javax.tools.SimpleJavaFileObject;
    43 import com.sun.source.util.JavacTask;
    45 public class LambdaParserTest
    46     extends JavacTestingAbstractThreadedTest
    47     implements Runnable {
    49     enum LambdaKind {
    50         NILARY_EXPR("()->x"),
    51         NILARY_STMT("()->{ return x; }"),
    52         ONEARY_SHORT_EXPR("#PN->x"),
    53         ONEARY_SHORT_STMT("#PN->{ return x; }"),
    54         ONEARY_EXPR("(#M1 #T1 #PN)->x"),
    55         ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"),
    56         TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"),
    57         TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }");
    59         String lambdaTemplate;
    61         LambdaKind(String lambdaTemplate) {
    62             this.lambdaTemplate = lambdaTemplate;
    63         }
    65         String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2,
    66                 ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) {
    67             return lambdaTemplate.replaceAll("#M1", mk1.modifier)
    68                     .replaceAll("#M2", mk2.modifier)
    69                     .replaceAll("#T1", pk1.parameterType)
    70                     .replaceAll("#T2", pk2.parameterType)
    71                     .replaceAll("#PN", pn.nameStr);
    72         }
    74         int arity() {
    75             switch (this) {
    76                 case NILARY_EXPR:
    77                 case NILARY_STMT: return 0;
    78                 case ONEARY_SHORT_EXPR:
    79                 case ONEARY_SHORT_STMT:
    80                 case ONEARY_EXPR:
    81                 case ONEARY_STMT: return 1;
    82                 case TWOARY_EXPR:
    83                 case TWOARY_STMT: return 2;
    84                 default: throw new AssertionError("Invalid lambda kind " + this);
    85             }
    86         }
    88         boolean isShort() {
    89             return this == ONEARY_SHORT_EXPR ||
    90                     this == ONEARY_SHORT_STMT;
    91         }
    92     }
    94     enum LambdaParameterName {
    95         IDENT("x"),
    96         UNDERSCORE("_");
    98         String nameStr;
   100         LambdaParameterName(String nameStr) {
   101             this.nameStr = nameStr;
   102         }
   103     }
   105     enum LambdaParameterKind {
   106         IMPLICIT(""),
   107         EXPLIICT_SIMPLE("A"),
   108         EXPLIICT_SIMPLE_ARR1("A[]"),
   109         EXPLIICT_SIMPLE_ARR2("A[][]"),
   110         EXPLICIT_VARARGS("A..."),
   111         EXPLICIT_GENERIC1("A<X>"),
   112         EXPLICIT_GENERIC2("A<? extends X, ? super Y>"),
   113         EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>..."),
   114         EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]"),
   115         EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]");
   117         String parameterType;
   119         LambdaParameterKind(String parameterType) {
   120             this.parameterType = parameterType;
   121         }
   123         boolean explicit() {
   124             return this != IMPLICIT;
   125         }
   127         boolean isVarargs() {
   128             return this == EXPLICIT_VARARGS ||
   129                     this == EXPLICIT_GENERIC2_VARARGS;
   130         }
   131     }
   133     enum ModifierKind {
   134         NONE(""),
   135         FINAL("final"),
   136         PUBLIC("public");
   138         String modifier;
   140         ModifierKind(String modifier) {
   141             this.modifier = modifier;
   142         }
   144         boolean compatibleWith(LambdaParameterKind pk) {
   145             switch (this) {
   146                 case PUBLIC: return false;
   147                 case FINAL: return pk != LambdaParameterKind.IMPLICIT;
   148                 case NONE: return true;
   149                 default: throw new AssertionError("Invalid modifier kind " + this);
   150             }
   151         }
   152     }
   154     enum ExprKind {
   155         NONE("#L#S"),
   156         SINGLE_PAREN1("(#L#S)"),
   157         SINGLE_PAREN2("(#L)#S"),
   158         DOUBLE_PAREN1("((#L#S))"),
   159         DOUBLE_PAREN2("((#L)#S)"),
   160         DOUBLE_PAREN3("((#L))#S");
   162         String expressionTemplate;
   164         ExprKind(String expressionTemplate) {
   165             this.expressionTemplate = expressionTemplate;
   166         }
   168         String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2,
   169                 ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) {
   170             return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn))
   171                     .replaceAll("#S", sk.subExpression);
   172         }
   173     }
   175     enum SubExprKind {
   176         NONE(""),
   177         SELECT_FIELD(".f"),
   178         SELECT_METHOD(".f()"),
   179         SELECT_NEW(".new Foo()"),
   180         POSTINC("++"),
   181         POSTDEC("--");
   183         String subExpression;
   185         SubExprKind(String subExpression) {
   186             this.subExpression = subExpression;
   187         }
   188     }
   190     public static void main(String... args) throws Exception {
   191         for (LambdaKind lk : LambdaKind.values()) {
   192             for (LambdaParameterName pn : LambdaParameterName.values()) {
   193                 for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
   194                     if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
   195                         continue;
   196                     for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
   197                         if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
   198                             continue;
   199                         for (ModifierKind mk1 : ModifierKind.values()) {
   200                             if (mk1 != ModifierKind.NONE && lk.isShort())
   201                                 continue;
   202                             if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
   203                                 continue;
   204                             for (ModifierKind mk2 : ModifierKind.values()) {
   205                                 if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
   206                                     continue;
   207                                 for (SubExprKind sk : SubExprKind.values()) {
   208                                     for (ExprKind ek : ExprKind.values()) {
   209                                         pool.execute(
   210                                             new LambdaParserTest(pk1, pk2, mk1,
   211                                                                  mk2, lk, sk, ek, pn));
   212                                     }
   213                                 }
   214                             }
   215                         }
   216                     }
   217                 }
   218             }
   219         }
   221         checkAfterExec();
   222     }
   224     LambdaParameterKind pk1;
   225     LambdaParameterKind pk2;
   226     ModifierKind mk1;
   227     ModifierKind mk2;
   228     LambdaKind lk;
   229     LambdaParameterName pn;
   230     SubExprKind sk;
   231     ExprKind ek;
   232     JavaSource source;
   233     DiagnosticChecker diagChecker;
   235     LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
   236             ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
   237             SubExprKind sk, ExprKind ek, LambdaParameterName pn) {
   238         this.pk1 = pk1;
   239         this.pk2 = pk2;
   240         this.mk1 = mk1;
   241         this.mk2 = mk2;
   242         this.lk = lk;
   243         this.pn = pn;
   244         this.sk = sk;
   245         this.ek = ek;
   246         this.source = new JavaSource();
   247         this.diagChecker = new DiagnosticChecker();
   248     }
   250     class JavaSource extends SimpleJavaFileObject {
   252         String template = "class Test {\n" +
   253                           "   SAM s = #E;\n" +
   254                           "}";
   256         String source;
   258         public JavaSource() {
   259             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   260             source = template.replaceAll("#E",
   261                     ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk));
   262         }
   264         @Override
   265         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   266             return source;
   267         }
   268     }
   270     public void run() {
   271         JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
   272                 null, null, Arrays.asList(source));
   273         try {
   274             ct.parse();
   275         } catch (Throwable ex) {
   276             processException(ex);
   277             return;
   278         }
   279         check();
   280     }
   282     void check() {
   283         checkCount.incrementAndGet();
   285         boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) ||
   286                 (lk.arity() > 1 && !mk2.compatibleWith(pk2));
   288         if (lk.arity() == 2 &&
   289                 (pk1.explicit() != pk2.explicit() ||
   290                 pk1.isVarargs())) {
   291             errorExpected = true;
   292         }
   294         errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
   295                 lk.arity() > 0;
   297         if (errorExpected != diagChecker.errorFound) {
   298             throw new Error("invalid diagnostics for source:\n" +
   299                 source.getCharContent(true) +
   300                 "\nFound error: " + diagChecker.errorFound +
   301                 "\nExpected error: " + errorExpected);
   302         }
   303     }
   305     static class DiagnosticChecker
   306         implements javax.tools.DiagnosticListener<JavaFileObject> {
   308         boolean errorFound;
   310         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   311             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   312                 errorFound = true;
   313             }
   314         }
   315     }
   317 }

mercurial