test/tools/javac/lambda/FunctionalInterfaceConversionTest.java

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

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

mercurial