langtools/test/tools/javac/varargs/warning/Warn4.java
changeset 7643 a067a0cda531
parent 5847 1908176fd6e3
child 8613 d8e9b6d6ccee
equal deleted inserted replaced
7642:9ca5d29b34f7 7643:a067a0cda531
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /**
    24 /**
    25  * @test
    25  * @test
    26  * @bug     6945418
    26  * @bug     6945418 6993978
    27  * @summary Project Coin: Simplified Varargs Method Invocation
    27  * @summary Project Coin: Simplified Varargs Method Invocation
    28  * @author  mcimadamore
    28  * @author  mcimadamore
    29  * @run main Warn4
    29  * @run main Warn4
    30  */
    30  */
    31 import com.sun.source.util.JavacTask;
    31 import com.sun.source.util.JavacTask;
    46     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
    46     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
    47     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
    47     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
    48     final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
    48     final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
    49 
    49 
    50     enum Warning {
    50     enum Warning {
    51         UNCHECKED("unchecked"),
    51         UNCHECKED("generic.array.creation"),
    52         VARARGS("varargs");
    52         VARARGS("varargs.non.reifiable.type");
    53 
    53 
    54         String category;
    54         String key;
    55 
    55 
    56         Warning(String category) {
    56         Warning(String key) {
    57             this.category = category;
    57             this.key = key;
    58         }
    58         }
    59 
    59 
    60         boolean isEnabled(XlintOption xlint, SuppressLevel suppressLevel) {
    60         boolean isSuppressed(TrustMe trustMe, SourceLevel source, SuppressLevel suppressLevelClient,
    61             return Arrays.asList(xlint.enabledWarnings).contains(this);
    61                 SuppressLevel suppressLevelDecl, ModifierKind modKind) {
    62         }
    62             switch(this) {
    63 
    63                 case VARARGS:
    64         boolean isSuppressed(SuppressLevel suppressLevel) {
    64                     return source == SourceLevel.JDK_6 ||
    65             return Arrays.asList(suppressLevel.suppressedWarnings).contains(VARARGS);
    65                             suppressLevelDecl == SuppressLevel.UNCHECKED ||
    66         }
    66                             trustMe == TrustMe.TRUST;
    67     }
    67                 case UNCHECKED:
    68 
    68                     return suppressLevelClient == SuppressLevel.UNCHECKED ||
    69     enum XlintOption {
    69                         (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE && source == SourceLevel.JDK_7);
    70         NONE(),
       
    71         UNCHECKED(Warning.UNCHECKED),
       
    72         VARARGS(Warning.VARARGS),
       
    73         ALL(Warning.UNCHECKED, Warning.VARARGS);
       
    74 
       
    75         Warning[] enabledWarnings;
       
    76 
       
    77         XlintOption(Warning... enabledWarnings) {
       
    78             this.enabledWarnings = enabledWarnings;
       
    79         }
       
    80 
       
    81         String getXlintOption() {
       
    82             StringBuilder buf = new StringBuilder();
       
    83             String sep = "";
       
    84             for (Warning w : enabledWarnings) {
       
    85                 buf.append(sep);
       
    86                 buf.append(w.category);
       
    87                 sep=",";
       
    88             }
    70             }
    89             return "-Xlint:" +
    71 
    90                     (this == NONE ? "none" : buf.toString());
    72             SuppressLevel supLev = this == VARARGS ?
       
    73                 suppressLevelDecl :
       
    74                 suppressLevelClient;
       
    75             return supLev == SuppressLevel.UNCHECKED ||
       
    76                     (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE);
       
    77         }
       
    78     }
       
    79 
       
    80     enum SourceLevel {
       
    81         JDK_6("6"),
       
    82         JDK_7("7");
       
    83 
       
    84         String sourceKey;
       
    85 
       
    86         SourceLevel(String sourceKey) {
       
    87             this.sourceKey = sourceKey;
       
    88         }
       
    89     }
       
    90 
       
    91     enum TrustMe {
       
    92         DONT_TRUST(""),
       
    93         TRUST("@java.lang.SafeVarargs");
       
    94 
       
    95         String anno;
       
    96 
       
    97         TrustMe(String anno) {
       
    98             this.anno = anno;
       
    99         }
       
   100     }
       
   101 
       
   102     enum ModifierKind {
       
   103         NONE(" "),
       
   104         FINAL("final "),
       
   105         STATIC("static ");
       
   106 
       
   107         String mod;
       
   108 
       
   109         ModifierKind(String mod) {
       
   110             this.mod = mod;
    91         }
   111         }
    92     }
   112     }
    93 
   113 
    94     enum SuppressLevel {
   114     enum SuppressLevel {
    95         NONE(),
   115         NONE(""),
    96         UNCHECKED(Warning.UNCHECKED),
   116         UNCHECKED("unchecked");
    97         VARARGS(Warning.VARARGS),
   117 
    98         ALL(Warning.UNCHECKED, Warning.VARARGS);
   118         String lint;
    99 
   119 
   100         Warning[] suppressedWarnings;
   120         SuppressLevel(String lint) {
   101 
   121             this.lint = lint;
   102         SuppressLevel(Warning... suppressedWarnings) {
   122         }
   103             this.suppressedWarnings = suppressedWarnings;
   123 
   104         }
   124         String getSuppressAnno() {
   105 
   125             return "@SuppressWarnings(\"" + lint + "\")";
   106         String getSuppressAnnotation() {
       
   107             StringBuilder buf = new StringBuilder();
       
   108             String sep = "";
       
   109             for (Warning w : suppressedWarnings) {
       
   110                 buf.append(sep);
       
   111                 buf.append("\"");
       
   112                 buf.append(w.category);
       
   113                 buf.append("\"");
       
   114                 sep=",";
       
   115             }
       
   116             return this == NONE ? "" :
       
   117                 "@SuppressWarnings({" + buf.toString() + "})";
       
   118         }
   126         }
   119     }
   127     }
   120 
   128 
   121     enum Signature {
   129     enum Signature {
   122 
       
   123         EXTENDS_TVAR("<Z> void #name(List<? extends Z>#arity arg) { #body }",
       
   124             new Warning[][] {both, both, both, both, error, both, both, both, error}),
       
   125         SUPER_TVAR("<Z> void #name(List<? super Z>#arity arg) { #body }",
       
   126             new Warning[][] {error, both, error, both, error, error, both, both, error}),
       
   127         UNBOUND("void #name(List<?>#arity arg) { #body }",
   130         UNBOUND("void #name(List<?>#arity arg) { #body }",
   128             new Warning[][] {none, none, none, none, none, none, none, none, error}),
   131             new Warning[][] {none, none, none, none, error}),
   129         INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
   132         INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
   130             new Warning[][] {both, both, both, both, error, both, both, both, error}),
   133             new Warning[][] {both, both, error, both, error}),
   131         TVAR("<Z> void #name(Z#arity arg) { #body }",
   134         TVAR("<Z> void #name(Z#arity arg) { #body }",
   132             new Warning[][] {both, both, both, both, both, both, both, both, vararg}),
   135             new Warning[][] {both, both, both, both, vararg}),
   133         EXTENDS("void #name(List<? extends String>#arity arg) { #body }",
       
   134             new Warning[][] {error, error, error, error, error, both, error, both, error}),
       
   135         SUPER("void #name(List<? super String>#arity arg) { #body }",
       
   136             new Warning[][] {error, error, error, error, error, error, both, both, error}),
       
   137         INVARIANT("void #name(List<String>#arity arg) { #body }",
   136         INVARIANT("void #name(List<String>#arity arg) { #body }",
   138             new Warning[][] {error, error, error, error, error, error, error, both, error}),
   137             new Warning[][] {error, error, error, both, error}),
   139         UNPARAMETERIZED("void #name(String#arity arg) { #body }",
   138         UNPARAMETERIZED("void #name(String#arity arg) { #body }",
   140             new Warning[][] {error, error, error, error, error, error, error, error, none});
   139             new Warning[][] {error, error, error, error, none});
   141 
   140 
   142         String template;
   141         String template;
   143         Warning[][] warnings;
   142         Warning[][] warnings;
   144 
   143 
   145         Signature(String template, Warning[][] warnings) {
   144         Signature(String template, Warning[][] warnings) {
   161                     warnings[other.ordinal()] == both;
   160                     warnings[other.ordinal()] == both;
   162         }
   161         }
   163     }
   162     }
   164 
   163 
   165     public static void main(String... args) throws Exception {
   164     public static void main(String... args) throws Exception {
   166         for (XlintOption xlint : XlintOption.values()) {
   165         for (SourceLevel sourceLevel : SourceLevel.values()) {
   167             for (SuppressLevel suppressLevel : SuppressLevel.values()) {
   166             for (TrustMe trustMe : TrustMe.values()) {
   168                 for (Signature vararg_meth : Signature.values()) {
   167                 for (SuppressLevel suppressLevelClient : SuppressLevel.values()) {
   169                     for (Signature client_meth : Signature.values()) {
   168                     for (SuppressLevel suppressLevelDecl : SuppressLevel.values()) {
   170                         if (vararg_meth.isApplicableTo(client_meth)) {
   169                         for (ModifierKind modKind : ModifierKind.values()) {
   171                             test(xlint,
   170                             for (Signature vararg_meth : Signature.values()) {
   172                                     suppressLevel,
   171                                 for (Signature client_meth : Signature.values()) {
   173                                     vararg_meth,
   172                                     if (vararg_meth.isApplicableTo(client_meth)) {
   174                                     client_meth);
   173                                         test(sourceLevel,
       
   174                                                 trustMe,
       
   175                                                 suppressLevelClient,
       
   176                                                 suppressLevelDecl,
       
   177                                                 modKind,
       
   178                                                 vararg_meth,
       
   179                                                 client_meth);
       
   180                                     }
       
   181                                 }
       
   182                             }
   175                         }
   183                         }
   176                     }
   184                     }
   177                 }
   185                 }
   178             }
   186             }
   179         }
   187         }
   180     }
   188     }
   181 
   189 
   182     static void test(XlintOption xlint, SuppressLevel suppressLevel,
   190     static void test(SourceLevel sourceLevel, TrustMe trustMe, SuppressLevel suppressLevelClient,
   183             Signature vararg_meth, Signature client_meth) throws Exception {
   191             SuppressLevel suppressLevelDecl, ModifierKind modKind, Signature vararg_meth, Signature client_meth) throws Exception {
   184         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   192         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   185         JavaSource source = new JavaSource(suppressLevel, vararg_meth, client_meth);
   193         JavaSource source = new JavaSource(trustMe, suppressLevelClient, suppressLevelDecl, modKind, vararg_meth, client_meth);
   186         DiagnosticChecker dc = new DiagnosticChecker();
   194         DiagnosticChecker dc = new DiagnosticChecker();
   187         JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
   195         JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
   188                 Arrays.asList(xlint.getXlintOption()), null, Arrays.asList(source));
   196                 Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
       
   197                 null, Arrays.asList(source));
   189         ct.generate(); //to get mandatory notes
   198         ct.generate(); //to get mandatory notes
   190         check(dc.warnings,
   199         check(dc.warnings, sourceLevel,
   191                 dc.notes,
       
   192                 new boolean[] {vararg_meth.giveUnchecked(client_meth),
   200                 new boolean[] {vararg_meth.giveUnchecked(client_meth),
   193                                vararg_meth.giveVarargs(client_meth)},
   201                                vararg_meth.giveVarargs(client_meth)},
   194                 source, xlint, suppressLevel);
   202                 source, trustMe, suppressLevelClient, suppressLevelDecl, modKind);
   195     }
   203     }
   196 
   204 
   197     static void check(Set<Warning> warnings, Set<Warning> notes, boolean[] warnArr, JavaSource source, XlintOption xlint, SuppressLevel suppressLevel) {
   205     static void check(Set<Warning> warnings, SourceLevel sourceLevel, boolean[] warnArr, JavaSource source,
       
   206             TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl, ModifierKind modKind) {
   198         boolean badOutput = false;
   207         boolean badOutput = false;
   199         for (Warning wkind : Warning.values()) {
   208         for (Warning wkind : Warning.values()) {
   200             badOutput |= (warnArr[wkind.ordinal()] && !wkind.isSuppressed(suppressLevel)) !=
   209             boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
   201                     (wkind.isEnabled(xlint, suppressLevel) ?
   210                     suppressLevelClient, suppressLevelDecl, modKind);
   202                         warnings.contains(wkind) :
   211             System.out.println("SUPPRESSED = " + isSuppressed);
   203                         notes.contains(wkind));
   212             badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != warnings.contains(wkind);
   204         }
   213         }
   205         if (badOutput) {
   214         if (badOutput) {
   206             throw new Error("invalid diagnostics for source:\n" +
   215             throw new Error("invalid diagnostics for source:\n" +
   207                     source.getCharContent(true) +
   216                     source.getCharContent(true) +
   208                     "\nOptions: " + xlint.getXlintOption() +
       
   209                     "\nExpected unchecked warning: " + warnArr[0] +
   217                     "\nExpected unchecked warning: " + warnArr[0] +
   210                     "\nExpected unsafe vararg warning: " + warnArr[1] +
   218                     "\nExpected unsafe vararg warning: " + warnArr[1] +
   211                     "\nWarnings: " + warnings +
   219                     "\nWarnings: " + warnings +
   212                     "\nNotes: " + notes);
   220                     "\nSource level: " + sourceLevel);
   213         }
   221         }
   214     }
   222     }
   215 
   223 
   216     static class JavaSource extends SimpleJavaFileObject {
   224     static class JavaSource extends SimpleJavaFileObject {
   217 
   225 
   218         String source;
   226         String source;
   219 
   227 
   220         public JavaSource(SuppressLevel suppressLevel, Signature vararg_meth, Signature client_meth) {
   228         public JavaSource(TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
       
   229                 ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
   221             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   230             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   222             String meth1 = vararg_meth.template.replace("#arity", "...");
   231             String meth1 = vararg_meth.template.replace("#arity", "...");
   223             meth1 = meth1.replace("#name", "m");
   232             meth1 = meth1.replace("#name", "m");
   224             meth1 = meth1.replace("#body", "");
   233             meth1 = meth1.replace("#body", "");
   225             meth1 = suppressLevel.getSuppressAnnotation() + meth1;
   234             meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() + modKind.mod + meth1;
   226             String meth2 = client_meth.template.replace("#arity", "");
   235             String meth2 = client_meth.template.replace("#arity", "");
   227             meth2 = meth2.replace("#name", "test");
   236             meth2 = meth2.replace("#name", "test");
   228             meth2 = meth2.replace("#body", "m(arg);");
   237             meth2 = meth2.replace("#body", "m(arg);");
       
   238             meth2 = suppressLevelClient.getSuppressAnno() + meth2;
   229             source = "import java.util.List;\n" +
   239             source = "import java.util.List;\n" +
   230                "class Test {\n" + meth1 +
   240                      "class Test {\n" + meth1 +
   231                "\n" + meth2 + "\n}\n";
   241                      "\n" + meth2 + "\n}\n";
   232         }
   242         }
   233 
   243 
   234         @Override
   244         @Override
   235         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   245         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   236             return source;
   246             return source;
   238     }
   248     }
   239 
   249 
   240     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   250     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   241 
   251 
   242         Set<Warning> warnings = new HashSet<>();
   252         Set<Warning> warnings = new HashSet<>();
   243         Set<Warning> notes = new HashSet<>();
       
   244 
   253 
   245         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   254         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   246             if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
   255             if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
   247                     diagnostic.getKind() == Diagnostic.Kind.WARNING) {
   256                     diagnostic.getKind() == Diagnostic.Kind.WARNING) {
   248                 warnings.add(diagnostic.getCode().contains("varargs") ?
   257                 if (diagnostic.getCode().contains(Warning.VARARGS.key)) {
   249                     Warning.VARARGS :
   258                     warnings.add(Warning.VARARGS);
   250                     Warning.UNCHECKED);
   259                 } else if(diagnostic.getCode().contains(Warning.UNCHECKED.key)) {
       
   260                     warnings.add(Warning.UNCHECKED);
       
   261                 }
   251             }
   262             }
   252             else if (diagnostic.getKind() == Diagnostic.Kind.NOTE) {
       
   253                 notes.add(diagnostic.getCode().contains("varargs") ?
       
   254                     Warning.VARARGS :
       
   255                     Warning.UNCHECKED);
       
   256             }
       
   257         }
   263         }
   258     }
   264     }
   259 }
   265 }