test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java

Tue, 08 Jan 2013 13:47:57 +0000

author
vromero
date
Tue, 08 Jan 2013 13:47:57 +0000
changeset 1482
954541f13717
parent 1415
01c9d4161882
child 1520
5c956be64b9e
permissions
-rw-r--r--

8005167: execution time of combo tests in javac should be improved
Reviewed-by: jjg, jjh

     1 /*
     2  * Copyright (c) 2012, 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
    27  * @summary Add lambda tests
    28  *  Automatic test for checking correctness of structural most specific test routine
    29  * @library ../../lib
    30  * @build JavacTestingAbstractThreadedTest
    31  * @run main/timeout=600 StructuralMostSpecificTest
    32  */
    34 import java.net.URI;
    35 import java.util.Arrays;
    36 import javax.tools.Diagnostic;
    37 import javax.tools.JavaFileObject;
    38 import javax.tools.SimpleJavaFileObject;
    39 import com.sun.source.util.JavacTask;
    40 import com.sun.tools.javac.api.ClientCodeWrapper;
    41 import com.sun.tools.javac.util.JCDiagnostic;
    43 public class StructuralMostSpecificTest
    44     extends JavacTestingAbstractThreadedTest
    45     implements Runnable {
    47     enum RetTypeKind {
    48         SHORT("short"),
    49         INT("int"),
    50         OBJECT("Object"),
    51         INTEGER("Integer"),
    52         VOID("void"),
    53         J_L_VOID("Void");
    55         String retTypeStr;
    57         RetTypeKind(String retTypeStr) {
    58             this.retTypeStr = retTypeStr;
    59         }
    61         boolean moreSpecificThan(RetTypeKind rk) {
    62             return moreSpecificThan[this.ordinal()][rk.ordinal()];
    63         }
    65         static boolean[][] moreSpecificThan = {
    66                 //              SHORT |  INT  | OBJECT | INTEGER | VOID  | J_L_VOID
    67                 /* SHORT */   { true  , true  , true   , false   , false , false },
    68                 /* INT */     { false , true  , true   , true    , false , false },
    69                 /* OBJECT */  { false , false , true   , false   , false , false },
    70                 /* INTEGER */ { false , false , true   , true    , false , false },
    71                 /* VOID */    { false , false , false  , false   , true  , true  },
    72                 /* J_L_VOID */{ false , false , true   , false   , false , true  } };
    73     }
    75     enum ArgTypeKind {
    76         SHORT("short"),
    77         INT("int"),
    78         BOOLEAN("boolean"),
    79         OBJECT("Object"),
    80         INTEGER("Integer"),
    81         DOUBLE("Double");
    83         String argTypeStr;
    85         ArgTypeKind(String typeStr) {
    86             this.argTypeStr = typeStr;
    87         }
    88     }
    90     enum ExceptionKind {
    91         NONE(""),
    92         EXCEPTION("throws Exception"),
    93         SQL_EXCEPTION("throws java.sql.SQLException"),
    94         IO_EXCEPTION("throws java.io.IOException");
    96         String exceptionStr;
    98         ExceptionKind(String exceptionStr) {
    99             this.exceptionStr = exceptionStr;
   100         }
   101     }
   103     enum LambdaReturnKind {
   104         VOID("return;"),
   105         SHORT("return (short)0;"),
   106         INT("return 0;"),
   107         INTEGER("return (Integer)null;"),
   108         NULL("return null;");
   110         String retStr;
   112         LambdaReturnKind(String retStr) {
   113             this.retStr = retStr;
   114         }
   116         boolean compatibleWith(RetTypeKind rk) {
   117             return compatibleWith[rk.ordinal()][ordinal()];
   118         }
   120         static boolean[][] compatibleWith = {
   121                 //              VOID  | SHORT | INT     | INTEGER | NULL
   122                 /* SHORT */   { false , true  , false   , false   , false },
   123                 /* INT */     { false , true  , true    , true    , false },
   124                 /* OBJECT */  { false , true  , true    , true    , true  },
   125                 /* INTEGER */ { false , false , true    , true    , true  },
   126                 /* VOID */    { true  , false , false   , false   , false },
   127                 /* J_L_VOID */{ false , false , false   , false   , true  } };
   129         boolean needsConversion(RetTypeKind rk) {
   130             return needsConversion[rk.ordinal()][ordinal()];
   131         }
   133         static boolean[][] needsConversion = {
   134                 //              VOID  | SHORT | INT     | INTEGER | NULL
   135                 /* SHORT */   { false , false , false   , false   , false },
   136                 /* INT */     { false , false , false   , true    , false },
   137                 /* OBJECT */  { false , true  , true    , false   , false },
   138                 /* INTEGER */ { false , false , true    , false   , false },
   139                 /* VOID */    { false , false , false   , false   , false },
   140                 /* J_L_VOID */{ true  , false , false   , false   , false } };
   141     }
   143     public static void main(String... args) throws Exception {
   144         for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
   145             for (RetTypeKind rk1 : RetTypeKind.values()) {
   146                 for (RetTypeKind rk2 : RetTypeKind.values()) {
   147                     for (ExceptionKind ek1 : ExceptionKind.values()) {
   148                         for (ExceptionKind ek2 : ExceptionKind.values()) {
   149                             for (ArgTypeKind ak11 : ArgTypeKind.values()) {
   150                                 for (ArgTypeKind ak12 : ArgTypeKind.values()) {
   151                                     pool.execute(
   152                                         new StructuralMostSpecificTest(lrk, rk1,
   153                                             rk2, ek1, ek2, ak11, ak12));
   154                                 }
   155                             }
   156                         }
   157                     }
   158                 }
   159             }
   160         }
   162         checkAfterExec();
   163     }
   165     LambdaReturnKind lrk;
   166     RetTypeKind rt1, rt2;
   167     ArgTypeKind ak1, ak2;
   168     ExceptionKind ek1, ek2;
   169     JavaSource source;
   170     DiagnosticChecker diagChecker;
   172     StructuralMostSpecificTest(LambdaReturnKind lrk, RetTypeKind rt1, RetTypeKind rt2,
   173             ExceptionKind ek1, ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
   174         this.lrk = lrk;
   175         this.rt1 = rt1;
   176         this.rt2 = rt2;
   177         this.ek1 = ek1;
   178         this.ek2 = ek2;
   179         this.ak1 = ak1;
   180         this.ak2 = ak2;
   181         this.source = new JavaSource();
   182         this.diagChecker = new DiagnosticChecker();
   183     }
   185     class JavaSource extends SimpleJavaFileObject {
   187         String template = "interface SAM1 {\n" +
   188                           "   #R1 m(#A1 a1) #E1;\n" +
   189                           "}\n" +
   190                           "interface SAM2 {\n" +
   191                           "   #R2 m(#A2 a1) #E2;\n" +
   192                           "}\n" +
   193                           "class Test {\n" +
   194                           "   void m(SAM1 s) { }\n" +
   195                           "   void m(SAM2 s) { }\n" +
   196                           "   { m(x->{ #LR }); }\n" +
   197                           "}\n";
   199         String source;
   201         public JavaSource() {
   202             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   203             source = template.replaceAll("#LR", lrk.retStr)
   204                     .replaceAll("#R1", rt1.retTypeStr)
   205                     .replaceAll("#R2", rt2.retTypeStr)
   206                     .replaceAll("#A1", ak1.argTypeStr)
   207                     .replaceAll("#A2", ak2.argTypeStr)
   208                     .replaceAll("#E1", ek1.exceptionStr)
   209                     .replaceAll("#E2", ek2.exceptionStr);
   210         }
   212         @Override
   213         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   214             return source;
   215         }
   216     }
   218     public void run() {
   219         JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
   220                 Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
   221                 null, Arrays.asList(source));
   222         try {
   223             ct.analyze();
   224         } catch (Throwable ex) {
   225             throw new
   226                 AssertionError("Error thron when analyzing the following source:\n" +
   227                     source.getCharContent(true));
   228         }
   229         check();
   230     }
   232     void check() {
   233         checkCount.incrementAndGet();
   235         if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
   236             return;
   238         if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2))
   239             return;
   241         boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2);
   242         boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1);
   244         boolean ambiguous = (m1MoreSpecific == m2MoreSpecific);
   246         if (ambiguous != diagChecker.ambiguityFound) {
   247             throw new Error("invalid diagnostics for source:\n" +
   248                 source.getCharContent(true) +
   249                 "\nAmbiguity found: " + diagChecker.ambiguityFound +
   250                 "\nm1 more specific: " + m1MoreSpecific +
   251                 "\nm2 more specific: " + m2MoreSpecific +
   252                 "\nexpected ambiguity: " + ambiguous);
   253         }
   255         if (!ambiguous) {
   256             String sigToCheck = m1MoreSpecific ? "m(SAM1)" : "m(SAM2)";
   257             if (!sigToCheck.equals(diagChecker.mostSpecificSig)) {
   258                 throw new Error("invalid most specific method selected:\n" +
   259                 source.getCharContent(true) +
   260                 "\nMost specific found: " + diagChecker.mostSpecificSig +
   261                 "\nm1 more specific: " + m1MoreSpecific +
   262                 "\nm2 more specific: " + m2MoreSpecific);
   263             }
   264         }
   265     }
   267     boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1,
   268             ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
   269         if (!rk1.moreSpecificThan(rk2))
   270             return false;
   272         if (ak1 != ak2)
   273             return false;
   275         return true;
   276     }
   278     static class DiagnosticChecker
   279         implements javax.tools.DiagnosticListener<JavaFileObject> {
   281         boolean ambiguityFound;
   282         String mostSpecificSig;
   284         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   285             try {
   286                 if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
   287                         diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
   288                     ambiguityFound = true;
   289                 } else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
   290                         diagnostic.getCode()
   291                         .equals("compiler.note.verbose.resolve.multi")) {
   292                     ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
   293                         (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
   294                     JCDiagnostic.MultilineDiagnostic mdiag =
   295                         (JCDiagnostic.MultilineDiagnostic)dsu.d;
   296                     int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
   297                     mostSpecificSig =
   298                         ((JCDiagnostic)mdiag.getSubdiagnostics()
   299                             .get(mostSpecificIndex)).getArgs()[1].toString();
   300                 }
   301             } catch (RuntimeException t) {
   302                 t.printStackTrace();
   303                 throw t;
   304             }
   305         }
   306     }
   308 }

mercurial