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

mercurial