test/tools/javac/lambda/FunctionalInterfaceConversionTest.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 2354
b33835c5d96a
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 8004102 8006694
    27  * @summary Add lambda tests
    28  *  perform several automated checks in lambda conversion, esp. around accessibility
    29  *  temporarily workaround combo tests are causing time out in several platforms
    30  * @author  Maurizio Cimadamore
    31  * @library ../lib
    32  * @build JavacTestingAbstractThreadedTest
    33  * @run main/othervm FunctionalInterfaceConversionTest
    34  */
    36 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
    37 // see JDK-8006746
    39 import java.io.IOException;
    40 import java.net.URI;
    41 import java.util.Arrays;
    42 import javax.tools.Diagnostic;
    43 import javax.tools.JavaCompiler;
    44 import javax.tools.JavaFileObject;
    45 import javax.tools.SimpleJavaFileObject;
    46 import javax.tools.ToolProvider;
    47 import com.sun.source.util.JavacTask;
    49 public class FunctionalInterfaceConversionTest
    50     extends JavacTestingAbstractThreadedTest
    51     implements Runnable {
    53     enum PackageKind {
    54         NO_PKG(""),
    55         PKG_A("a");
    57         String pkg;
    59         PackageKind(String pkg) {
    60             this.pkg = pkg;
    61         }
    63         String getPkgDecl() {
    64             return this == NO_PKG ?
    65                 "" :
    66                 "package " + pkg + ";";
    67         }
    69         String getImportStat() {
    70             return this == NO_PKG ?
    71                 "" :
    72                 "import " + pkg + ".*;";
    73         }
    74     }
    76     enum SamKind {
    77         CLASS("public class Sam {  }"),
    78         ABSTACT_CLASS("public abstract class Sam {  }"),
    79         ANNOTATION("public @interface Sam {  }"),
    80         ENUM("public enum Sam { }"),
    81         INTERFACE("public interface Sam { \n #METH; \n }");
    83         String sam_str;
    85         SamKind(String sam_str) {
    86             this.sam_str = sam_str;
    87         }
    89         String getSam(String methStr) {
    90             return sam_str.replaceAll("#METH", methStr);
    91         }
    92     }
    94     enum ModifierKind {
    95         PUBLIC("public"),
    96         PACKAGE("");
    98         String modifier_str;
   100         ModifierKind(String modifier_str) {
   101             this.modifier_str = modifier_str;
   102         }
   104         boolean stricterThan(ModifierKind that) {
   105             return this.ordinal() > that.ordinal();
   106         }
   107     }
   109     enum TypeKind {
   110         EXCEPTION("Exception"),
   111         PKG_CLASS("PackageClass");
   113         String typeStr;
   115         private TypeKind(String typeStr) {
   116             this.typeStr = typeStr;
   117         }
   118     }
   120     enum ExprKind {
   121         LAMBDA("x -> null"),
   122         MREF("this::m");
   124         String exprStr;
   126         private ExprKind(String exprStr) {
   127             this.exprStr = exprStr;
   128         }
   129     }
   131     enum MethodKind {
   132         NONE(""),
   133         NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
   134         GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
   136         String methodTemplate;
   138         private MethodKind(String methodTemplate) {
   139             this.methodTemplate = methodTemplate;
   140         }
   142         String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
   143             return methodTemplate.replaceAll("#R", retType.typeStr).
   144                     replaceAll("#ARG", argType.typeStr).
   145                     replaceAll("#T", thrownType.typeStr);
   146         }
   147     }
   149     public static void main(String[] args) throws Exception {
   150         for (PackageKind samPkg : PackageKind.values()) {
   151             for (ModifierKind modKind : ModifierKind.values()) {
   152                 for (SamKind samKind : SamKind.values()) {
   153                     for (MethodKind samMeth : MethodKind.values()) {
   154                         for (MethodKind clientMeth : MethodKind.values()) {
   155                             for (TypeKind retType : TypeKind.values()) {
   156                                 for (TypeKind argType : TypeKind.values()) {
   157                                     for (TypeKind thrownType : TypeKind.values()) {
   158                                         for (ExprKind exprKind : ExprKind.values()) {
   159                                             pool.execute(
   160                                                 new FunctionalInterfaceConversionTest(
   161                                                     samPkg, modKind, samKind,
   162                                                     samMeth, clientMeth, retType,
   163                                                     argType, thrownType, exprKind));
   164                                         }
   165                                     }
   166                                 }
   167                             }
   168                         }
   169                     }
   170                 }
   171             }
   172         }
   174         checkAfterExec(false);
   175     }
   177     PackageKind samPkg;
   178     ModifierKind modKind;
   179     SamKind samKind;
   180     MethodKind samMeth;
   181     MethodKind clientMeth;
   182     TypeKind retType;
   183     TypeKind argType;
   184     TypeKind thrownType;
   185     ExprKind exprKind;
   186     DiagnosticChecker dc;
   188     SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
   189         @Override
   190         public String toString() {
   191             return template.replaceAll("#P", samPkg.getPkgDecl()).
   192                     replaceAll("#C", samKind.getSam(
   193                     samMeth.getMethod(retType, argType, thrownType)));
   194         }
   195     };
   197     SourceFile pkgClassSourceFile =
   198             new SourceFile("PackageClass.java",
   199                            "#P\n #M class PackageClass extends Exception { }") {
   200         @Override
   201         public String toString() {
   202             return template.replaceAll("#P", samPkg.getPkgDecl()).
   203                     replaceAll("#M", modKind.modifier_str);
   204         }
   205     };
   207     SourceFile clientSourceFile =
   208             new SourceFile("Client.java",
   209                            "#I\n abstract class Client { \n" +
   210                            "  Sam s = #E;\n" +
   211                            "  #M \n }") {
   212         @Override
   213         public String toString() {
   214             return template.replaceAll("#I", samPkg.getImportStat())
   215                     .replaceAll("#E", exprKind.exprStr)
   216                     .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
   217         }
   218     };
   220     FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind,
   221             SamKind samKind, MethodKind samMeth, MethodKind clientMeth,
   222             TypeKind retType, TypeKind argType, TypeKind thrownType,
   223             ExprKind exprKind) {
   224         this.samPkg = samPkg;
   225         this.modKind = modKind;
   226         this.samKind = samKind;
   227         this.samMeth = samMeth;
   228         this.clientMeth = clientMeth;
   229         this.retType = retType;
   230         this.argType = argType;
   231         this.thrownType = thrownType;
   232         this.exprKind = exprKind;
   233         this.dc = new DiagnosticChecker();
   234     }
   236     @Override
   237     public void run() {
   238         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   240         JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc, null, null,
   241                 Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
   242         try {
   243             ct.analyze();
   244         } catch (IOException ex) {
   245             throw new AssertionError("Test failing with cause", ex.getCause());
   246         }
   247         if (dc.errorFound == checkSamConversion()) {
   248             throw new AssertionError(samSourceFile + "\n\n" +
   249                 pkgClassSourceFile + "\n\n" + clientSourceFile);
   250         }
   251     }
   253     boolean checkSamConversion() {
   254         if (samKind != SamKind.INTERFACE) {
   255             //sam type must be an interface
   256             return false;
   257         } else if (samMeth == MethodKind.NONE) {
   258             //interface must have at least a method
   259             return false;
   260         } else if (exprKind == ExprKind.LAMBDA &&
   261                 samMeth != MethodKind.NON_GENERIC) {
   262             //target method for lambda must be non-generic
   263             return false;
   264         } else if (exprKind == ExprKind.MREF &&
   265                 clientMeth == MethodKind.NONE) {
   266             return false;
   267         } else if (samPkg != PackageKind.NO_PKG &&
   268                 modKind != ModifierKind.PUBLIC &&
   269                 (retType == TypeKind.PKG_CLASS ||
   270                 argType == TypeKind.PKG_CLASS ||
   271                 thrownType == TypeKind.PKG_CLASS)) {
   272             //target must not contain inaccessible types
   273             return false;
   274         } else {
   275             return true;
   276         }
   277     }
   279     abstract class SourceFile extends SimpleJavaFileObject {
   281         protected String template;
   283         public SourceFile(String filename, String template) {
   284             super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
   285             this.template = template;
   286         }
   288         @Override
   289         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   290             return toString();
   291         }
   293         @Override
   294         public abstract String toString();
   295     }
   297     static class DiagnosticChecker
   298         implements javax.tools.DiagnosticListener<JavaFileObject> {
   300         boolean errorFound = false;
   302         @Override
   303         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   304             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   305                 errorFound = true;
   306             }
   307         }
   308     }
   309 }

mercurial