test/tools/javac/varargs/warning/Warn4.java

Wed, 06 Apr 2011 20:33:44 -0700

author
ohair
date
Wed, 06 Apr 2011 20:33:44 -0700
changeset 962
0ff2bbd38f10
parent 892
3e30c95da3c6
child 1482
954541f13717
permissions
-rw-r--r--

7033660: Update copyright year to 2011 on any files changed in 2011
Reviewed-by: dholmes

     1 /*
     2  * Copyright (c) 2010, 2011, 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     6945418 6993978
    27  * @summary Project Coin: Simplified Varargs Method Invocation
    28  * @author  mcimadamore
    29  * @run main Warn4
    30  */
    31 import com.sun.source.util.JavacTask;
    32 import com.sun.tools.javac.api.JavacTool;
    33 import java.net.URI;
    34 import java.util.Arrays;
    35 import java.util.Set;
    36 import java.util.HashSet;
    37 import javax.tools.Diagnostic;
    38 import javax.tools.JavaCompiler;
    39 import javax.tools.JavaFileObject;
    40 import javax.tools.SimpleJavaFileObject;
    41 import javax.tools.StandardJavaFileManager;
    42 import javax.tools.ToolProvider;
    44 public class Warn4 {
    46     final static Warning[] error = null;
    47     final static Warning[] none = new Warning[] {};
    48     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
    49     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
    50     final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
    52     enum Warning {
    53         UNCHECKED("generic.array.creation"),
    54         VARARGS("varargs.non.reifiable.type");
    56         String key;
    58         Warning(String key) {
    59             this.key = key;
    60         }
    62         boolean isSuppressed(TrustMe trustMe, SourceLevel source, SuppressLevel suppressLevelClient,
    63                 SuppressLevel suppressLevelDecl, ModifierKind modKind) {
    64             switch(this) {
    65                 case VARARGS:
    66                     return source == SourceLevel.JDK_6 ||
    67                             suppressLevelDecl == SuppressLevel.UNCHECKED ||
    68                             trustMe == TrustMe.TRUST;
    69                 case UNCHECKED:
    70                     return suppressLevelClient == SuppressLevel.UNCHECKED ||
    71                         (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE && source == SourceLevel.JDK_7);
    72             }
    74             SuppressLevel supLev = this == VARARGS ?
    75                 suppressLevelDecl :
    76                 suppressLevelClient;
    77             return supLev == SuppressLevel.UNCHECKED ||
    78                     (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE);
    79         }
    80     }
    82     enum SourceLevel {
    83         JDK_6("6"),
    84         JDK_7("7");
    86         String sourceKey;
    88         SourceLevel(String sourceKey) {
    89             this.sourceKey = sourceKey;
    90         }
    91     }
    93     enum TrustMe {
    94         DONT_TRUST(""),
    95         TRUST("@java.lang.SafeVarargs");
    97         String anno;
    99         TrustMe(String anno) {
   100             this.anno = anno;
   101         }
   102     }
   104     enum ModifierKind {
   105         NONE(" "),
   106         FINAL("final "),
   107         STATIC("static ");
   109         String mod;
   111         ModifierKind(String mod) {
   112             this.mod = mod;
   113         }
   114     }
   116     enum SuppressLevel {
   117         NONE(""),
   118         UNCHECKED("unchecked");
   120         String lint;
   122         SuppressLevel(String lint) {
   123             this.lint = lint;
   124         }
   126         String getSuppressAnno() {
   127             return "@SuppressWarnings(\"" + lint + "\")";
   128         }
   129     }
   131     enum Signature {
   132         UNBOUND("void #name(List<?>#arity arg) { #body }",
   133             new Warning[][] {none, none, none, none, error}),
   134         INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
   135             new Warning[][] {both, both, error, both, error}),
   136         TVAR("<Z> void #name(Z#arity arg) { #body }",
   137             new Warning[][] {both, both, both, both, vararg}),
   138         INVARIANT("void #name(List<String>#arity arg) { #body }",
   139             new Warning[][] {error, error, error, both, error}),
   140         UNPARAMETERIZED("void #name(String#arity arg) { #body }",
   141             new Warning[][] {error, error, error, error, none});
   143         String template;
   144         Warning[][] warnings;
   146         Signature(String template, Warning[][] warnings) {
   147             this.template = template;
   148             this.warnings = warnings;
   149         }
   151         boolean isApplicableTo(Signature other) {
   152             return warnings[other.ordinal()] != null;
   153         }
   155         boolean giveUnchecked(Signature other) {
   156             return warnings[other.ordinal()] == unchecked ||
   157                     warnings[other.ordinal()] == both;
   158         }
   160         boolean giveVarargs(Signature other) {
   161             return warnings[other.ordinal()] == vararg ||
   162                     warnings[other.ordinal()] == both;
   163         }
   164     }
   166     public static void main(String... args) throws Exception {
   167         for (SourceLevel sourceLevel : SourceLevel.values()) {
   168             for (TrustMe trustMe : TrustMe.values()) {
   169                 for (SuppressLevel suppressLevelClient : SuppressLevel.values()) {
   170                     for (SuppressLevel suppressLevelDecl : SuppressLevel.values()) {
   171                         for (ModifierKind modKind : ModifierKind.values()) {
   172                             for (Signature vararg_meth : Signature.values()) {
   173                                 for (Signature client_meth : Signature.values()) {
   174                                     if (vararg_meth.isApplicableTo(client_meth)) {
   175                                         test(sourceLevel,
   176                                                 trustMe,
   177                                                 suppressLevelClient,
   178                                                 suppressLevelDecl,
   179                                                 modKind,
   180                                                 vararg_meth,
   181                                                 client_meth);
   182                                     }
   183                                 }
   184                             }
   185                         }
   186                     }
   187                 }
   188             }
   189         }
   190     }
   192     // Create a single file manager and reuse it for each compile to save time.
   193     static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
   195     static void test(SourceLevel sourceLevel, TrustMe trustMe, SuppressLevel suppressLevelClient,
   196             SuppressLevel suppressLevelDecl, ModifierKind modKind, Signature vararg_meth, Signature client_meth) throws Exception {
   197         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   198         JavaSource source = new JavaSource(trustMe, suppressLevelClient, suppressLevelDecl, modKind, vararg_meth, client_meth);
   199         DiagnosticChecker dc = new DiagnosticChecker();
   200         JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
   201                 Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
   202                 null, Arrays.asList(source));
   203         ct.generate(); //to get mandatory notes
   204         check(dc.warnings, sourceLevel,
   205                 new boolean[] {vararg_meth.giveUnchecked(client_meth),
   206                                vararg_meth.giveVarargs(client_meth)},
   207                 source, trustMe, suppressLevelClient, suppressLevelDecl, modKind);
   208     }
   210     static void check(Set<Warning> warnings, SourceLevel sourceLevel, boolean[] warnArr, JavaSource source,
   211             TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl, ModifierKind modKind) {
   212         boolean badOutput = false;
   213         for (Warning wkind : Warning.values()) {
   214             boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
   215                     suppressLevelClient, suppressLevelDecl, modKind);
   216             System.out.println("SUPPRESSED = " + isSuppressed);
   217             badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != warnings.contains(wkind);
   218         }
   219         if (badOutput) {
   220             throw new Error("invalid diagnostics for source:\n" +
   221                     source.getCharContent(true) +
   222                     "\nExpected unchecked warning: " + warnArr[0] +
   223                     "\nExpected unsafe vararg warning: " + warnArr[1] +
   224                     "\nWarnings: " + warnings +
   225                     "\nSource level: " + sourceLevel);
   226         }
   227     }
   229     static class JavaSource extends SimpleJavaFileObject {
   231         String source;
   233         public JavaSource(TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
   234                 ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
   235             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   236             String meth1 = vararg_meth.template.replace("#arity", "...");
   237             meth1 = meth1.replace("#name", "m");
   238             meth1 = meth1.replace("#body", "");
   239             meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() + modKind.mod + meth1;
   240             String meth2 = client_meth.template.replace("#arity", "");
   241             meth2 = meth2.replace("#name", "test");
   242             meth2 = meth2.replace("#body", "m(arg);");
   243             meth2 = suppressLevelClient.getSuppressAnno() + meth2;
   244             source = "import java.util.List;\n" +
   245                      "class Test {\n" + meth1 +
   246                      "\n" + meth2 + "\n}\n";
   247         }
   249         @Override
   250         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   251             return source;
   252         }
   253     }
   255     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   257         Set<Warning> warnings = new HashSet<>();
   259         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   260             if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
   261                     diagnostic.getKind() == Diagnostic.Kind.WARNING) {
   262                 if (diagnostic.getCode().contains(Warning.VARARGS.key)) {
   263                     warnings.add(Warning.VARARGS);
   264                 } else if(diagnostic.getCode().contains(Warning.UNCHECKED.key)) {
   265                     warnings.add(Warning.UNCHECKED);
   266                 }
   267             }
   268         }
   269     }
   270 }

mercurial