2010-12-13 23:11:00 +00:00
|
|
|
/*
|
2022-09-01 16:43:50 +00:00
|
|
|
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
|
2010-12-13 23:11:00 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
2014-07-03 22:48:23 +00:00
|
|
|
* @bug 6993978 7097436 8006694 7196160
|
2010-12-13 23:11:00 +00:00
|
|
|
* @summary Project Coin: Annotation to reduce varargs warnings
|
2013-01-23 20:57:40 +00:00
|
|
|
* temporarily workaround combo tests are causing time out in several platforms
|
2015-08-31 16:33:34 +00:00
|
|
|
* @library /tools/javac/lib
|
|
|
|
* @modules jdk.compiler/com.sun.tools.javac.api
|
2020-01-28 08:13:27 +00:00
|
|
|
* jdk.compiler/com.sun.tools.javac.file
|
2015-08-31 16:33:34 +00:00
|
|
|
* jdk.compiler/com.sun.tools.javac.util
|
|
|
|
* @build combo.ComboTestHelper
|
2013-01-23 20:57:40 +00:00
|
|
|
* @run main/othervm Warn5
|
2010-12-13 23:11:00 +00:00
|
|
|
*/
|
2013-01-23 20:57:40 +00:00
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
import java.io.IOException;
|
2011-10-17 11:54:33 +00:00
|
|
|
import java.util.EnumSet;
|
2010-12-13 23:11:00 +00:00
|
|
|
import javax.tools.Diagnostic;
|
2015-08-31 16:33:34 +00:00
|
|
|
import javax.tools.Diagnostic.Kind;
|
2010-12-13 23:11:00 +00:00
|
|
|
import javax.tools.JavaFileObject;
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
import combo.ComboInstance;
|
|
|
|
import combo.ComboParameter;
|
|
|
|
import combo.ComboTask.Result;
|
|
|
|
import combo.ComboTestHelper;
|
|
|
|
|
|
|
|
|
|
|
|
public class Warn5 extends ComboInstance<Warn5> {
|
2010-12-13 23:11:00 +00:00
|
|
|
|
|
|
|
enum XlintOption {
|
|
|
|
NONE("none"),
|
|
|
|
ALL("all");
|
|
|
|
|
|
|
|
String opt;
|
|
|
|
|
|
|
|
XlintOption(String opt) {
|
|
|
|
this.opt = opt;
|
|
|
|
}
|
|
|
|
|
|
|
|
String getXlintOption() {
|
|
|
|
return "-Xlint:" + opt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
enum TrustMe implements ComboParameter {
|
2010-12-13 23:11:00 +00:00
|
|
|
DONT_TRUST(""),
|
|
|
|
TRUST("@java.lang.SafeVarargs");
|
|
|
|
|
|
|
|
String anno;
|
|
|
|
|
|
|
|
TrustMe(String anno) {
|
|
|
|
this.anno = anno;
|
|
|
|
}
|
2015-08-31 16:33:34 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
|
|
|
return anno;
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
enum SuppressLevel implements ComboParameter {
|
2010-12-13 23:11:00 +00:00
|
|
|
NONE,
|
|
|
|
VARARGS;
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
2010-12-13 23:11:00 +00:00
|
|
|
return this == VARARGS ?
|
|
|
|
"@SuppressWarnings(\"varargs\")" :
|
|
|
|
"";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
enum ModifierKind implements ComboParameter {
|
2010-12-13 23:11:00 +00:00
|
|
|
NONE(""),
|
|
|
|
FINAL("final"),
|
2014-06-24 17:51:00 +00:00
|
|
|
STATIC("static"),
|
|
|
|
PRIVATE("private");
|
2010-12-13 23:11:00 +00:00
|
|
|
|
|
|
|
String mod;
|
|
|
|
|
|
|
|
ModifierKind(String mod) {
|
|
|
|
this.mod = mod;
|
|
|
|
}
|
2015-08-31 16:33:34 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
|
|
|
return mod;
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
enum MethodKind implements ComboParameter {
|
2010-12-13 23:11:00 +00:00
|
|
|
METHOD("void m"),
|
|
|
|
CONSTRUCTOR("Test");
|
|
|
|
|
|
|
|
String name;
|
|
|
|
|
|
|
|
MethodKind(String name) {
|
|
|
|
this.name = name;
|
|
|
|
}
|
2015-08-31 16:33:34 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
|
|
|
return name;
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2022-09-02 02:53:59 +00:00
|
|
|
// Handling of varargs warnings changed in JDK 9 compared to JDK 8
|
|
|
|
// and then remained consistent; test 8 and then current release.
|
2010-12-13 23:11:00 +00:00
|
|
|
enum SourceLevel {
|
2022-09-01 16:43:50 +00:00
|
|
|
JDK_8("8"),
|
|
|
|
LATEST(Integer.toString(javax.lang.model.SourceVersion.latest().runtimeVersion().feature()));
|
2010-12-13 23:11:00 +00:00
|
|
|
|
|
|
|
String sourceKey;
|
|
|
|
|
|
|
|
SourceLevel(String sourceKey) {
|
|
|
|
this.sourceKey = sourceKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
enum SignatureKind implements ComboParameter {
|
|
|
|
VARARGS_X("<X>#{NAME}(X... x)", false, true),
|
|
|
|
VARARGS_STRING("#{NAME}(String... x)", true, true),
|
|
|
|
ARRAY_X("<X>#{NAME}(X[] x)", false, false),
|
|
|
|
ARRAY_STRING("#{NAME}(String[] x)", true, false);
|
2010-12-13 23:11:00 +00:00
|
|
|
|
|
|
|
String stub;
|
|
|
|
boolean isReifiableArg;
|
|
|
|
boolean isVarargs;
|
|
|
|
|
|
|
|
SignatureKind(String stub, boolean isReifiableArg, boolean isVarargs) {
|
|
|
|
this.stub = stub;
|
|
|
|
this.isReifiableArg = isReifiableArg;
|
|
|
|
this.isVarargs = isVarargs;
|
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
|
|
|
return stub;
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-02 02:53:59 +00:00
|
|
|
// javac does not currently perform analysis of the method body
|
|
|
|
// with respect to the validity of the @SafeVargs annotation. If
|
|
|
|
// that changes, the body tests should be expanded.
|
2015-08-31 16:33:34 +00:00
|
|
|
enum BodyKind implements ComboParameter {
|
2022-09-02 02:53:59 +00:00
|
|
|
// ASSIGN("Object o = x;", true),
|
|
|
|
// CAST("Object o = (Object)x;", true),
|
2010-12-13 23:11:00 +00:00
|
|
|
METH("test(x);", true),
|
|
|
|
PRINT("System.out.println(x.toString());", false),
|
2022-09-02 02:53:59 +00:00
|
|
|
// ARRAY_ASSIGN("Object[] o = x;", true),
|
2010-12-13 23:11:00 +00:00
|
|
|
ARRAY_CAST("Object[] o = (Object[])x;", true),
|
|
|
|
ARRAY_METH("testArr(x);", true);
|
|
|
|
|
|
|
|
String body;
|
|
|
|
boolean hasAliasing;
|
|
|
|
|
|
|
|
BodyKind(String body, boolean hasAliasing) {
|
|
|
|
this.body = body;
|
|
|
|
this.hasAliasing = hasAliasing;
|
|
|
|
}
|
2015-08-31 16:33:34 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String expand(String optParameter) {
|
|
|
|
return body;
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2011-10-17 11:54:33 +00:00
|
|
|
enum WarningKind {
|
2015-08-31 16:33:34 +00:00
|
|
|
UNSAFE_BODY("compiler.warn.varargs.unsafe.use.varargs.param"),
|
|
|
|
UNSAFE_DECL("compiler.warn.unchecked.varargs.non.reifiable.type"),
|
|
|
|
MALFORMED_SAFEVARARGS("compiler.err.varargs.invalid.trustme.anno"),
|
|
|
|
REDUNDANT_SAFEVARARGS("compiler.warn.varargs.redundant.trustme.anno");
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
String code;
|
|
|
|
|
|
|
|
WarningKind(String code) {
|
|
|
|
this.code = code;
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
2015-08-31 16:33:34 +00:00
|
|
|
}
|
2013-01-08 13:47:57 +00:00
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
public static void main(String[] args) {
|
|
|
|
new ComboTestHelper<Warn5>()
|
|
|
|
.withFilter(Warn5::badTestFilter)
|
|
|
|
.withDimension("SOURCE", (x, level) -> x.sourceLevel = level, SourceLevel.values())
|
|
|
|
.withDimension("LINT", (x, lint) -> x.xlint = lint, XlintOption.values())
|
|
|
|
.withDimension("TRUSTME", (x, trustme) -> x.trustMe = trustme, TrustMe.values())
|
|
|
|
.withDimension("SUPPRESS", (x, suppress) -> x.suppressLevel = suppress, SuppressLevel.values())
|
|
|
|
.withDimension("MOD", (x, mod) -> x.modKind = mod, ModifierKind.values())
|
|
|
|
.withDimension("NAME", (x, name) -> x.methKind = name, MethodKind.values())
|
|
|
|
.withDimension("SIG", (x, sig) -> x.sig = sig, SignatureKind.values())
|
|
|
|
.withDimension("BODY", (x, body) -> x.body = body, BodyKind.values())
|
|
|
|
.run(Warn5::new);
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
SourceLevel sourceLevel;
|
|
|
|
XlintOption xlint;
|
|
|
|
TrustMe trustMe;
|
|
|
|
SuppressLevel suppressLevel;
|
|
|
|
ModifierKind modKind;
|
|
|
|
MethodKind methKind;
|
|
|
|
SignatureKind sig;
|
|
|
|
BodyKind body;
|
|
|
|
|
|
|
|
boolean badTestFilter() {
|
|
|
|
return (methKind != MethodKind.CONSTRUCTOR || modKind == ModifierKind.NONE);
|
2011-10-17 11:54:33 +00:00
|
|
|
}
|
2011-02-24 16:40:49 +00:00
|
|
|
|
2022-09-02 02:53:59 +00:00
|
|
|
String template = """
|
|
|
|
import com.sun.tols.javac.api.*;
|
|
|
|
import java.util.List;
|
|
|
|
class Test {
|
|
|
|
static void test(Object o) {}
|
|
|
|
static void testArr(Object[] o) {}
|
|
|
|
#{TRUSTME} #{SUPPRESS} #{MOD} #{SIG} { #{BODY} }
|
|
|
|
}
|
|
|
|
""";
|
2015-08-31 16:33:34 +00:00
|
|
|
|
2013-01-08 13:47:57 +00:00
|
|
|
@Override
|
2015-08-31 16:33:34 +00:00
|
|
|
public void doWork() throws IOException {
|
2017-09-01 12:04:20 +00:00
|
|
|
newCompilationTask()
|
2015-08-31 16:33:34 +00:00
|
|
|
.withOption(xlint.getXlintOption())
|
2022-09-01 16:43:50 +00:00
|
|
|
.withOption("--release")
|
2015-08-31 16:33:34 +00:00
|
|
|
.withOption(sourceLevel.sourceKey)
|
|
|
|
.withSourceFromTemplate(template)
|
2017-09-01 12:04:20 +00:00
|
|
|
.analyze(this::check);
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
void check(Result<?> res) {
|
|
|
|
|
|
|
|
EnumSet<WarningKind> foundWarnings = EnumSet.noneOf(WarningKind.class);
|
|
|
|
for (Diagnostic.Kind kind : new Kind[] { Kind.ERROR, Kind.MANDATORY_WARNING, Kind.WARNING}) {
|
|
|
|
for (Diagnostic<? extends JavaFileObject> diag : res.diagnosticsForKind(kind)) {
|
|
|
|
for (WarningKind wk : WarningKind.values()) {
|
|
|
|
if (wk.code.equals(diag.getCode())) {
|
|
|
|
foundWarnings.add(wk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2013-01-08 13:47:57 +00:00
|
|
|
EnumSet<WarningKind> expectedWarnings =
|
|
|
|
EnumSet.noneOf(WarningKind.class);
|
2011-10-17 11:54:33 +00:00
|
|
|
|
2022-09-01 16:43:50 +00:00
|
|
|
if (trustMe == TrustMe.TRUST &&
|
|
|
|
suppressLevel != SuppressLevel.VARARGS &&
|
|
|
|
xlint != XlintOption.NONE &&
|
|
|
|
sig.isVarargs &&
|
|
|
|
!sig.isReifiableArg &&
|
|
|
|
body.hasAliasing &&
|
|
|
|
(methKind == MethodKind.CONSTRUCTOR ||
|
|
|
|
(methKind == MethodKind.METHOD &&
|
|
|
|
modKind == ModifierKind.FINAL || modKind == ModifierKind.STATIC ||
|
2022-09-02 02:53:59 +00:00
|
|
|
(modKind == ModifierKind.PRIVATE && sourceLevel.compareTo(SourceLevel.JDK_8) > 0)))) {
|
2011-10-17 11:54:33 +00:00
|
|
|
expectedWarnings.add(WarningKind.UNSAFE_BODY);
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2022-09-01 16:43:50 +00:00
|
|
|
if (trustMe == TrustMe.DONT_TRUST &&
|
|
|
|
sig.isVarargs &&
|
|
|
|
!sig.isReifiableArg &&
|
|
|
|
xlint == XlintOption.ALL) {
|
2011-10-17 11:54:33 +00:00
|
|
|
expectedWarnings.add(WarningKind.UNSAFE_DECL);
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2022-09-01 16:43:50 +00:00
|
|
|
if (trustMe == TrustMe.TRUST &&
|
|
|
|
(!sig.isVarargs ||
|
|
|
|
((modKind == ModifierKind.NONE ||
|
2022-09-02 02:53:59 +00:00
|
|
|
modKind == ModifierKind.PRIVATE && sourceLevel.compareTo(SourceLevel.JDK_8) <= 0 ) &&
|
2022-09-01 16:43:50 +00:00
|
|
|
methKind == MethodKind.METHOD))) {
|
2011-10-17 11:54:33 +00:00
|
|
|
expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2022-09-01 16:43:50 +00:00
|
|
|
if (trustMe == TrustMe.TRUST &&
|
|
|
|
xlint != XlintOption.NONE &&
|
|
|
|
suppressLevel != SuppressLevel.VARARGS &&
|
|
|
|
(modKind == ModifierKind.FINAL || modKind == ModifierKind.STATIC ||
|
2022-09-02 02:53:59 +00:00
|
|
|
(modKind == ModifierKind.PRIVATE && sourceLevel.compareTo(SourceLevel.JDK_8) > 0) ||
|
2022-09-01 16:43:50 +00:00
|
|
|
methKind == MethodKind.CONSTRUCTOR) &&
|
|
|
|
sig.isVarargs &&
|
|
|
|
sig.isReifiableArg) {
|
2011-10-17 11:54:33 +00:00
|
|
|
expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
|
|
|
|
}
|
2010-12-13 23:11:00 +00:00
|
|
|
|
2015-08-31 16:33:34 +00:00
|
|
|
if (!expectedWarnings.containsAll(foundWarnings) ||
|
|
|
|
!foundWarnings.containsAll(expectedWarnings)) {
|
|
|
|
fail("invalid diagnostics for source:\n" +
|
|
|
|
res.compilationInfo() +
|
2010-12-13 23:11:00 +00:00
|
|
|
"\nOptions: " + xlint.getXlintOption() +
|
2014-06-24 17:51:00 +00:00
|
|
|
"\nSource Level: " + sourceLevel +
|
2011-10-17 11:54:33 +00:00
|
|
|
"\nExpected warnings: " + expectedWarnings +
|
2015-08-31 16:33:34 +00:00
|
|
|
"\nFound warnings: " + foundWarnings);
|
2010-12-13 23:11:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|