langtools/test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java
changeset 15040 99fd9483d3f0
parent 11381 890ea587d133
child 15384 5a8d00abf076
equal deleted inserted replaced
15039:80190ab051c0 15040:99fd9483d3f0
     1 /*
     1 /*
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 7046778
    26  * @bug 7046778
    27  * @summary Project Coin: problem with diamond and member inner classes
    27  * @summary Project Coin: problem with diamond and member inner classes
       
    28  * @library ../../../lib
       
    29  * @build JavacTestingAbstractThreadedTest
       
    30  * @run main DiamondAndInnerClassTest
    28  */
    31  */
    29 
    32 
    30 import com.sun.source.util.JavacTask;
    33 import com.sun.source.util.JavacTask;
    31 import java.net.URI;
    34 import java.net.URI;
    32 import java.util.Arrays;
    35 import java.util.Arrays;
    33 import javax.tools.Diagnostic;
    36 import javax.tools.Diagnostic;
    34 import javax.tools.JavaCompiler;
       
    35 import javax.tools.JavaFileObject;
    37 import javax.tools.JavaFileObject;
    36 import javax.tools.SimpleJavaFileObject;
    38 import javax.tools.SimpleJavaFileObject;
    37 import javax.tools.StandardJavaFileManager;
    39 
    38 import javax.tools.ToolProvider;
    40 public class DiamondAndInnerClassTest
    39 
    41     extends JavacTestingAbstractThreadedTest
    40 public class DiamondAndInnerClassTest {
    42     implements Runnable {
    41 
       
    42     static int checkCount = 0;
       
    43 
    43 
    44     enum TypeArgumentKind {
    44     enum TypeArgumentKind {
    45         NONE(""),
    45         NONE(""),
    46         STRING("<String>"),
    46         STRING("<String>"),
    47         INTEGER("<Integer>"),
    47         INTEGER("<Integer>"),
   149             return n ==innerClassDeclArity.n;
   149             return n ==innerClassDeclArity.n;
   150         }
   150         }
   151     }
   151     }
   152 
   152 
   153     public static void main(String... args) throws Exception {
   153     public static void main(String... args) throws Exception {
   154 
       
   155         //create default shared JavaCompiler - reused across multiple compilations
       
   156         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
       
   157         StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
       
   158 
       
   159         for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
   154         for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
   160             for (TypeQualifierArity declType : TypeQualifierArity.values()) {
   155             for (TypeQualifierArity declType : TypeQualifierArity.values()) {
   161                 if (!declType.matches(innerClassDeclArity)) continue;
   156                 if (!declType.matches(innerClassDeclArity)) continue;
   162                 for (TypeQualifierArity newClassType : TypeQualifierArity.values()) {
   157                 for (TypeQualifierArity newClassType : TypeQualifierArity.values()) {
   163                     if (!newClassType.matches(innerClassDeclArity)) continue;
   158                     if (!newClassType.matches(innerClassDeclArity)) continue;
   166                         for (TypeArgumentKind taDecl1 : TypeArgumentKind.values()) {
   161                         for (TypeArgumentKind taDecl1 : TypeArgumentKind.values()) {
   167                             boolean isDeclRaw = taDecl1 == TypeArgumentKind.NONE;
   162                             boolean isDeclRaw = taDecl1 == TypeArgumentKind.NONE;
   168                             //no diamond on decl site
   163                             //no diamond on decl site
   169                             if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
   164                             if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
   170                             for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
   165                             for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
   171                                 boolean isSiteRaw = taSite1 == TypeArgumentKind.NONE;
   166                                 boolean isSiteRaw =
       
   167                                         taSite1 == TypeArgumentKind.NONE;
   172                                 //diamond only allowed on the last type qualifier
   168                                 //diamond only allowed on the last type qualifier
   173                                 if (taSite1 == TypeArgumentKind.DIAMOND &&
   169                                 if (taSite1 == TypeArgumentKind.DIAMOND &&
   174                                         innerClassDeclArity != InnerClassDeclArity.ONE) continue;
   170                                         innerClassDeclArity !=
       
   171                                         InnerClassDeclArity.ONE)
       
   172                                     continue;
   175                                 for (ArgumentKind arg1 : ArgumentKind.values()) {
   173                                 for (ArgumentKind arg1 : ArgumentKind.values()) {
   176                                     if (innerClassDeclArity == innerClassDeclArity.ONE) {
   174                                     if (innerClassDeclArity == innerClassDeclArity.ONE) {
   177                                         new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
   175                                         pool.execute(
   178                                                 argList, new TypeArgumentKind[] {taDecl1},
   176                                                 new DiamondAndInnerClassTest(
   179                                                 new TypeArgumentKind[] {taSite1}, new ArgumentKind[] {arg1}).run(comp, fm);
   177                                                 innerClassDeclArity, declType,
       
   178                                                 newClassType, argList,
       
   179                                                 new TypeArgumentKind[] {taDecl1},
       
   180                                                 new TypeArgumentKind[] {taSite1},
       
   181                                                 new ArgumentKind[] {arg1}));
   180                                         continue;
   182                                         continue;
   181                                     }
   183                                     }
   182                                     for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
   184                                     for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
   183                                         //no rare types
   185                                         //no rare types
   184                                         if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE)) continue;
   186                                         if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE))
       
   187                                             continue;
   185                                         //no diamond on decl site
   188                                         //no diamond on decl site
   186                                         if (taDecl2 == TypeArgumentKind.DIAMOND) continue;
   189                                         if (taDecl2 == TypeArgumentKind.DIAMOND)
       
   190                                             continue;
   187                                         for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
   191                                         for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
   188                                             //no rare types
   192                                             //no rare types
   189                                             if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE)) continue;
   193                                             if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE))
       
   194                                                 continue;
   190                                             //diamond only allowed on the last type qualifier
   195                                             //diamond only allowed on the last type qualifier
   191                                             if (taSite2 == TypeArgumentKind.DIAMOND &&
   196                                             if (taSite2 == TypeArgumentKind.DIAMOND &&
   192                                                     innerClassDeclArity != InnerClassDeclArity.TWO) continue;
   197                                                     innerClassDeclArity != InnerClassDeclArity.TWO)
       
   198                                                 continue;
   193                                             for (ArgumentKind arg2 : ArgumentKind.values()) {
   199                                             for (ArgumentKind arg2 : ArgumentKind.values()) {
   194                                                 if (innerClassDeclArity == innerClassDeclArity.TWO) {
   200                                                 if (innerClassDeclArity == innerClassDeclArity.TWO) {
   195                                                     new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
   201                                                     pool.execute(
   196                                                             argList, new TypeArgumentKind[] {taDecl1, taDecl2},
   202                                                             new DiamondAndInnerClassTest(
       
   203                                                             innerClassDeclArity,
       
   204                                                             declType,
       
   205                                                             newClassType,
       
   206                                                             argList,
       
   207                                                             new TypeArgumentKind[] {taDecl1, taDecl2},
   197                                                             new TypeArgumentKind[] {taSite1, taSite2},
   208                                                             new TypeArgumentKind[] {taSite1, taSite2},
   198                                                             new ArgumentKind[] {arg1, arg2}).run(comp, fm);
   209                                                             new ArgumentKind[] {arg1, arg2}));
   199                                                     continue;
   210                                                     continue;
   200                                                 }
   211                                                 }
   201                                                 for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
   212                                                 for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
   202                                                     //no rare types
   213                                                     //no rare types
   203                                                     if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE)) continue;
   214                                                     if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE))
       
   215                                                         continue;
   204                                                     //no diamond on decl site
   216                                                     //no diamond on decl site
   205                                                     if (taDecl3 == TypeArgumentKind.DIAMOND) continue;
   217                                                     if (taDecl3 == TypeArgumentKind.DIAMOND)
       
   218                                                         continue;
   206                                                     for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
   219                                                     for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
   207                                                         //no rare types
   220                                                         //no rare types
   208                                                         if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE)) continue;
   221                                                         if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE))
       
   222                                                             continue;
   209                                                         //diamond only allowed on the last type qualifier
   223                                                         //diamond only allowed on the last type qualifier
   210                                                         if (taSite3 == TypeArgumentKind.DIAMOND &&
   224                                                         if (taSite3 == TypeArgumentKind.DIAMOND &&
   211                                                                 innerClassDeclArity != InnerClassDeclArity.THREE) continue;
   225                                                             innerClassDeclArity != InnerClassDeclArity.THREE)
       
   226                                                             continue;
   212                                                         for (ArgumentKind arg3 : ArgumentKind.values()) {
   227                                                         for (ArgumentKind arg3 : ArgumentKind.values()) {
   213                                                             if (innerClassDeclArity == innerClassDeclArity.THREE) {
   228                                                             if (innerClassDeclArity ==
   214                                                                 new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
   229                                                                     innerClassDeclArity.THREE) {
   215                                                                         argList, new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
   230                                                                 pool.execute(
       
   231                                                                         new DiamondAndInnerClassTest(
       
   232                                                                         innerClassDeclArity,
       
   233                                                                         declType,
       
   234                                                                         newClassType,
       
   235                                                                         argList,
       
   236                                                                         new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
   216                                                                         new TypeArgumentKind[] {taSite1, taSite2, taSite3},
   237                                                                         new TypeArgumentKind[] {taSite1, taSite2, taSite3},
   217                                                                         new ArgumentKind[] {arg1, arg2, arg3}).run(comp, fm);
   238                                                                         new ArgumentKind[] {arg1, arg2, arg3}));
   218                                                                 continue;
   239                                                                 continue;
   219                                                             }
   240                                                             }
   220                                                         }
   241                                                         }
   221                                                     }
   242                                                     }
   222                                                 }
   243                                                 }
   228                         }
   249                         }
   229                     }
   250                     }
   230                 }
   251                 }
   231             }
   252             }
   232         }
   253         }
   233         System.out.println("Total check executed: " + checkCount);
   254 
       
   255         checkAfterExec();
   234     }
   256     }
   235 
   257 
   236     InnerClassDeclArity innerClassDeclArity;
   258     InnerClassDeclArity innerClassDeclArity;
   237     TypeQualifierArity declType;
   259     TypeQualifierArity declType;
   238     TypeQualifierArity siteType;
   260     TypeQualifierArity siteType;
   242     ArgumentKind[] argumentKinds;
   264     ArgumentKind[] argumentKinds;
   243     JavaSource source;
   265     JavaSource source;
   244     DiagnosticChecker diagChecker;
   266     DiagnosticChecker diagChecker;
   245 
   267 
   246     DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
   268     DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
   247             TypeQualifierArity declType, TypeQualifierArity siteType, ArgumentListArity argList,
   269             TypeQualifierArity declType, TypeQualifierArity siteType,
   248             TypeArgumentKind[] declTypeArgumentKinds, TypeArgumentKind[] siteTypeArgumentKinds,
   270             ArgumentListArity argList, TypeArgumentKind[] declTypeArgumentKinds,
   249             ArgumentKind[] argumentKinds) {
   271             TypeArgumentKind[] siteTypeArgumentKinds, ArgumentKind[] argumentKinds) {
   250         this.innerClassDeclArity = innerClassDeclArity;
   272         this.innerClassDeclArity = innerClassDeclArity;
   251         this.declType = declType;
   273         this.declType = declType;
   252         this.siteType = siteType;
   274         this.siteType = siteType;
   253         this.argList = argList;
   275         this.argList = argList;
   254         this.declTypeArgumentKinds = declTypeArgumentKinds;
   276         this.declTypeArgumentKinds = declTypeArgumentKinds;
   265         String source;
   287         String source;
   266 
   288 
   267         public JavaSource() {
   289         public JavaSource() {
   268             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   290             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   269             source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
   291             source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
   270                              .replace("#D", declType.getType(declTypeArgumentKinds))
   292                     .replace("#D", declType.getType(declTypeArgumentKinds))
   271                              .replace("#S", siteType.getType(siteTypeArgumentKinds))
   293                     .replace("#S", siteType.getType(siteTypeArgumentKinds))
   272                              .replace("#AL", argList.getArgs(argumentKinds));
   294                     .replace("#AL", argList.getArgs(argumentKinds));
   273         }
   295         }
   274 
   296 
   275         @Override
   297         @Override
   276         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   298         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   277             return source;
   299             return source;
   278         }
   300         }
   279     }
   301     }
   280 
   302 
   281     void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
   303     @Override
   282         JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
   304     public void run() {
       
   305         JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
   283                 null, null, Arrays.asList(source));
   306                 null, null, Arrays.asList(source));
   284         try {
   307         try {
   285             ct.analyze();
   308             ct.analyze();
   286         } catch (Throwable ex) {
   309         } catch (Throwable ex) {
   287             throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
   310             throw new AssertionError("Error thrown when compiling the following code:\n" +
       
   311                     source.getCharContent(true));
   288         }
   312         }
   289         check();
   313         check();
   290     }
   314     }
   291 
   315 
   292     void check() {
   316     void check() {
   293         checkCount++;
   317         checkCount.incrementAndGet();
   294 
   318 
   295         boolean errorExpected = false;
   319         boolean errorExpected = false;
   296 
   320 
   297         TypeArgumentKind[] expectedArgKinds = new TypeArgumentKind[innerClassDeclArity.n];
   321         TypeArgumentKind[] expectedArgKinds =
       
   322                 new TypeArgumentKind[innerClassDeclArity.n];
   298 
   323 
   299         for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
   324         for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
   300             if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
   325             if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
   301                 errorExpected = true;
   326                 errorExpected = true;
   302                 break;
   327                 break;
   303             }
   328             }
   304             expectedArgKinds[i] = siteTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND ?
   329             expectedArgKinds[i] = siteTypeArgumentKinds[i] ==
       
   330                     TypeArgumentKind.DIAMOND ?
   305                 declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
   331                 declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
   306         }
   332         }
   307 
   333 
   308         if (!errorExpected) {
   334         if (!errorExpected) {
   309             for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
   335             for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
   310                 //System.out.println("check " + expectedArgKinds[i] + " against " + argumentKinds[i]);
       
   311                 if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
   336                 if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
   312                     errorExpected = true;
   337                     errorExpected = true;
   313                     break;
   338                     break;
   314                 }
   339                 }
   315             }
   340             }
   321                 "\nFound error: " + diagChecker.errorFound +
   346                 "\nFound error: " + diagChecker.errorFound +
   322                 "\nExpected error: " + errorExpected);
   347                 "\nExpected error: " + errorExpected);
   323         }
   348         }
   324     }
   349     }
   325 
   350 
   326     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   351     static class DiagnosticChecker
       
   352         implements javax.tools.DiagnosticListener<JavaFileObject> {
   327 
   353 
   328         boolean errorFound;
   354         boolean errorFound;
   329 
   355 
   330         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   356         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   331             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   357             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   332                 errorFound = true;
   358                 errorFound = true;
   333             }
   359             }
   334         }
   360         }
   335     }
   361     }
       
   362 
   336 }
   363 }