langtools/test/tools/javac/varargs/warning/Warn4.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     6945418 6993978 8006694 7196160
    26  * @bug     6945418 6993978 8006694 7196160 8129962
    27  * @summary Project Coin: Simplified Varargs Method Invocation
    27  * @summary Project Coin: Simplified Varargs Method Invocation
    28  *  temporarily workaround combo tests are causing time out in several platforms
    28  *  temporarily workaround combo tests are causing time out in several platforms
    29  * @author  mcimadamore
    29  * @library /tools/javac/lib
    30  * @library ../../lib
    30  * @modules jdk.compiler/com.sun.tools.javac.api
    31  * @modules jdk.compiler
    31  *          jdk.compiler/com.sun.tools.javac.code
    32  * @build JavacTestingAbstractThreadedTest
    32  *          jdk.compiler/com.sun.tools.javac.comp
    33  * @run main/othervm Warn4
    33  *          jdk.compiler/com.sun.tools.javac.main
       
    34  *          jdk.compiler/com.sun.tools.javac.tree
       
    35  *          jdk.compiler/com.sun.tools.javac.util
       
    36  * @build combo.ComboTestHelper
       
    37  * @run main Warn4
    34  */
    38  */
    35 
    39 
    36 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
    40 import java.io.IOException;
    37 // see JDK-8006746
       
    38 
       
    39 import java.net.URI;
       
    40 import java.util.Arrays;
       
    41 import java.util.Set;
    41 import java.util.Set;
    42 import java.util.HashSet;
    42 import java.util.HashSet;
    43 import javax.tools.Diagnostic;
    43 import javax.tools.Diagnostic;
    44 import javax.tools.JavaCompiler;
    44 import javax.tools.Diagnostic.Kind;
    45 import javax.tools.JavaFileObject;
    45 import javax.tools.JavaFileObject;
    46 import javax.tools.SimpleJavaFileObject;
    46 
    47 import javax.tools.ToolProvider;
    47 import combo.ComboInstance;
    48 import com.sun.source.util.JavacTask;
    48 import combo.ComboParameter;
    49 
    49 import combo.ComboTask.Result;
    50 public class Warn4
    50 import combo.ComboTestHelper;
    51     extends JavacTestingAbstractThreadedTest
    51 
    52     implements Runnable {
    52 public class Warn4 extends ComboInstance<Warn4> {
    53 
    53 
    54     final static Warning[] error = null;
    54     final static Warning[] error = null;
    55     final static Warning[] none = new Warning[] {};
    55     final static Warning[] none = new Warning[] {};
    56     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
    56     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
    57     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
    57     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
    58     final static Warning[] both =
    58     final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
    59             new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
       
    60 
    59 
    61     enum Warning {
    60     enum Warning {
    62         UNCHECKED("generic.array.creation"),
    61         UNCHECKED("generic.array.creation"),
    63         VARARGS("varargs.non.reifiable.type");
    62         VARARGS("varargs.non.reifiable.type");
    64 
    63 
   103         SourceLevel(String sourceKey) {
   102         SourceLevel(String sourceKey) {
   104             this.sourceKey = sourceKey;
   103             this.sourceKey = sourceKey;
   105         }
   104         }
   106     }
   105     }
   107 
   106 
   108     enum TrustMe {
   107     enum TrustMe implements ComboParameter {
   109         DONT_TRUST(""),
   108         DONT_TRUST(""),
   110         TRUST("@java.lang.SafeVarargs");
   109         TRUST("@java.lang.SafeVarargs");
   111 
   110 
   112         String anno;
   111         String anno;
   113 
   112 
   114         TrustMe(String anno) {
   113         TrustMe(String anno) {
   115             this.anno = anno;
   114             this.anno = anno;
   116         }
   115         }
   117     }
   116 
   118 
   117         @Override
   119     enum ModifierKind {
   118         public String expand(String optParameter) {
       
   119             return anno;
       
   120         }
       
   121     }
       
   122 
       
   123     enum ModifierKind implements ComboParameter {
   120         NONE(" "),
   124         NONE(" "),
   121         FINAL("final "),
   125         FINAL("final "),
   122         STATIC("static "),
   126         STATIC("static "),
   123         PRIVATE("private ");
   127         PRIVATE("private ");
   124 
   128 
   125         String mod;
   129         String mod;
   126 
   130 
   127         ModifierKind(String mod) {
   131         ModifierKind(String mod) {
   128             this.mod = mod;
   132             this.mod = mod;
   129         }
   133         }
   130     }
   134 
   131 
   135         @Override
   132     enum SuppressLevel {
   136         public String expand(String optParameter) {
       
   137             return mod;
       
   138         }
       
   139     }
       
   140 
       
   141     enum SuppressLevel implements ComboParameter {
   133         NONE(""),
   142         NONE(""),
   134         UNCHECKED("unchecked");
   143         UNCHECKED("unchecked");
   135 
   144 
   136         String lint;
   145         String lint;
   137 
   146 
   138         SuppressLevel(String lint) {
   147         SuppressLevel(String lint) {
   139             this.lint = lint;
   148             this.lint = lint;
   140         }
   149         }
   141 
   150 
   142         String getSuppressAnno() {
   151         @Override
       
   152         public String expand(String optParameter) {
   143             return "@SuppressWarnings(\"" + lint + "\")";
   153             return "@SuppressWarnings(\"" + lint + "\")";
   144         }
   154         }
   145     }
   155     }
   146 
   156 
   147     enum Signature {
   157     enum Signature implements ComboParameter {
   148         UNBOUND("void #name(List<?>#arity arg) { #body }",
   158         UNBOUND("void #NAME(List<?>#ARITY arg) { #BODY }",
   149             new Warning[][] {none, none, none, none, error}),
   159             new Warning[][] {none, none, none, none, error}),
   150         INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
   160         INVARIANT_TVAR("<Z> void #NAME(List<Z>#ARITY arg) { #BODY }",
   151             new Warning[][] {both, both, error, both, error}),
   161             new Warning[][] {both, both, error, both, error}),
   152         TVAR("<Z> void #name(Z#arity arg) { #body }",
   162         TVAR("<Z> void #NAME(Z#ARITY arg) { #BODY }",
   153             new Warning[][] {both, both, both, both, vararg}),
   163             new Warning[][] {both, both, both, both, vararg}),
   154         INVARIANT("void #name(List<String>#arity arg) { #body }",
   164         INVARIANT("void #NAME(List<String>#ARITY arg) { #BODY }",
   155             new Warning[][] {error, error, error, both, error}),
   165             new Warning[][] {error, error, error, both, error}),
   156         UNPARAMETERIZED("void #name(String#arity arg) { #body }",
   166         UNPARAMETERIZED("void #NAME(String#ARITY arg) { #BODY }",
   157             new Warning[][] {error, error, error, error, none});
   167             new Warning[][] {error, error, error, error, none});
   158 
   168 
   159         String template;
   169         String template;
   160         Warning[][] warnings;
   170         Warning[][] warnings;
   161 
   171 
   175 
   185 
   176         boolean giveVarargs(Signature other) {
   186         boolean giveVarargs(Signature other) {
   177             return warnings[other.ordinal()] == vararg ||
   187             return warnings[other.ordinal()] == vararg ||
   178                     warnings[other.ordinal()] == both;
   188                     warnings[other.ordinal()] == both;
   179         }
   189         }
   180     }
   190 
   181 
   191         @Override
   182     public static void main(String... args) throws Exception {
   192         public String expand(String optParameter) {
   183         for (SourceLevel sourceLevel : SourceLevel.values()) {
   193             if (optParameter.equals("CLIENT")) {
   184             for (TrustMe trustMe : TrustMe.values()) {
   194                 return template.replaceAll("#ARITY", "")
   185                 for (SuppressLevel suppressLevelClient : SuppressLevel.values()) {
   195                         .replaceAll("#NAME", "test")
   186                     for (SuppressLevel suppressLevelDecl : SuppressLevel.values()) {
   196                         .replaceAll("#BODY", "m(arg)");
   187                         for (ModifierKind modKind : ModifierKind.values()) {
   197             } else {
   188                             for (Signature vararg_meth : Signature.values()) {
   198                 return template.replaceAll("#ARITY", "...")
   189                                 for (Signature client_meth : Signature.values()) {
   199                         .replaceAll("#NAME", "m")
   190                                     if (vararg_meth.isApplicableTo(client_meth)) {
   200                         .replaceAll("#BODY", "");
   191                                         pool.execute(new Warn4(sourceLevel,
       
   192                                                 trustMe,
       
   193                                                 suppressLevelClient,
       
   194                                                 suppressLevelDecl,
       
   195                                                 modKind,
       
   196                                                 vararg_meth,
       
   197                                                 client_meth));
       
   198                                     }
       
   199                                 }
       
   200                             }
       
   201                         }
       
   202                     }
       
   203                 }
       
   204             }
   201             }
   205         }
   202         }
   206 
   203     }
   207         checkAfterExec();
   204 
       
   205     public static void main(String... args) {
       
   206         new ComboTestHelper<Warn4>()
       
   207                 .withFilter(Warn4::badTestFilter)
       
   208                 .withDimension("SOURCE", (x, level) -> x.sourceLevel = level, SourceLevel.values())
       
   209                 .withDimension("TRUSTME", (x, trustme) -> x.trustMe = trustme, TrustMe.values())
       
   210                 .withArrayDimension("SUPPRESS", (x, suppress, idx) -> x.suppress[idx] = suppress, 2, SuppressLevel.values())
       
   211                 .withDimension("MOD", (x, mod) -> x.modKind = mod, ModifierKind.values())
       
   212                 .withArrayDimension("MTH", (x, sig, idx) -> x.sigs[idx] = sig, 2, Signature.values())
       
   213                 .run(Warn4::new);
   208     }
   214     }
   209 
   215 
   210     SourceLevel sourceLevel;
   216     SourceLevel sourceLevel;
   211     TrustMe trustMe;
   217     TrustMe trustMe;
   212     SuppressLevel suppressLevelClient;
   218     SuppressLevel[] suppress = new SuppressLevel[2];
   213     SuppressLevel suppressLevelDecl;
       
   214     ModifierKind modKind;
   219     ModifierKind modKind;
   215     Signature vararg_meth;
   220     Signature[] sigs = new Signature[2];
   216     Signature client_meth;
   221 
   217     DiagnosticChecker diagChecker;
   222     boolean badTestFilter() {
   218 
   223         return sigs[0].isApplicableTo(sigs[1]);
   219     public Warn4(SourceLevel sourceLevel, TrustMe trustMe,
   224     }
   220             SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
   225 
   221             ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
   226     final String template = "import java.util.List;\n" +
   222         this.sourceLevel = sourceLevel;
   227                             "class Test {\n" +
   223         this.trustMe = trustMe;
   228                             "   #{TRUSTME} #{SUPPRESS[0]} #{MOD} #{MTH[0].VARARG}\n" +
   224         this.suppressLevelClient = suppressLevelClient;
   229                             "   #{SUPPRESS[1]} #{MTH[1].CLIENT}\n" +
   225         this.suppressLevelDecl = suppressLevelDecl;
   230                             "}";
   226         this.modKind = modKind;
       
   227         this.vararg_meth = vararg_meth;
       
   228         this.client_meth = client_meth;
       
   229         this.diagChecker = new DiagnosticChecker();
       
   230     }
       
   231 
   231 
   232     @Override
   232     @Override
   233     public void run() {
   233     public void doWork() throws IOException {
   234         int id = checkCount.incrementAndGet();
   234         check(newCompilationTask()
   235         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   235                 .withOption("-Xlint:unchecked")
   236         JavaSource source = new JavaSource(id);
   236                 .withOption("-source")
   237         JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
   237                 .withOption(sourceLevel.sourceKey)
   238                 Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
   238                 .withSourceFromTemplate(template)
   239                 null, Arrays.asList(source));
   239                 .analyze());
   240         ct.call(); //to get mandatory notes
   240     }
   241         check(source, new boolean[] {vararg_meth.giveUnchecked(client_meth),
   241 
   242                                vararg_meth.giveVarargs(client_meth)});
   242     void check(Result<?> res) {
   243     }
   243         boolean[] warnArr = new boolean[] {sigs[0].giveUnchecked(sigs[1]),
   244 
   244                                sigs[0].giveVarargs(sigs[1])};
   245     void check(JavaSource source, boolean[] warnArr) {
   245 
       
   246         Set<Warning> warnings = new HashSet<>();
       
   247         for (Diagnostic<? extends JavaFileObject> d : res.diagnosticsForKind(Kind.MANDATORY_WARNING)) {
       
   248             if (d.getCode().contains(Warning.VARARGS.key)) {
       
   249                     warnings.add(Warning.VARARGS);
       
   250             } else if(d.getCode().contains(Warning.UNCHECKED.key)) {
       
   251                 warnings.add(Warning.UNCHECKED);
       
   252             }
       
   253         }
       
   254 
   246         boolean badOutput = false;
   255         boolean badOutput = false;
   247         for (Warning wkind : Warning.values()) {
   256         for (Warning wkind : Warning.values()) {
   248             boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
   257             boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
   249                     suppressLevelClient, suppressLevelDecl, modKind);
   258                     suppress[1], suppress[0], modKind);
   250             badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) !=
   259             badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) !=
   251                     diagChecker.warnings.contains(wkind);
   260                     warnings.contains(wkind);
   252         }
   261         }
   253         if (badOutput) {
   262         if (badOutput) {
   254             throw new Error("invalid diagnostics for source:\n" +
   263             fail("invalid diagnostics for source:\n" +
   255                     source.getCharContent(true) +
   264                     res.compilationInfo() +
   256                     "\nExpected unchecked warning: " + warnArr[0] +
   265                     "\nExpected unchecked warning: " + warnArr[0] +
   257                     "\nExpected unsafe vararg warning: " + warnArr[1] +
   266                     "\nExpected unsafe vararg warning: " + warnArr[1] +
   258                     "\nWarnings: " + diagChecker.warnings +
   267                     "\nWarnings: " + warnings +
   259                     "\nSource level: " + sourceLevel);
   268                     "\nSource level: " + sourceLevel);
   260         }
   269         }
   261     }
   270     }
   262 
       
   263     class JavaSource extends SimpleJavaFileObject {
       
   264 
       
   265         String source;
       
   266 
       
   267         public JavaSource(int id) {
       
   268             super(URI.create(String.format("myfo:/Test%d.java", id)),
       
   269                     JavaFileObject.Kind.SOURCE);
       
   270             String meth1 = vararg_meth.template.replace("#arity", "...");
       
   271             meth1 = meth1.replace("#name", "m");
       
   272             meth1 = meth1.replace("#body", "");
       
   273             meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() +
       
   274                     modKind.mod + meth1;
       
   275             String meth2 = client_meth.template.replace("#arity", "");
       
   276             meth2 = meth2.replace("#name", "test");
       
   277             meth2 = meth2.replace("#body", "m(arg);");
       
   278             meth2 = suppressLevelClient.getSuppressAnno() + meth2;
       
   279             source = String.format("import java.util.List;\n" +
       
   280                      "class Test%s {\n %s \n %s \n } \n", id, meth1, meth2);
       
   281         }
       
   282 
       
   283         @Override
       
   284         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
       
   285             return source;
       
   286         }
       
   287     }
       
   288 
       
   289     static class DiagnosticChecker
       
   290         implements javax.tools.DiagnosticListener<JavaFileObject> {
       
   291 
       
   292         Set<Warning> warnings = new HashSet<>();
       
   293 
       
   294         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
       
   295             if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
       
   296                     diagnostic.getKind() == Diagnostic.Kind.WARNING) {
       
   297                 if (diagnostic.getCode().contains(Warning.VARARGS.key)) {
       
   298                     warnings.add(Warning.VARARGS);
       
   299                 } else if(diagnostic.getCode().contains(Warning.UNCHECKED.key)) {
       
   300                     warnings.add(Warning.UNCHECKED);
       
   301                 }
       
   302             }
       
   303         }
       
   304     }
       
   305 
       
   306 }
   271 }