langtools/test/tools/javac/lambda/MethodReferenceParserTest.java
changeset 32454 b0ac04e0fefe
parent 30730 d3ce7619db2c
equal deleted inserted replaced
32453:8eebd1f0b8ea 32454:b0ac04e0fefe
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 7115052 8003280 8006694
    26  * @bug 7115052 8003280 8006694 8129962
    27  * @summary Add lambda tests
    27  * @summary Add lambda tests
    28  *  Add parser support for method references
    28  *  Add parser support for method references
    29  *  temporarily workaround combo tests are causing time out in several platforms
    29  *  temporarily workaround combo tests are causing time out in several platforms
    30  * @library ../lib
    30  * @library /tools/javac/lib
    31  * @modules jdk.compiler
    31  * @modules jdk.compiler/com.sun.tools.javac.api
    32  * @build JavacTestingAbstractThreadedTest
    32  *          jdk.compiler/com.sun.tools.javac.code
    33  * @run main/othervm MethodReferenceParserTest
    33  *          jdk.compiler/com.sun.tools.javac.comp
       
    34  *          jdk.compiler/com.sun.tools.javac.main
       
    35  *          jdk.compiler/com.sun.tools.javac.tree
       
    36  *          jdk.compiler/com.sun.tools.javac.util
       
    37  * @build combo.ComboTestHelper
       
    38  * @run main MethodReferenceParserTest
    34  */
    39  */
    35 
    40 
    36 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
    41 import java.io.IOException;
    37 // see JDK-8006746
    42 
    38 
    43 import combo.ComboInstance;
    39 import java.net.URI;
    44 import combo.ComboParameter;
    40 import java.util.Arrays;
    45 import combo.ComboTask.Result;
    41 import javax.tools.Diagnostic;
    46 import combo.ComboTestHelper;
    42 import javax.tools.JavaFileObject;
    47 
    43 import javax.tools.SimpleJavaFileObject;
    48 public class MethodReferenceParserTest extends ComboInstance<MethodReferenceParserTest> {
    44 import com.sun.source.util.JavacTask;
    49 
    45 
    50     enum ReferenceKind implements ComboParameter {
    46 public class MethodReferenceParserTest
    51         METHOD_REF("#{QUAL}::#{TARGS}m"),
    47     extends JavacTestingAbstractThreadedTest
    52         CONSTRUCTOR_REF("#{QUAL}::#{TARGS}new"),
    48     implements Runnable {
       
    49 
       
    50     enum ReferenceKind {
       
    51         METHOD_REF("#Q::#Gm"),
       
    52         CONSTRUCTOR_REF("#Q::#Gnew"),
       
    53         FALSE_REF("min < max"),
    53         FALSE_REF("min < max"),
    54         ERR_SUPER("#Q::#Gsuper"),
    54         ERR_SUPER("#{QUAL}::#{TARGS}super"),
    55         ERR_METH0("#Q::#Gm()"),
    55         ERR_METH0("#{QUAL}::#{TARGS}m()"),
    56         ERR_METH1("#Q::#Gm(X)"),
    56         ERR_METH1("#{QUAL}::#{TARGS}m(X)"),
    57         ERR_CONSTR0("#Q::#Gnew()"),
    57         ERR_CONSTR0("#{QUAL}::#{TARGS}new()"),
    58         ERR_CONSTR1("#Q::#Gnew(X)");
    58         ERR_CONSTR1("#{QUAL}::#{TARGS}new(X)");
    59 
    59 
    60         String referenceTemplate;
    60         String referenceTemplate;
    61 
    61 
    62         ReferenceKind(String referenceTemplate) {
    62         ReferenceKind(String referenceTemplate) {
    63             this.referenceTemplate = referenceTemplate;
    63             this.referenceTemplate = referenceTemplate;
    64         }
       
    65 
       
    66         String getReferenceString(QualifierKind qk, GenericKind gk) {
       
    67             return referenceTemplate
       
    68                     .replaceAll("#Q", qk.qualifier)
       
    69                     .replaceAll("#G", gk.typeParameters);
       
    70         }
    64         }
    71 
    65 
    72         boolean erroneous() {
    66         boolean erroneous() {
    73             switch (this) {
    67             switch (this) {
    74                 case ERR_SUPER:
    68                 case ERR_SUPER:
    78                 case ERR_CONSTR1:
    72                 case ERR_CONSTR1:
    79                     return true;
    73                     return true;
    80                 default: return false;
    74                 default: return false;
    81             }
    75             }
    82         }
    76         }
    83     }
    77 
    84 
    78         @Override
    85     enum ContextKind {
    79         public String expand(String optParameter) {
    86         ASSIGN("SAM s = #E;"),
    80             return referenceTemplate;
    87         METHOD("m(#E, i);");
    81         }
       
    82     }
       
    83 
       
    84     enum ContextKind implements ComboParameter {
       
    85         ASSIGN("SAM s = #{EXPR};"),
       
    86         METHOD("m(#{EXPR}, i);");
    88 
    87 
    89         String contextTemplate;
    88         String contextTemplate;
    90 
    89 
    91         ContextKind(String contextTemplate) {
    90         ContextKind(String contextTemplate) {
    92             this.contextTemplate = contextTemplate;
    91             this.contextTemplate = contextTemplate;
    93         }
    92         }
    94 
    93 
    95         String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk,
    94         @Override
    96                 GenericKind gk, SubExprKind sk) {
    95         public String expand(String optParameter) {
    97             return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
    96             return contextTemplate;
    98         }
    97         }
    99     }
    98     }
   100 
    99 
   101     enum GenericKind {
   100     enum GenericKind implements ComboParameter {
   102         NONE(""),
   101         NONE(""),
   103         ONE("<X>"),
   102         ONE("<X>"),
   104         TWO("<X,Y>");
   103         TWO("<X,Y>");
   105 
   104 
   106         String typeParameters;
   105         String typeParameters;
   107 
   106 
   108         GenericKind(String typeParameters) {
   107         GenericKind(String typeParameters) {
   109             this.typeParameters = typeParameters;
   108             this.typeParameters = typeParameters;
   110         }
   109         }
   111     }
   110 
   112 
   111         @Override
   113     enum QualifierKind {
   112         public String expand(String optParameter) {
       
   113             return typeParameters;
       
   114         }
       
   115     }
       
   116 
       
   117     enum QualifierKind implements ComboParameter {
   114         THIS("this"),
   118         THIS("this"),
   115         SUPER("super"),
   119         SUPER("super"),
   116         NEW("new Foo()"),
   120         NEW("new Foo()"),
   117         METHOD("m()"),
   121         METHOD("m()"),
   118         FIELD("a.f"),
   122         FIELD("a.f"),
   129         String qualifier;
   133         String qualifier;
   130 
   134 
   131         QualifierKind(String qualifier) {
   135         QualifierKind(String qualifier) {
   132             this.qualifier = qualifier;
   136             this.qualifier = qualifier;
   133         }
   137         }
   134     }
   138 
   135 
   139         @Override
   136     enum ExprKind {
   140         public String expand(String optParameter) {
   137         NONE("#R::S"),
   141             return qualifier;
   138         SINGLE_PAREN1("(#R#S)"),
   142         }
   139         SINGLE_PAREN2("(#R)#S"),
   143     }
   140         DOUBLE_PAREN1("((#R#S))"),
   144 
   141         DOUBLE_PAREN2("((#R)#S)"),
   145     enum ExprKind implements ComboParameter {
   142         DOUBLE_PAREN3("((#R))#S");
   146         NONE("#{MREF}"),
       
   147         SINGLE_PAREN1("(#{MREF}#{SUBEXPR})"),
       
   148         SINGLE_PAREN2("(#{MREF})#{SUBEXPR}"),
       
   149         DOUBLE_PAREN1("((#{MREF}#{SUBEXPR}))"),
       
   150         DOUBLE_PAREN2("((#{MREF})#{SUBEXPR})"),
       
   151         DOUBLE_PAREN3("((#{MREF}))#{SUBEXPR}");
   143 
   152 
   144         String expressionTemplate;
   153         String expressionTemplate;
   145 
   154 
   146         ExprKind(String expressionTemplate) {
   155         ExprKind(String expressionTemplate) {
   147             this.expressionTemplate = expressionTemplate;
   156             this.expressionTemplate = expressionTemplate;
   148         }
   157         }
   149 
   158 
   150         String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) {
   159         @Override
   151             return expressionTemplate
   160         public String expand(String optParameter) {
   152                     .replaceAll("#R", rk.getReferenceString(qk, gk))
   161             return expressionTemplate;
   153                     .replaceAll("#S", sk.subExpression);
   162         }
   154         }
   163     }
   155     }
   164 
   156 
   165     enum SubExprKind implements ComboParameter {
   157     enum SubExprKind {
       
   158         NONE(""),
   166         NONE(""),
   159         SELECT_FIELD(".f"),
   167         SELECT_FIELD(".f"),
   160         SELECT_METHOD(".f()"),
   168         SELECT_METHOD(".f()"),
   161         SELECT_NEW(".new Foo()"),
   169         SELECT_NEW(".new Foo()"),
   162         POSTINC("++"),
   170         POSTINC("++"),
   165         String subExpression;
   173         String subExpression;
   166 
   174 
   167         SubExprKind(String subExpression) {
   175         SubExprKind(String subExpression) {
   168             this.subExpression = subExpression;
   176             this.subExpression = subExpression;
   169         }
   177         }
       
   178 
       
   179         @Override
       
   180         public String expand(String optParameter) {
       
   181             return subExpression;
       
   182         }
   170     }
   183     }
   171 
   184 
   172     public static void main(String... args) throws Exception {
   185     public static void main(String... args) throws Exception {
   173         for (ReferenceKind rk : ReferenceKind.values()) {
   186         new ComboTestHelper<MethodReferenceParserTest>()
   174             for (QualifierKind qk : QualifierKind.values()) {
   187                 .withDimension("MREF", (x, ref) -> x.rk = ref, ReferenceKind.values())
   175                 for (GenericKind gk : GenericKind.values()) {
   188                 .withDimension("QUAL", QualifierKind.values())
   176                     for (SubExprKind sk : SubExprKind.values()) {
   189                 .withDimension("TARGS", GenericKind.values())
   177                         for (ExprKind ek : ExprKind.values()) {
   190                 .withDimension("EXPR", ExprKind.values())
   178                             for (ContextKind ck : ContextKind.values()) {
   191                 .withDimension("SUBEXPR", SubExprKind.values())
   179                                 pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck));
   192                 .withDimension("CTX", ContextKind.values())
   180                             }
   193                 .run(MethodReferenceParserTest::new);
   181                         }
       
   182                     }
       
   183                 }
       
   184             }
       
   185         }
       
   186 
       
   187         checkAfterExec();
       
   188     }
   194     }
   189 
   195 
   190     ReferenceKind rk;
   196     ReferenceKind rk;
   191     QualifierKind qk;
   197 
   192     GenericKind gk;
   198     String template = "class Test {\n" +
   193     SubExprKind sk;
   199                       "   void test() {\n" +
   194     ExprKind ek;
   200                       "      #{CTX}\n" +
   195     ContextKind ck;
   201                       "   }" +
   196     JavaSource source;
   202                       "}";
   197     DiagnosticChecker diagChecker;
       
   198 
       
   199     MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek, ContextKind ck) {
       
   200         this.rk = rk;
       
   201         this.qk = qk;
       
   202         this.gk = gk;
       
   203         this.sk = sk;
       
   204         this.ek = ek;
       
   205         this.ck = ck;
       
   206         this.source = new JavaSource();
       
   207         this.diagChecker = new DiagnosticChecker();
       
   208     }
       
   209 
       
   210     class JavaSource extends SimpleJavaFileObject {
       
   211 
       
   212         String template = "class Test {\n" +
       
   213                           "   void test() {\n" +
       
   214                           "      #C\n" +
       
   215                           "   }" +
       
   216                           "}";
       
   217 
       
   218         String source;
       
   219 
       
   220         public JavaSource() {
       
   221             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
       
   222             source = template.replaceAll("#C", ck.contextString(ek, rk, qk, gk, sk));
       
   223         }
       
   224 
       
   225         @Override
       
   226         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
       
   227             return source;
       
   228         }
       
   229     }
       
   230 
   203 
   231     @Override
   204     @Override
   232     public void run() {
   205     public void doWork() throws IOException {
   233         JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
   206         check(newCompilationTask()
   234                 null, null, Arrays.asList(source));
   207                 .withSourceFromTemplate(template)
   235         try {
   208                 .parse());
   236             ct.parse();
   209     }
   237         } catch (Throwable ex) {
   210 
   238             processException(ex);
   211     void check(Result<?> res) {
   239             return;
   212         if (res.hasErrors() != rk.erroneous()) {
   240         }
   213             fail("invalid diagnostics for source:\n" +
   241         check();
   214                 res.compilationInfo() +
   242     }
   215                 "\nFound error: " + res.hasErrors() +
   243 
       
   244     void check() {
       
   245         checkCount.incrementAndGet();
       
   246 
       
   247         if (diagChecker.errorFound != rk.erroneous()) {
       
   248             throw new Error("invalid diagnostics for source:\n" +
       
   249                 source.getCharContent(true) +
       
   250                 "\nFound error: " + diagChecker.errorFound +
       
   251                 "\nExpected error: " + rk.erroneous());
   216                 "\nExpected error: " + rk.erroneous());
   252         }
   217         }
   253     }
   218     }
   254 
       
   255     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
       
   256 
       
   257         boolean errorFound;
       
   258 
       
   259         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
       
   260             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
       
   261                 errorFound = true;
       
   262             }
       
   263         }
       
   264     }
       
   265 
       
   266 }
   219 }