6993978: Project Coin: Compiler support of annotation to reduce varargs warnings

Mon, 13 Dec 2010 15:11:00 -0800

author
mcimadamore
date
Mon, 13 Dec 2010 15:11:00 -0800
changeset 795
7b99f98b3035
parent 794
2f2ead61db06
child 796
a3b5b531542a
child 801
a8d3eed8e247

6993978: Project Coin: Compiler support of annotation to reduce varargs warnings
Reviewed-by: jjg, darcy

src/share/classes/com/sun/tools/javac/code/Source.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Symtab.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Infer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/MemberEnter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/resources/compiler.properties file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/List.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/Warner.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/CheckExamples.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/RunExamples.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/TrustMeOnNonVarargsMeth.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/TrustMeOnReifiableVarargsParam.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/TrustMeOnVirtualMethod.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/UncheckedGenericArrayCreation.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/UnsafeUseOfVarargsParam.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsFilename.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsFilenameAdditional.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsNonReifiableType.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsPlural/VarargsFilename.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsPlural/VarargsPlural.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsFilename.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPlural.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPluralAdditional.java file | annotate | diff | comparison | revisions
test/tools/javac/varargs/6730476/T6730476a.java file | annotate | diff | comparison | revisions
test/tools/javac/varargs/6806876/T6806876.out file | annotate | diff | comparison | revisions
test/tools/javac/varargs/6993978/T6993978neg.java file | annotate | diff | comparison | revisions
test/tools/javac/varargs/6993978/T6993978neg.out file | annotate | diff | comparison | revisions
test/tools/javac/varargs/warning/Warn4.java file | annotate | diff | comparison | revisions
test/tools/javac/varargs/warning/Warn5.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 13 14:08:01 2010 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 13 15:11:00 2010 -0800
     1.3 @@ -177,6 +177,9 @@
     1.4      public boolean allowStringsInSwitch() {
     1.5          return compareTo(JDK1_7) >= 0;
     1.6      }
     1.7 +    public boolean allowSimplifiedVarargs() {
     1.8 +        return compareTo(JDK1_7) >= 0;
     1.9 +    }
    1.10      public static SourceVersion toSourceVersion(Source source) {
    1.11          switch(source) {
    1.12          case JDK1_2:
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Dec 13 14:08:01 2010 -0800
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Dec 13 15:11:00 2010 -0800
     2.3 @@ -154,6 +154,7 @@
     2.4      public final Type proprietaryType;
     2.5      public final Type systemType;
     2.6      public final Type autoCloseableType;
     2.7 +    public final Type trustMeType;
     2.8  
     2.9      /** The symbol representing the length field of an array.
    2.10       */
    2.11 @@ -461,6 +462,7 @@
    2.12                               new MethodType(List.<Type>nil(), voidType,
    2.13                                              List.of(exceptionType), methodClass),
    2.14                               autoCloseableType.tsym);
    2.15 +        trustMeType = enterClass("java.lang.SafeVarargs");
    2.16  
    2.17          synthesizeEmptyInterfaceIfMissing(cloneableType);
    2.18          synthesizeEmptyInterfaceIfMissing(serializableType);
     3.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 13 14:08:01 2010 -0800
     3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 13 15:11:00 2010 -0800
     3.3 @@ -754,6 +754,10 @@
     3.4              return (ARRAY << 5) + elemtype.hashCode();
     3.5          }
     3.6  
     3.7 +        public boolean isVarargs() {
     3.8 +            return false;
     3.9 +        }
    3.10 +
    3.11          public List<Type> allparams() { return elemtype.allparams(); }
    3.12  
    3.13          public boolean isErroneous() {
    3.14 @@ -768,6 +772,15 @@
    3.15              return elemtype.isRaw();
    3.16          }
    3.17  
    3.18 +        public ArrayType makeVarargs() {
    3.19 +            return new ArrayType(elemtype, tsym) {
    3.20 +                @Override
    3.21 +                public boolean isVarargs() {
    3.22 +                    return true;
    3.23 +                }
    3.24 +            };
    3.25 +        }
    3.26 +
    3.27          public Type map(Mapping f) {
    3.28              Type elemtype1 = f.apply(elemtype);
    3.29              if (elemtype1 == elemtype) return this;
     4.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 14:08:01 2010 -0800
     4.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 15:11:00 2010 -0800
     4.3 @@ -33,6 +33,7 @@
     4.4  
     4.5  import com.sun.tools.javac.jvm.ClassReader;
     4.6  import com.sun.tools.javac.code.Attribute.RetentionPolicy;
     4.7 +import com.sun.tools.javac.code.Lint.LintCategory;
     4.8  import com.sun.tools.javac.comp.Check;
     4.9  
    4.10  import static com.sun.tools.javac.code.Type.*;
    4.11 @@ -272,13 +273,36 @@
    4.12      public boolean isConvertible(Type t, Type s, Warner warn) {
    4.13          boolean tPrimitive = t.isPrimitive();
    4.14          boolean sPrimitive = s.isPrimitive();
    4.15 -        if (tPrimitive == sPrimitive)
    4.16 +        if (tPrimitive == sPrimitive) {
    4.17 +            checkUnsafeVarargsConversion(t, s, warn);
    4.18              return isSubtypeUnchecked(t, s, warn);
    4.19 +        }
    4.20          if (!allowBoxing) return false;
    4.21          return tPrimitive
    4.22              ? isSubtype(boxedClass(t).type, s)
    4.23              : isSubtype(unboxedType(t), s);
    4.24      }
    4.25 +    //where
    4.26 +    private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
    4.27 +        if (t.tag != ARRAY || isReifiable(t)) return;
    4.28 +        ArrayType from = (ArrayType)t;
    4.29 +        boolean shouldWarn = false;
    4.30 +        switch (s.tag) {
    4.31 +            case ARRAY:
    4.32 +                ArrayType to = (ArrayType)s;
    4.33 +                shouldWarn = from.isVarargs() &&
    4.34 +                        !to.isVarargs() &&
    4.35 +                        !isReifiable(from);
    4.36 +                break;
    4.37 +            case CLASS:
    4.38 +                shouldWarn = from.isVarargs() &&
    4.39 +                        isSubtype(from, s);
    4.40 +                break;
    4.41 +        }
    4.42 +        if (shouldWarn) {
    4.43 +            warn.warn(LintCategory.VARARGS);
    4.44 +        }
    4.45 +    }
    4.46  
    4.47      /**
    4.48       * Is t a subtype of or convertiable via boxing/unboxing
    4.49 @@ -301,9 +325,18 @@
    4.50       */
    4.51      public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
    4.52          if (t.tag == ARRAY && s.tag == ARRAY) {
    4.53 -            return (((ArrayType)t).elemtype.tag <= lastBaseTag)
    4.54 -                ? isSameType(elemtype(t), elemtype(s))
    4.55 -                : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
    4.56 +            if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
    4.57 +                return isSameType(elemtype(t), elemtype(s));
    4.58 +            } else {
    4.59 +                ArrayType from = (ArrayType)t;
    4.60 +                ArrayType to = (ArrayType)s;
    4.61 +                if (from.isVarargs() &&
    4.62 +                        !to.isVarargs() &&
    4.63 +                        !isReifiable(from)) {
    4.64 +                    warn.warn(LintCategory.VARARGS);
    4.65 +                }
    4.66 +                return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
    4.67 +            }
    4.68          } else if (isSubtype(t, s)) {
    4.69              return true;
    4.70          }
    4.71 @@ -319,9 +352,9 @@
    4.72              Type t2 = asSuper(t, s.tsym);
    4.73              if (t2 != null && t2.isRaw()) {
    4.74                  if (isReifiable(s))
    4.75 -                    warn.silentUnchecked();
    4.76 +                    warn.silentWarn(LintCategory.UNCHECKED);
    4.77                  else
    4.78 -                    warn.warnUnchecked();
    4.79 +                    warn.warn(LintCategory.UNCHECKED);
    4.80                  return true;
    4.81              }
    4.82          }
    4.83 @@ -922,6 +955,7 @@
    4.84          if (warn != warnStack.head) {
    4.85              try {
    4.86                  warnStack = warnStack.prepend(warn);
    4.87 +                checkUnsafeVarargsConversion(t, s, warn);
    4.88                  return isCastable.visit(t,s);
    4.89              } finally {
    4.90                  warnStack = warnStack.tail;
    4.91 @@ -964,7 +998,7 @@
    4.92  
    4.93                  if (s.tag == TYPEVAR) {
    4.94                      if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
    4.95 -                        warnStack.head.warnUnchecked();
    4.96 +                        warnStack.head.warn(LintCategory.UNCHECKED);
    4.97                          return true;
    4.98                      } else {
    4.99                          return false;
   4.100 @@ -980,8 +1014,8 @@
   4.101                          if (!visit(intf, s))
   4.102                              return false;
   4.103                      }
   4.104 -                    if (warnStack.head.unchecked == true)
   4.105 -                        oldWarner.warnUnchecked();
   4.106 +                    if (warnStack.head.hasLint(LintCategory.UNCHECKED))
   4.107 +                        oldWarner.warn(LintCategory.UNCHECKED);
   4.108                      return true;
   4.109                  }
   4.110  
   4.111 @@ -996,13 +1030,13 @@
   4.112                          || isSubtype(erasure(s), erasure(t))) {
   4.113                          if (!upcast && s.tag == ARRAY) {
   4.114                              if (!isReifiable(s))
   4.115 -                                warnStack.head.warnUnchecked();
   4.116 +                                warnStack.head.warn(LintCategory.UNCHECKED);
   4.117                              return true;
   4.118                          } else if (s.isRaw()) {
   4.119                              return true;
   4.120                          } else if (t.isRaw()) {
   4.121                              if (!isUnbounded(s))
   4.122 -                                warnStack.head.warnUnchecked();
   4.123 +                                warnStack.head.warn(LintCategory.UNCHECKED);
   4.124                              return true;
   4.125                          }
   4.126                          // Assume |a| <: |b|
   4.127 @@ -1035,7 +1069,7 @@
   4.128                                  && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
   4.129                                  if (upcast ? giveWarning(a, b) :
   4.130                                      giveWarning(b, a))
   4.131 -                                    warnStack.head.warnUnchecked();
   4.132 +                                    warnStack.head.warn(LintCategory.UNCHECKED);
   4.133                                  return true;
   4.134                              }
   4.135                          }
   4.136 @@ -1072,7 +1106,7 @@
   4.137                      return true;
   4.138                  case TYPEVAR:
   4.139                      if (isCastable(s, t, Warner.noWarnings)) {
   4.140 -                        warnStack.head.warnUnchecked();
   4.141 +                        warnStack.head.warn(LintCategory.UNCHECKED);
   4.142                          return true;
   4.143                      } else {
   4.144                          return false;
   4.145 @@ -1101,7 +1135,7 @@
   4.146                      if (isSubtype(t, s)) {
   4.147                          return true;
   4.148                      } else if (isCastable(t.bound, s, Warner.noWarnings)) {
   4.149 -                        warnStack.head.warnUnchecked();
   4.150 +                        warnStack.head.warn(LintCategory.UNCHECKED);
   4.151                          return true;
   4.152                      } else {
   4.153                          return false;
   4.154 @@ -2906,7 +2940,7 @@
   4.155              return true;
   4.156          if (!isSubtype(r1.getReturnType(), erasure(r2res)))
   4.157              return false;
   4.158 -        warner.warnUnchecked();
   4.159 +        warner.warn(LintCategory.UNCHECKED);
   4.160          return true;
   4.161      }
   4.162  
   4.163 @@ -3122,7 +3156,7 @@
   4.164              commonSupers = commonSupers.tail;
   4.165          }
   4.166          if (giveWarning && !isReifiable(reverse ? from : to))
   4.167 -            warn.warnUnchecked();
   4.168 +            warn.warn(LintCategory.UNCHECKED);
   4.169          if (!source.allowCovariantReturns())
   4.170              // reject if there is a common method signature with
   4.171              // incompatible return types.
   4.172 @@ -3156,7 +3190,7 @@
   4.173              chk.checkCompatibleAbstracts(warn.pos(), from, to);
   4.174          if (!isReifiable(target) &&
   4.175              (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
   4.176 -            warn.warnUnchecked();
   4.177 +            warn.warn(LintCategory.UNCHECKED);
   4.178          return true;
   4.179      }
   4.180  
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Dec 13 14:08:01 2010 -0800
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Dec 13 15:11:00 2010 -0800
     5.3 @@ -38,6 +38,7 @@
     5.4  import com.sun.tools.javac.util.List;
     5.5  
     5.6  import com.sun.tools.javac.jvm.Target;
     5.7 +import com.sun.tools.javac.code.Lint.LintCategory;
     5.8  import com.sun.tools.javac.code.Symbol.*;
     5.9  import com.sun.tools.javac.tree.JCTree.*;
    5.10  import com.sun.tools.javac.code.Type.*;
    5.11 @@ -669,6 +670,7 @@
    5.12  
    5.13          Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
    5.14          Lint prevLint = chk.setLint(lint);
    5.15 +        MethodSymbol prevMethod = chk.setMethod(m);
    5.16          try {
    5.17              chk.checkDeprecatedAnnotation(tree.pos(), m);
    5.18  
    5.19 @@ -700,7 +702,7 @@
    5.20                  attribStat(l.head, localEnv);
    5.21              }
    5.22  
    5.23 -            chk.checkVarargMethodDecl(tree);
    5.24 +            chk.checkVarargsMethodDecl(localEnv, tree);
    5.25  
    5.26              // Check that type parameters are well-formed.
    5.27              chk.validate(tree.typarams, localEnv);
    5.28 @@ -789,6 +791,7 @@
    5.29          }
    5.30          finally {
    5.31              chk.setLint(prevLint);
    5.32 +            chk.setMethod(prevMethod);
    5.33          }
    5.34      }
    5.35  
    5.36 @@ -2272,8 +2275,8 @@
    5.37                  ((VarSymbol)sitesym).isResourceVariable() &&
    5.38                  sym.kind == MTH &&
    5.39                  sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
    5.40 -                env.info.lint.isEnabled(Lint.LintCategory.TRY)) {
    5.41 -            log.warning(Lint.LintCategory.TRY, tree, "try.explicit.close.call");
    5.42 +                env.info.lint.isEnabled(LintCategory.TRY)) {
    5.43 +            log.warning(LintCategory.TRY, tree, "try.explicit.close.call");
    5.44          }
    5.45  
    5.46          // Disallow selecting a type from an expression
    5.47 @@ -2700,7 +2703,7 @@
    5.48          // For methods, we need to compute the instance type by
    5.49          // Resolve.instantiate from the symbol's type as well as
    5.50          // any type arguments and value arguments.
    5.51 -        noteWarner.warned = false;
    5.52 +        noteWarner.clear();
    5.53          Type owntype = rs.instantiate(env,
    5.54                                        site,
    5.55                                        sym,
    5.56 @@ -2709,7 +2712,7 @@
    5.57                                        true,
    5.58                                        useVarargs,
    5.59                                        noteWarner);
    5.60 -        boolean warned = noteWarner.warned;
    5.61 +        boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
    5.62  
    5.63          // If this fails, something went wrong; we should not have
    5.64          // found the identifier in the first place.
    5.65 @@ -2734,7 +2737,7 @@
    5.66                  JCTree arg = args.head;
    5.67                  Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
    5.68                  assertConvertible(arg, arg.type, formals.head, warn);
    5.69 -                warned |= warn.warned;
    5.70 +                warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
    5.71                  args = args.tail;
    5.72                  formals = formals.tail;
    5.73              }
    5.74 @@ -2744,7 +2747,7 @@
    5.75                      JCTree arg = args.head;
    5.76                      Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
    5.77                      assertConvertible(arg, arg.type, varArg, warn);
    5.78 -                    warned |= warn.warned;
    5.79 +                    warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
    5.80                      args = args.tail;
    5.81                  }
    5.82              } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
    5.83 @@ -2776,7 +2779,7 @@
    5.84                  JCTree tree = env.tree;
    5.85                  Type argtype = owntype.getParameterTypes().last();
    5.86                  if (owntype.getReturnType().tag != FORALL || warned) {
    5.87 -                    chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym, env);
    5.88 +                    chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
    5.89                  }
    5.90                  Type elemtype = types.elemtype(argtype);
    5.91                  switch (tree.getTag()) {
    5.92 @@ -3175,7 +3178,7 @@
    5.93          chk.checkNonCyclicElements(tree);
    5.94  
    5.95          // Check for proper use of serialVersionUID
    5.96 -        if (env.info.lint.isEnabled(Lint.LintCategory.SERIAL) &&
    5.97 +        if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
    5.98              isSerializable(c) &&
    5.99              (c.flags() & Flags.ENUM) == 0 &&
   5.100              (c.flags() & ABSTRACT) == 0) {
   5.101 @@ -3204,7 +3207,7 @@
   5.102              Scope.Entry e = c.members().lookup(names.serialVersionUID);
   5.103              while (e.scope != null && e.sym.kind != VAR) e = e.next();
   5.104              if (e.scope == null) {
   5.105 -                log.warning(Lint.LintCategory.SERIAL,
   5.106 +                log.warning(LintCategory.SERIAL,
   5.107                          tree.pos(), "missing.SVUID", c);
   5.108                  return;
   5.109              }
   5.110 @@ -3213,17 +3216,17 @@
   5.111              VarSymbol svuid = (VarSymbol)e.sym;
   5.112              if ((svuid.flags() & (STATIC | FINAL)) !=
   5.113                  (STATIC | FINAL))
   5.114 -                log.warning(Lint.LintCategory.SERIAL,
   5.115 +                log.warning(LintCategory.SERIAL,
   5.116                          TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
   5.117  
   5.118              // check that it is long
   5.119              else if (svuid.type.tag != TypeTags.LONG)
   5.120 -                log.warning(Lint.LintCategory.SERIAL,
   5.121 +                log.warning(LintCategory.SERIAL,
   5.122                          TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
   5.123  
   5.124              // check constant
   5.125              else if (svuid.getConstValue() == null)
   5.126 -                log.warning(Lint.LintCategory.SERIAL,
   5.127 +                log.warning(LintCategory.SERIAL,
   5.128                          TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c);
   5.129          }
   5.130  
     6.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Dec 13 14:08:01 2010 -0800
     6.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Dec 13 15:11:00 2010 -0800
     6.3 @@ -75,6 +75,10 @@
     6.4      // visits all the various parts of the trees during attribution.
     6.5      private Lint lint;
     6.6  
     6.7 +    // The method being analyzed in Attr - it is set/reset as needed by
     6.8 +    // Attr as it visits new method declarations.
     6.9 +    private MethodSymbol method;
    6.10 +
    6.11      public static Check instance(Context context) {
    6.12          Check instance = context.get(checkKey);
    6.13          if (instance == null)
    6.14 @@ -100,6 +104,7 @@
    6.15          allowGenerics = source.allowGenerics();
    6.16          allowAnnotations = source.allowAnnotations();
    6.17          allowCovariantReturns = source.allowCovariantReturns();
    6.18 +        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
    6.19          complexInference = options.isSet(COMPLEXINFERENCE);
    6.20          skipAnnotations = options.isSet("skipAnnotations");
    6.21          warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
    6.22 @@ -136,6 +141,10 @@
    6.23       */
    6.24      boolean allowCovariantReturns;
    6.25  
    6.26 +    /** Switch: simplified varargs enabled?
    6.27 +     */
    6.28 +    boolean allowSimplifiedVarargs;
    6.29 +
    6.30      /** Switch: -complexinference option set?
    6.31       */
    6.32      boolean complexInference;
    6.33 @@ -175,6 +184,12 @@
    6.34          return prev;
    6.35      }
    6.36  
    6.37 +    MethodSymbol setMethod(MethodSymbol newMethod) {
    6.38 +        MethodSymbol prev = method;
    6.39 +        method = newMethod;
    6.40 +        return prev;
    6.41 +    }
    6.42 +
    6.43      /** Warn about deprecated symbol.
    6.44       *  @param pos        Position to be used for error reporting.
    6.45       *  @param sym        The deprecated symbol.
    6.46 @@ -197,9 +212,9 @@
    6.47       *  @param pos        Position to be used for error reporting.
    6.48       *  @param sym        The deprecated symbol.
    6.49       */
    6.50 -    void warnUnsafeVararg(DiagnosticPosition pos, Type elemType) {
    6.51 -        if (!lint.isSuppressed(LintCategory.VARARGS))
    6.52 -            unsafeVarargsHandler.report(pos, "varargs.non.reifiable.type", elemType);
    6.53 +    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
    6.54 +        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
    6.55 +            log.warning(LintCategory.VARARGS, pos, key, args);
    6.56      }
    6.57  
    6.58      /** Warn about using proprietary API.
    6.59 @@ -222,7 +237,6 @@
    6.60      public void reportDeferredDiagnostics() {
    6.61          deprecationHandler.reportDeferredDiagnostic();
    6.62          uncheckedHandler.reportDeferredDiagnostic();
    6.63 -        unsafeVarargsHandler.reportDeferredDiagnostic();
    6.64          sunApiHandler.reportDeferredDiagnostic();
    6.65      }
    6.66  
    6.67 @@ -705,29 +719,56 @@
    6.68          }
    6.69      }
    6.70  
    6.71 -    void checkVarargMethodDecl(JCMethodDecl tree) {
    6.72 +    void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
    6.73          MethodSymbol m = tree.sym;
    6.74 -        //check the element type of the vararg
    6.75 +        if (!allowSimplifiedVarargs) return;
    6.76 +        boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
    6.77 +        Type varargElemType = null;
    6.78          if (m.isVarArgs()) {
    6.79 -            Type varargElemType = types.elemtype(tree.params.last().type);
    6.80 -            if (!types.isReifiable(varargElemType)) {
    6.81 -                warnUnsafeVararg(tree.params.head.pos(), varargElemType);
    6.82 +            varargElemType = types.elemtype(tree.params.last().type);
    6.83 +        }
    6.84 +        if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
    6.85 +            if (varargElemType != null) {
    6.86 +                log.error(tree,
    6.87 +                        "varargs.invalid.trustme.anno",
    6.88 +                        syms.trustMeType.tsym,
    6.89 +                        diags.fragment("varargs.trustme.on.virtual.varargs", m));
    6.90 +            } else {
    6.91 +                log.error(tree,
    6.92 +                            "varargs.invalid.trustme.anno",
    6.93 +                            syms.trustMeType.tsym,
    6.94 +                            diags.fragment("varargs.trustme.on.non.varargs.meth", m));
    6.95              }
    6.96 +        } else if (hasTrustMeAnno && varargElemType != null &&
    6.97 +                            types.isReifiable(varargElemType)) {
    6.98 +            warnUnsafeVararg(tree,
    6.99 +                            "varargs.redundant.trustme.anno",
   6.100 +                            syms.trustMeType.tsym,
   6.101 +                            diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType));
   6.102 +        }
   6.103 +        else if (!hasTrustMeAnno && varargElemType != null &&
   6.104 +                !types.isReifiable(varargElemType)) {
   6.105 +            warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
   6.106          }
   6.107      }
   6.108 +    //where
   6.109 +        private boolean isTrustMeAllowedOnMethod(Symbol s) {
   6.110 +            return (s.flags() & VARARGS) != 0 &&
   6.111 +                (s.isConstructor() ||
   6.112 +                    (s.flags() & (STATIC | FINAL)) != 0);
   6.113 +        }
   6.114  
   6.115      /**
   6.116       * Check that vararg method call is sound
   6.117       * @param pos Position to be used for error reporting.
   6.118       * @param argtypes Actual arguments supplied to vararg method.
   6.119       */
   6.120 -    void checkVararg(DiagnosticPosition pos, List<Type> argtypes, Symbol msym, Env<AttrContext> env) {
   6.121 -        Env<AttrContext> calleeLintEnv = env;
   6.122 -        while (calleeLintEnv.info.lint == null)
   6.123 -            calleeLintEnv = calleeLintEnv.next;
   6.124 -        Lint calleeLint = calleeLintEnv.info.lint.augment(msym.attributes_field, msym.flags());
   6.125 +    void checkVararg(DiagnosticPosition pos, List<Type> argtypes, Symbol msym) {
   6.126          Type argtype = argtypes.last();
   6.127 -        if (!types.isReifiable(argtype) && !calleeLint.isSuppressed(Lint.LintCategory.VARARGS)) {
   6.128 +        if (!types.isReifiable(argtype) &&
   6.129 +                (!allowSimplifiedVarargs ||
   6.130 +                msym.attribute(syms.trustMeType.tsym) == null ||
   6.131 +                !isTrustMeAllowedOnMethod(msym))) {
   6.132              warnUnchecked(pos,
   6.133                                "unchecked.generic.array.creation",
   6.134                                argtype);
   6.135 @@ -1075,12 +1116,12 @@
   6.136          }
   6.137  
   6.138          void checkRaw(JCTree tree, Env<AttrContext> env) {
   6.139 -            if (lint.isEnabled(Lint.LintCategory.RAW) &&
   6.140 +            if (lint.isEnabled(LintCategory.RAW) &&
   6.141                  tree.type.tag == CLASS &&
   6.142                  !TreeInfo.isDiamond(tree) &&
   6.143                  !env.enclClass.name.isEmpty() &&  //anonymous or intersection
   6.144                  tree.type.isRaw()) {
   6.145 -                log.warning(Lint.LintCategory.RAW,
   6.146 +                log.warning(LintCategory.RAW,
   6.147                          tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
   6.148              }
   6.149          }
   6.150 @@ -1347,7 +1388,7 @@
   6.151          Type mtres = mt.getReturnType();
   6.152          Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
   6.153  
   6.154 -        overrideWarner.warned = false;
   6.155 +        overrideWarner.clear();
   6.156          boolean resultTypesOK =
   6.157              types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
   6.158          if (!resultTypesOK) {
   6.159 @@ -1362,7 +1403,7 @@
   6.160                            mtres, otres);
   6.161                  return;
   6.162              }
   6.163 -        } else if (overrideWarner.warned) {
   6.164 +        } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
   6.165              warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
   6.166                      "override.unchecked.ret",
   6.167                      uncheckedOverrides(m, other),
   6.168 @@ -1391,7 +1432,7 @@
   6.169  
   6.170          // Optional warning if varargs don't agree
   6.171          if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
   6.172 -            && lint.isEnabled(Lint.LintCategory.OVERRIDES)) {
   6.173 +            && lint.isEnabled(LintCategory.OVERRIDES)) {
   6.174              log.warning(TreeInfo.diagnosticPositionFor(m, tree),
   6.175                          ((m.flags() & Flags.VARARGS) != 0)
   6.176                          ? "override.varargs.missing"
   6.177 @@ -2380,11 +2421,11 @@
   6.178  
   6.179      void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
   6.180          if (allowAnnotations &&
   6.181 -            lint.isEnabled(Lint.LintCategory.DEP_ANN) &&
   6.182 +            lint.isEnabled(LintCategory.DEP_ANN) &&
   6.183              (s.flags() & DEPRECATED) != 0 &&
   6.184              !syms.deprecatedType.isErroneous() &&
   6.185              s.attribute(syms.deprecatedType.tsym) == null) {
   6.186 -            log.warning(Lint.LintCategory.DEP_ANN,
   6.187 +            log.warning(LintCategory.DEP_ANN,
   6.188                      pos, "missing.deprecated.annotation");
   6.189          }
   6.190      }
   6.191 @@ -2530,13 +2571,13 @@
   6.192       */
   6.193      void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
   6.194          if (operand.constValue() != null
   6.195 -            && lint.isEnabled(Lint.LintCategory.DIVZERO)
   6.196 +            && lint.isEnabled(LintCategory.DIVZERO)
   6.197              && operand.tag <= LONG
   6.198              && ((Number) (operand.constValue())).longValue() == 0) {
   6.199              int opc = ((OperatorSymbol)operator).opcode;
   6.200              if (opc == ByteCodes.idiv || opc == ByteCodes.imod
   6.201                  || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
   6.202 -                log.warning(Lint.LintCategory.DIVZERO, pos, "div.zero");
   6.203 +                log.warning(LintCategory.DIVZERO, pos, "div.zero");
   6.204              }
   6.205          }
   6.206      }
   6.207 @@ -2545,8 +2586,8 @@
   6.208       * Check for empty statements after if
   6.209       */
   6.210      void checkEmptyIf(JCIf tree) {
   6.211 -        if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(Lint.LintCategory.EMPTY))
   6.212 -            log.warning(Lint.LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
   6.213 +        if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(LintCategory.EMPTY))
   6.214 +            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
   6.215      }
   6.216  
   6.217      /** Check that symbol is unique in given scope.
   6.218 @@ -2654,23 +2695,36 @@
   6.219          }
   6.220  
   6.221      private class ConversionWarner extends Warner {
   6.222 -        final String key;
   6.223 +        final String uncheckedKey;
   6.224          final Type found;
   6.225          final Type expected;
   6.226 -        public ConversionWarner(DiagnosticPosition pos, String key, Type found, Type expected) {
   6.227 +        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
   6.228              super(pos);
   6.229 -            this.key = key;
   6.230 +            this.uncheckedKey = uncheckedKey;
   6.231              this.found = found;
   6.232              this.expected = expected;
   6.233          }
   6.234  
   6.235          @Override
   6.236 -        public void warnUnchecked() {
   6.237 +        public void warn(LintCategory lint) {
   6.238              boolean warned = this.warned;
   6.239 -            super.warnUnchecked();
   6.240 +            super.warn(lint);
   6.241              if (warned) return; // suppress redundant diagnostics
   6.242 -            Object problem = diags.fragment(key);
   6.243 -            Check.this.warnUnchecked(pos(), "prob.found.req", problem, found, expected);
   6.244 +            switch (lint) {
   6.245 +                case UNCHECKED:
   6.246 +                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
   6.247 +                    break;
   6.248 +                case VARARGS:
   6.249 +                    if (method != null &&
   6.250 +                            method.attribute(syms.trustMeType.tsym) != null &&
   6.251 +                            isTrustMeAllowedOnMethod(method) &&
   6.252 +                            !types.isReifiable(method.type.getParameterTypes().last())) {
   6.253 +                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
   6.254 +                    }
   6.255 +                    break;
   6.256 +                default:
   6.257 +                    throw new AssertionError("Unexpected lint: " + lint);
   6.258 +            }
   6.259          }
   6.260      }
   6.261  
     7.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Dec 13 14:08:01 2010 -0800
     7.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Dec 13 15:11:00 2010 -0800
     7.3 @@ -481,7 +481,7 @@
     7.4                      checkWithinBounds(all_tvars,
     7.5                             types.subst(inferredTypes, tvars, inferred), warn);
     7.6                      if (useVarargs) {
     7.7 -                        chk.checkVararg(env.tree.pos(), formals, msym, env);
     7.8 +                        chk.checkVararg(env.tree.pos(), formals, msym);
     7.9                      }
    7.10                      return super.inst(inferred, types);
    7.11              }};
     8.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Dec 13 14:08:01 2010 -0800
     8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Dec 13 15:11:00 2010 -0800
     8.3 @@ -77,6 +77,7 @@
     8.4      private final Target target;
     8.5  
     8.6      private final boolean skipAnnotations;
     8.7 +    private final boolean allowSimplifiedVarargs;
     8.8  
     8.9      public static MemberEnter instance(Context context) {
    8.10          MemberEnter instance = context.get(memberEnterKey);
    8.11 @@ -103,6 +104,8 @@
    8.12          target = Target.instance(context);
    8.13          Options options = Options.instance(context);
    8.14          skipAnnotations = options.isSet("skipAnnotations");
    8.15 +        Source source = Source.instance(context);
    8.16 +        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
    8.17      }
    8.18  
    8.19      /** A queue for classes whose members still need to be entered into the
    8.20 @@ -617,6 +620,14 @@
    8.21              localEnv.info.staticLevel++;
    8.22          }
    8.23          attr.attribType(tree.vartype, localEnv);
    8.24 +        if ((tree.mods.flags & VARARGS) != 0) {
    8.25 +            //if we are entering a varargs parameter, we need to replace its type
    8.26 +            //(a plain array type) with the more precise VarargsType --- we need
    8.27 +            //to do it this way because varargs is represented in the tree as a modifier
    8.28 +            //on the parameter declaration, and not as a distinct type of array node.
    8.29 +            ArrayType atype = (ArrayType)tree.vartype.type;
    8.30 +            tree.vartype.type = atype.makeVarargs();
    8.31 +        }
    8.32          Scope enclScope = enter.enterScope(env);
    8.33          VarSymbol v =
    8.34              new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
     9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 13 14:08:01 2010 -0800
     9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 13 15:11:00 2010 -0800
     9.3 @@ -815,13 +815,13 @@
     9.4      }
     9.5      //where
     9.6      private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
     9.7 +        noteWarner.clear();
     9.8          Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
     9.9 -        noteWarner.unchecked = false;
    9.10          return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
    9.11                               allowBoxing, false, noteWarner) != null ||
    9.12                   useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
    9.13                                             allowBoxing, true, noteWarner) != null) &&
    9.14 -                !noteWarner.unchecked;
    9.15 +                !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
    9.16      }
    9.17      //where
    9.18      private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
    10.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Dec 13 14:08:01 2010 -0800
    10.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Dec 13 15:11:00 2010 -0800
    10.3 @@ -105,10 +105,15 @@
    10.4       */
    10.5      boolean allowAnnotations;
    10.6  
    10.7 -    /** Lint option: warn about classfile issues
    10.8 +    /** Switch: allow simplified varargs.
    10.9 +     */
   10.10 +    boolean allowSimplifiedVarargs;
   10.11 +
   10.12 +   /** Lint option: warn about classfile issues
   10.13       */
   10.14      boolean lintClassfile;
   10.15  
   10.16 +
   10.17      /** Switch: preserve parameter names from the variable table.
   10.18       */
   10.19      public boolean saveParameterNames;
   10.20 @@ -279,6 +284,7 @@
   10.21          allowGenerics    = source.allowGenerics();
   10.22          allowVarargs     = source.allowVarargs();
   10.23          allowAnnotations = source.allowAnnotations();
   10.24 +        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
   10.25          saveParameterNames = options.isSet("save-parameter-names");
   10.26          cacheCompletionFailure = options.isUnset("dev");
   10.27          preferSource = "source".equals(options.get("-Xprefer"));
   10.28 @@ -1883,7 +1889,7 @@
   10.29              // instance, however, there is no reliable way to tell so
   10.30              // we never strip this$n
   10.31              if (!currentOwner.name.isEmpty())
   10.32 -                type = new MethodType(type.getParameterTypes().tail,
   10.33 +                type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
   10.34                                        type.getReturnType(),
   10.35                                        type.getThrownTypes(),
   10.36                                        syms.methodClass);
   10.37 @@ -1903,6 +1909,21 @@
   10.38          return m;
   10.39      }
   10.40  
   10.41 +    private List<Type> adjustMethodParams(long flags, List<Type> args) {
   10.42 +        boolean isVarargs = (flags & VARARGS) != 0;
   10.43 +        if (isVarargs) {
   10.44 +            Type varargsElem = args.last();
   10.45 +            ListBuffer<Type> adjustedArgs = ListBuffer.lb();
   10.46 +            for (Type t : args) {
   10.47 +                adjustedArgs.append(t != varargsElem ?
   10.48 +                    t :
   10.49 +                    ((ArrayType)t).makeVarargs());
   10.50 +            }
   10.51 +            args = adjustedArgs.toList();
   10.52 +        }
   10.53 +        return args.tail;
   10.54 +    }
   10.55 +
   10.56      /**
   10.57       * Init the parameter names array.
   10.58       * Parameter names are currently inferred from the names in the
    11.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Dec 13 14:08:01 2010 -0800
    11.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Dec 13 15:11:00 2010 -0800
    11.3 @@ -516,6 +516,15 @@
    11.4  compiler.err.var.might.be.assigned.in.loop=\
    11.5      variable {0} might be assigned in loop
    11.6  
    11.7 +compiler.err.varargs.invalid.trustme.anno=\
    11.8 +    Invalid {0} annotation. {1}
    11.9 +compiler.misc.varargs.trustme.on.reifiable.varargs=\
   11.10 +    Varargs element type {0} is reifiable.
   11.11 +compiler.misc.varargs.trustme.on.non.varargs.meth=\
   11.12 +    Method {0} is not a varargs method.
   11.13 +compiler.misc.varargs.trustme.on.virtual.varargs=\
   11.14 +    Instance method {0} is not final.
   11.15 +
   11.16  # In the following string, {1} will always be the detail message from
   11.17  # java.io.IOException.
   11.18  compiler.err.class.cant.write=\
   11.19 @@ -600,20 +609,6 @@
   11.20  compiler.note.unchecked.plural.additional=\
   11.21      Some input files additionally use unchecked or unsafe operations.
   11.22  
   11.23 -compiler.note.varargs.filename=\
   11.24 -    {0} declares unsafe vararg methods.
   11.25 -compiler.note.varargs.plural=\
   11.26 -    Some input files declare unsafe vararg methods.
   11.27 -# The following string may appear after one of the above unsafe varargs
   11.28 -# messages.
   11.29 -compiler.note.varargs.recompile=\
   11.30 -    Recompile with -Xlint:varargs for details.
   11.31 -
   11.32 -compiler.note.varargs.filename.additional=\
   11.33 -    {0} declares additional unsafe vararg methods.
   11.34 -compiler.note.varargs.plural.additional=\
   11.35 -    Some input files additionally declares unsafe vararg methods.
   11.36 -
   11.37  compiler.note.sunapi.filename=\
   11.38      {0} uses internal proprietary API that may be removed in a future release.
   11.39  compiler.note.sunapi.plural=\
   11.40 @@ -841,9 +836,12 @@
   11.41  compiler.warn.unchecked.generic.array.creation=\
   11.42      unchecked generic array creation for varargs parameter of type {0}
   11.43  
   11.44 -compiler.warn.varargs.non.reifiable.type=\
   11.45 +compiler.warn.unchecked.varargs.non.reifiable.type=\
   11.46      Possible heap pollution from parameterized vararg type {0}
   11.47  
   11.48 +compiler.warn.varargs.unsafe.use.varargs.param=\
   11.49 +    Varargs method could cause heap pollution from non-reifiable varargs parameter {0}
   11.50 +
   11.51  compiler.warn.missing.deprecated.annotation=\
   11.52      deprecated item is not annotated with @Deprecated
   11.53  
   11.54 @@ -876,6 +874,9 @@
   11.55      explicit: {0}\n\
   11.56      inferred: {1}
   11.57  
   11.58 +compiler.warn.varargs.redundant.trustme.anno=\
   11.59 +    Redundant {0} annotation. {1}
   11.60 +
   11.61  #####
   11.62  
   11.63  ## The following are tokens which are non-terminals in the language. They should
    12.1 --- a/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 13 14:08:01 2010 -0800
    12.2 +++ b/src/share/classes/com/sun/tools/javac/util/List.java	Mon Dec 13 15:11:00 2010 -0800
    12.3 @@ -103,7 +103,7 @@
    12.4  
    12.5      /** Construct a list consisting of given elements.
    12.6       */
    12.7 -    @SuppressWarnings("varargs")
    12.8 +    @SuppressWarnings({"varargs", "unchecked"})
    12.9      public static <A> List<A> of(A x1, A x2, A x3, A... rest) {
   12.10          return new List<A>(x1, new List<A>(x2, new List<A>(x3, from(rest))));
   12.11      }
    13.1 --- a/src/share/classes/com/sun/tools/javac/util/Warner.java	Mon Dec 13 14:08:01 2010 -0800
    13.2 +++ b/src/share/classes/com/sun/tools/javac/util/Warner.java	Mon Dec 13 15:11:00 2010 -0800
    13.3 @@ -25,7 +25,9 @@
    13.4  
    13.5  package com.sun.tools.javac.util;
    13.6  
    13.7 +import com.sun.tools.javac.code.Lint.LintCategory;
    13.8  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    13.9 +import java.util.EnumSet;
   13.10  
   13.11  /**
   13.12   * An interface to support optional warnings, needed for support of
   13.13 @@ -40,25 +42,45 @@
   13.14      public static final Warner noWarnings = new Warner();
   13.15  
   13.16      private DiagnosticPosition pos = null;
   13.17 -    public boolean warned = false;
   13.18 -    public boolean unchecked = false;
   13.19 +    protected boolean warned = false;
   13.20 +    private EnumSet<LintCategory> nonSilentLintSet = EnumSet.noneOf(LintCategory.class);
   13.21 +    private EnumSet<LintCategory> silentLintSet = EnumSet.noneOf(LintCategory.class);
   13.22  
   13.23      public DiagnosticPosition pos() {
   13.24          return pos;
   13.25      }
   13.26  
   13.27 -    public void warnUnchecked() {
   13.28 -        warned = true;
   13.29 -        unchecked = true;
   13.30 +    public void warn(LintCategory lint) {
   13.31 +        nonSilentLintSet.add(lint);
   13.32      }
   13.33 -    public void silentUnchecked() {
   13.34 -        unchecked = true;
   13.35 +
   13.36 +    public void silentWarn(LintCategory lint) {
   13.37 +        silentLintSet.add(lint);
   13.38      }
   13.39  
   13.40      public Warner(DiagnosticPosition pos) {
   13.41          this.pos = pos;
   13.42      }
   13.43  
   13.44 +    public boolean hasSilentLint(LintCategory lint) {
   13.45 +        return silentLintSet.contains(lint);
   13.46 +    }
   13.47 +
   13.48 +    public boolean hasNonSilentLint(LintCategory lint) {
   13.49 +        return nonSilentLintSet.contains(lint);
   13.50 +    }
   13.51 +
   13.52 +    public boolean hasLint(LintCategory lint) {
   13.53 +        return hasSilentLint(lint) ||
   13.54 +                hasNonSilentLint(lint);
   13.55 +    }
   13.56 +
   13.57 +    public void clear() {
   13.58 +        nonSilentLintSet.clear();
   13.59 +        silentLintSet.clear();
   13.60 +        this.warned = false;
   13.61 +    }
   13.62 +
   13.63      public Warner() {
   13.64          this(null);
   13.65      }
    14.1 --- a/test/tools/javac/diags/CheckExamples.java	Mon Dec 13 14:08:01 2010 -0800
    14.2 +++ b/test/tools/javac/diags/CheckExamples.java	Mon Dec 13 15:11:00 2010 -0800
    14.3 @@ -129,12 +129,17 @@
    14.4          File testSrc = new File(System.getProperty("test.src"));
    14.5          File examples = new File(testSrc, "examples");
    14.6          for (File f: examples.listFiles()) {
    14.7 -            if (f.isDirectory() || f.isFile() && f.getName().endsWith(".java"))
    14.8 +            if (isValidExample(f))
    14.9                  results.add(new Example(f));
   14.10          }
   14.11          return results;
   14.12      }
   14.13  
   14.14 +    boolean isValidExample(File f) {
   14.15 +        return (f.isDirectory() && f.list().length > 0) ||
   14.16 +                (f.isFile() && f.getName().endsWith(".java"));
   14.17 +    }
   14.18 +
   14.19      /**
   14.20       * Get the contents of the "not-yet" list.
   14.21       */
    15.1 --- a/test/tools/javac/diags/RunExamples.java	Mon Dec 13 14:08:01 2010 -0800
    15.2 +++ b/test/tools/javac/diags/RunExamples.java	Mon Dec 13 15:11:00 2010 -0800
    15.3 @@ -52,7 +52,7 @@
    15.4   */
    15.5  public class RunExamples {
    15.6      public static void main(String... args) throws Exception {
    15.7 -        boolean jtreg = (System.getProperty("test.src") != null);
    15.8 +        jtreg = (System.getProperty("test.src") != null);
    15.9          File tmpDir;
   15.10          if (jtreg) {
   15.11              // use standard jtreg scratch directory: the current directory
   15.12 @@ -166,12 +166,17 @@
   15.13      Set<Example> getExamples(File examplesDir) {
   15.14          Set<Example> results = new TreeSet<Example>();
   15.15          for (File f: examplesDir.listFiles()) {
   15.16 -            if (f.isDirectory() || f.isFile() && f.getName().endsWith(".java"))
   15.17 +            if (isValidExample(f))
   15.18                  results.add(new Example(f));
   15.19          }
   15.20          return results;
   15.21      }
   15.22  
   15.23 +    boolean isValidExample(File f) {
   15.24 +        return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
   15.25 +                (f.isFile() && f.getName().endsWith(".java"));
   15.26 +    }
   15.27 +
   15.28      /**
   15.29       * Report an error.
   15.30       */
   15.31 @@ -180,6 +185,8 @@
   15.32          errors++;
   15.33      }
   15.34  
   15.35 +    static boolean jtreg;
   15.36 +
   15.37      int errors;
   15.38  
   15.39      /**
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/javac/diags/examples/TrustMeOnNonVarargsMeth.java	Mon Dec 13 15:11:00 2010 -0800
    16.3 @@ -0,0 +1,30 @@
    16.4 +/*
    16.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +
   16.27 +// key: compiler.err.varargs.invalid.trustme.anno
   16.28 +// key: compiler.misc.varargs.trustme.on.non.varargs.meth
   16.29 +// options: -Xlint:varargs
   16.30 +
   16.31 +class TrustMeOnNonVarargsMeth {
   16.32 +    @SafeVarargs static void m(String[] args) { }
   16.33 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/tools/javac/diags/examples/TrustMeOnReifiableVarargsParam.java	Mon Dec 13 15:11:00 2010 -0800
    17.3 @@ -0,0 +1,30 @@
    17.4 +/*
    17.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.
   17.11 + *
   17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.15 + * version 2 for more details (a copy is included in the LICENSE file that
   17.16 + * accompanied this code).
   17.17 + *
   17.18 + * You should have received a copy of the GNU General Public License version
   17.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.21 + *
   17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.23 + * or visit www.oracle.com if you need additional information or have any
   17.24 + * questions.
   17.25 + */
   17.26 +
   17.27 +// key: compiler.warn.varargs.redundant.trustme.anno
   17.28 +// key: compiler.misc.varargs.trustme.on.reifiable.varargs
   17.29 +// options: -Xlint:varargs
   17.30 +
   17.31 +class TrustMeOnReifiableVarargsParam {
   17.32 +    @SafeVarargs static void m(String... args) { }
   17.33 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/tools/javac/diags/examples/TrustMeOnVirtualMethod.java	Mon Dec 13 15:11:00 2010 -0800
    18.3 @@ -0,0 +1,32 @@
    18.4 +/*
    18.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.
   18.11 + *
   18.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.15 + * version 2 for more details (a copy is included in the LICENSE file that
   18.16 + * accompanied this code).
   18.17 + *
   18.18 + * You should have received a copy of the GNU General Public License version
   18.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.21 + *
   18.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.23 + * or visit www.oracle.com if you need additional information or have any
   18.24 + * questions.
   18.25 + */
   18.26 +
   18.27 +// key: compiler.err.varargs.invalid.trustme.anno
   18.28 +// key: compiler.misc.varargs.trustme.on.virtual.varargs
   18.29 +// options: -Xlint:varargs,unchecked
   18.30 +
   18.31 +import java.util.List;
   18.32 +
   18.33 +class TrustMeOnVirtualMethod {
   18.34 +    @SafeVarargs void m(List<String>... args) { }
   18.35 +}
    19.1 --- a/test/tools/javac/diags/examples/UncheckedGenericArrayCreation.java	Mon Dec 13 14:08:01 2010 -0800
    19.2 +++ b/test/tools/javac/diags/examples/UncheckedGenericArrayCreation.java	Mon Dec 13 15:11:00 2010 -0800
    19.3 @@ -22,10 +22,8 @@
    19.4   */
    19.5  
    19.6  // key: compiler.warn.unchecked.generic.array.creation
    19.7 -// key: compiler.warn.varargs.non.reifiable.type
    19.8 -// options: -Xlint:unchecked,varargs
    19.9 -
   19.10 -import java.util.*;
   19.11 +// key: compiler.warn.unchecked.varargs.non.reifiable.type
   19.12 +// options: -Xlint:unchecked
   19.13  
   19.14  class UncheckedGenericArrayCreation<T> {
   19.15      void m(T t1, T t2, T t3) {
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/tools/javac/diags/examples/UnsafeUseOfVarargsParam.java	Mon Dec 13 15:11:00 2010 -0800
    20.3 @@ -0,0 +1,31 @@
    20.4 +/*
    20.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.
   20.11 + *
   20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.15 + * version 2 for more details (a copy is included in the LICENSE file that
   20.16 + * accompanied this code).
   20.17 + *
   20.18 + * You should have received a copy of the GNU General Public License version
   20.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.21 + *
   20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.23 + * or visit www.oracle.com if you need additional information or have any
   20.24 + * questions.
   20.25 + */
   20.26 +
   20.27 +// key: compiler.warn.varargs.unsafe.use.varargs.param
   20.28 +// options: -Xlint:varargs
   20.29 +
   20.30 +class UnsafeUseOfVarargsParam {
   20.31 +    @SafeVarargs static <X> void m(X... x) {
   20.32 +        Object[] o = x;
   20.33 +    }
   20.34 +}
    21.1 --- a/test/tools/javac/diags/examples/VarargsFilename.java	Mon Dec 13 14:08:01 2010 -0800
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,29 +0,0 @@
    21.4 -/*
    21.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    21.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 - *
    21.8 - * This code is free software; you can redistribute it and/or modify it
    21.9 - * under the terms of the GNU General Public License version 2 only, as
   21.10 - * published by the Free Software Foundation.
   21.11 - *
   21.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   21.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.15 - * version 2 for more details (a copy is included in the LICENSE file that
   21.16 - * accompanied this code).
   21.17 - *
   21.18 - * You should have received a copy of the GNU General Public License version
   21.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   21.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.21 - *
   21.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.23 - * or visit www.oracle.com if you need additional information or have any
   21.24 - * questions.
   21.25 - */
   21.26 -
   21.27 -// key: compiler.note.varargs.filename
   21.28 -// key: compiler.note.varargs.recompile
   21.29 -
   21.30 -class VarargsFilename<T> {
   21.31 -    void m(T... items) { }
   21.32 -}
    22.1 --- a/test/tools/javac/diags/examples/VarargsFilenameAdditional.java	Mon Dec 13 14:08:01 2010 -0800
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,31 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 - *
    22.8 - * This code is free software; you can redistribute it and/or modify it
    22.9 - * under the terms of the GNU General Public License version 2 only, as
   22.10 - * published by the Free Software Foundation.
   22.11 - *
   22.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   22.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.15 - * version 2 for more details (a copy is included in the LICENSE file that
   22.16 - * accompanied this code).
   22.17 - *
   22.18 - * You should have received a copy of the GNU General Public License version
   22.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   22.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.21 - *
   22.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.23 - * or visit www.oracle.com if you need additional information or have any
   22.24 - * questions.
   22.25 - */
   22.26 -
   22.27 -// key: compiler.note.varargs.filename.additional
   22.28 -// key: compiler.warn.varargs.non.reifiable.type
   22.29 -// options: -Xlint:varargs -Xmaxwarns 1
   22.30 -
   22.31 -class VarargsFilenameAdditional<T> {
   22.32 -    void m1(T... items) { }
   22.33 -    void m2(T... items) { }
   22.34 -}
    23.1 --- a/test/tools/javac/diags/examples/VarargsNonReifiableType.java	Mon Dec 13 14:08:01 2010 -0800
    23.2 +++ b/test/tools/javac/diags/examples/VarargsNonReifiableType.java	Mon Dec 13 15:11:00 2010 -0800
    23.3 @@ -21,10 +21,8 @@
    23.4   * questions.
    23.5   */
    23.6  
    23.7 -// key: compiler.warn.varargs.non.reifiable.type
    23.8 -// options: -Xlint:varargs
    23.9 -
   23.10 -import java.util.*;
   23.11 +// key: compiler.warn.unchecked.varargs.non.reifiable.type
   23.12 +// options: -Xlint:unchecked
   23.13  
   23.14  class VarargsNonReifiableType<T> {
   23.15      void m(T... items) {
    24.1 --- a/test/tools/javac/diags/examples/VarargsPlural/VarargsFilename.java	Mon Dec 13 14:08:01 2010 -0800
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,26 +0,0 @@
    24.4 -/*
    24.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    24.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 - *
    24.8 - * This code is free software; you can redistribute it and/or modify it
    24.9 - * under the terms of the GNU General Public License version 2 only, as
   24.10 - * published by the Free Software Foundation.
   24.11 - *
   24.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   24.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.15 - * version 2 for more details (a copy is included in the LICENSE file that
   24.16 - * accompanied this code).
   24.17 - *
   24.18 - * You should have received a copy of the GNU General Public License version
   24.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   24.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.21 - *
   24.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.23 - * or visit www.oracle.com if you need additional information or have any
   24.24 - * questions.
   24.25 - */
   24.26 -
   24.27 -class VarargsFilename<T> {
   24.28 -    void m(T... items) { }
   24.29 -}
    25.1 --- a/test/tools/javac/diags/examples/VarargsPlural/VarargsPlural.java	Mon Dec 13 14:08:01 2010 -0800
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,29 +0,0 @@
    25.4 -/*
    25.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    25.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 - *
    25.8 - * This code is free software; you can redistribute it and/or modify it
    25.9 - * under the terms of the GNU General Public License version 2 only, as
   25.10 - * published by the Free Software Foundation.
   25.11 - *
   25.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   25.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.15 - * version 2 for more details (a copy is included in the LICENSE file that
   25.16 - * accompanied this code).
   25.17 - *
   25.18 - * You should have received a copy of the GNU General Public License version
   25.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   25.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.21 - *
   25.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.23 - * or visit www.oracle.com if you need additional information or have any
   25.24 - * questions.
   25.25 - */
   25.26 -
   25.27 -// key: compiler.note.varargs.plural
   25.28 -// key: compiler.note.varargs.recompile
   25.29 -
   25.30 -class VarargsPlural<T> {
   25.31 -    void m(T... items) { }
   25.32 -}
    26.1 --- a/test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsFilename.java	Mon Dec 13 14:08:01 2010 -0800
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,26 +0,0 @@
    26.4 -/*
    26.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    26.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 - *
    26.8 - * This code is free software; you can redistribute it and/or modify it
    26.9 - * under the terms of the GNU General Public License version 2 only, as
   26.10 - * published by the Free Software Foundation.
   26.11 - *
   26.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   26.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.15 - * version 2 for more details (a copy is included in the LICENSE file that
   26.16 - * accompanied this code).
   26.17 - *
   26.18 - * You should have received a copy of the GNU General Public License version
   26.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   26.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.21 - *
   26.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.23 - * or visit www.oracle.com if you need additional information or have any
   26.24 - * questions.
   26.25 - */
   26.26 -
   26.27 -class VarargsFilename<T> {
   26.28 -    void m(T... items) { }
   26.29 -}
    27.1 --- a/test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPlural.java	Mon Dec 13 14:08:01 2010 -0800
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,26 +0,0 @@
    27.4 -/*
    27.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    27.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 - *
    27.8 - * This code is free software; you can redistribute it and/or modify it
    27.9 - * under the terms of the GNU General Public License version 2 only, as
   27.10 - * published by the Free Software Foundation.
   27.11 - *
   27.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   27.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.15 - * version 2 for more details (a copy is included in the LICENSE file that
   27.16 - * accompanied this code).
   27.17 - *
   27.18 - * You should have received a copy of the GNU General Public License version
   27.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   27.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.21 - *
   27.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.23 - * or visit www.oracle.com if you need additional information or have any
   27.24 - * questions.
   27.25 - */
   27.26 -
   27.27 -class VarargsPlural<T> {
   27.28 -    void m(T... items) { }
   27.29 -}
    28.1 --- a/test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPluralAdditional.java	Mon Dec 13 14:08:01 2010 -0800
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,30 +0,0 @@
    28.4 -/*
    28.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    28.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    28.7 - *
    28.8 - * This code is free software; you can redistribute it and/or modify it
    28.9 - * under the terms of the GNU General Public License version 2 only, as
   28.10 - * published by the Free Software Foundation.
   28.11 - *
   28.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   28.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   28.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   28.15 - * version 2 for more details (a copy is included in the LICENSE file that
   28.16 - * accompanied this code).
   28.17 - *
   28.18 - * You should have received a copy of the GNU General Public License version
   28.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   28.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   28.21 - *
   28.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   28.23 - * or visit www.oracle.com if you need additional information or have any
   28.24 - * questions.
   28.25 - */
   28.26 -
   28.27 -// key: compiler.note.varargs.plural.additional
   28.28 -// key: compiler.warn.varargs.non.reifiable.type
   28.29 -// options: -Xlint:varargs -Xmaxwarns 1
   28.30 -
   28.31 -class VarargsPluralAdditional<T> {
   28.32 -    void m(T... items) { }
   28.33 -}
    29.1 --- a/test/tools/javac/varargs/6730476/T6730476a.java	Mon Dec 13 14:08:01 2010 -0800
    29.2 +++ b/test/tools/javac/varargs/6730476/T6730476a.java	Mon Dec 13 15:11:00 2010 -0800
    29.3 @@ -32,6 +32,7 @@
    29.4   */
    29.5  
    29.6  class T6730476a {
    29.7 +    @SuppressWarnings("unchecked")
    29.8      <T> void f(int i, T ... x) {}
    29.9      void g() {
   29.10        f(1);
    30.1 --- a/test/tools/javac/varargs/6806876/T6806876.out	Mon Dec 13 14:08:01 2010 -0800
    30.2 +++ b/test/tools/javac/varargs/6806876/T6806876.out	Mon Dec 13 15:11:00 2010 -0800
    30.3 @@ -1,6 +1,5 @@
    30.4  T6806876.java:11:32: compiler.warn.unchecked.generic.array.creation: java.lang.Number&java.lang.Comparable<? extends java.lang.Number&java.lang.Comparable<?>>[]
    30.5 +T6806876.java:14:19: compiler.warn.unchecked.varargs.non.reifiable.type: T
    30.6  - compiler.err.warnings.and.werror
    30.7 -- compiler.note.varargs.filename: T6806876.java
    30.8 -- compiler.note.varargs.recompile
    30.9  1 error
   30.10 -1 warning
   30.11 +2 warnings
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/tools/javac/varargs/6993978/T6993978neg.java	Mon Dec 13 15:11:00 2010 -0800
    31.3 @@ -0,0 +1,17 @@
    31.4 +/*
    31.5 + * @test /nodynamiccopyright/
    31.6 + * @bug     6993978
    31.7 + * @author mcimadamore
    31.8 + * @summary  ClassCastException occurs in assignment expressions without any heap pollutions
    31.9 + * @compile/fail/ref=T6993978neg.out -Xlint:unchecked -Werror -XDrawDiagnostics T6993978neg.java
   31.10 + */
   31.11 +
   31.12 +import java.util.List;
   31.13 +
   31.14 +class T6993978neg {
   31.15 +   @SuppressWarnings({"varargs","unchecked"})
   31.16 +   static <X> void m(X... x) {  }
   31.17 +   static void test(List<String> ls) {
   31.18 +       m(ls); //compiler should still give unchecked here
   31.19 +   }
   31.20 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/tools/javac/varargs/6993978/T6993978neg.out	Mon Dec 13 15:11:00 2010 -0800
    32.3 @@ -0,0 +1,4 @@
    32.4 +T6993978neg.java:15:9: compiler.warn.unchecked.generic.array.creation: java.util.List<java.lang.String>[]
    32.5 +- compiler.err.warnings.and.werror
    32.6 +1 error
    32.7 +1 warning
    33.1 --- a/test/tools/javac/varargs/warning/Warn4.java	Mon Dec 13 14:08:01 2010 -0800
    33.2 +++ b/test/tools/javac/varargs/warning/Warn4.java	Mon Dec 13 15:11:00 2010 -0800
    33.3 @@ -23,7 +23,7 @@
    33.4  
    33.5  /**
    33.6   * @test
    33.7 - * @bug     6945418
    33.8 + * @bug     6945418 6993978
    33.9   * @summary Project Coin: Simplified Varargs Method Invocation
   33.10   * @author  mcimadamore
   33.11   * @run main Warn4
   33.12 @@ -48,96 +48,95 @@
   33.13      final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
   33.14  
   33.15      enum Warning {
   33.16 -        UNCHECKED("unchecked"),
   33.17 -        VARARGS("varargs");
   33.18 +        UNCHECKED("generic.array.creation"),
   33.19 +        VARARGS("varargs.non.reifiable.type");
   33.20  
   33.21 -        String category;
   33.22 +        String key;
   33.23  
   33.24 -        Warning(String category) {
   33.25 -            this.category = category;
   33.26 +        Warning(String key) {
   33.27 +            this.key = key;
   33.28          }
   33.29  
   33.30 -        boolean isEnabled(XlintOption xlint, SuppressLevel suppressLevel) {
   33.31 -            return Arrays.asList(xlint.enabledWarnings).contains(this);
   33.32 -        }
   33.33 +        boolean isSuppressed(TrustMe trustMe, SourceLevel source, SuppressLevel suppressLevelClient,
   33.34 +                SuppressLevel suppressLevelDecl, ModifierKind modKind) {
   33.35 +            switch(this) {
   33.36 +                case VARARGS:
   33.37 +                    return source == SourceLevel.JDK_6 ||
   33.38 +                            suppressLevelDecl == SuppressLevel.UNCHECKED ||
   33.39 +                            trustMe == TrustMe.TRUST;
   33.40 +                case UNCHECKED:
   33.41 +                    return suppressLevelClient == SuppressLevel.UNCHECKED ||
   33.42 +                        (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE && source == SourceLevel.JDK_7);
   33.43 +            }
   33.44  
   33.45 -        boolean isSuppressed(SuppressLevel suppressLevel) {
   33.46 -            return Arrays.asList(suppressLevel.suppressedWarnings).contains(VARARGS);
   33.47 +            SuppressLevel supLev = this == VARARGS ?
   33.48 +                suppressLevelDecl :
   33.49 +                suppressLevelClient;
   33.50 +            return supLev == SuppressLevel.UNCHECKED ||
   33.51 +                    (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE);
   33.52          }
   33.53      }
   33.54  
   33.55 -    enum XlintOption {
   33.56 -        NONE(),
   33.57 -        UNCHECKED(Warning.UNCHECKED),
   33.58 -        VARARGS(Warning.VARARGS),
   33.59 -        ALL(Warning.UNCHECKED, Warning.VARARGS);
   33.60 +    enum SourceLevel {
   33.61 +        JDK_6("6"),
   33.62 +        JDK_7("7");
   33.63  
   33.64 -        Warning[] enabledWarnings;
   33.65 +        String sourceKey;
   33.66  
   33.67 -        XlintOption(Warning... enabledWarnings) {
   33.68 -            this.enabledWarnings = enabledWarnings;
   33.69 +        SourceLevel(String sourceKey) {
   33.70 +            this.sourceKey = sourceKey;
   33.71          }
   33.72 +    }
   33.73  
   33.74 -        String getXlintOption() {
   33.75 -            StringBuilder buf = new StringBuilder();
   33.76 -            String sep = "";
   33.77 -            for (Warning w : enabledWarnings) {
   33.78 -                buf.append(sep);
   33.79 -                buf.append(w.category);
   33.80 -                sep=",";
   33.81 -            }
   33.82 -            return "-Xlint:" +
   33.83 -                    (this == NONE ? "none" : buf.toString());
   33.84 +    enum TrustMe {
   33.85 +        DONT_TRUST(""),
   33.86 +        TRUST("@java.lang.SafeVarargs");
   33.87 +
   33.88 +        String anno;
   33.89 +
   33.90 +        TrustMe(String anno) {
   33.91 +            this.anno = anno;
   33.92 +        }
   33.93 +    }
   33.94 +
   33.95 +    enum ModifierKind {
   33.96 +        NONE(" "),
   33.97 +        FINAL("final "),
   33.98 +        STATIC("static ");
   33.99 +
  33.100 +        String mod;
  33.101 +
  33.102 +        ModifierKind(String mod) {
  33.103 +            this.mod = mod;
  33.104          }
  33.105      }
  33.106  
  33.107      enum SuppressLevel {
  33.108 -        NONE(),
  33.109 -        UNCHECKED(Warning.UNCHECKED),
  33.110 -        VARARGS(Warning.VARARGS),
  33.111 -        ALL(Warning.UNCHECKED, Warning.VARARGS);
  33.112 +        NONE(""),
  33.113 +        UNCHECKED("unchecked");
  33.114  
  33.115 -        Warning[] suppressedWarnings;
  33.116 +        String lint;
  33.117  
  33.118 -        SuppressLevel(Warning... suppressedWarnings) {
  33.119 -            this.suppressedWarnings = suppressedWarnings;
  33.120 +        SuppressLevel(String lint) {
  33.121 +            this.lint = lint;
  33.122          }
  33.123  
  33.124 -        String getSuppressAnnotation() {
  33.125 -            StringBuilder buf = new StringBuilder();
  33.126 -            String sep = "";
  33.127 -            for (Warning w : suppressedWarnings) {
  33.128 -                buf.append(sep);
  33.129 -                buf.append("\"");
  33.130 -                buf.append(w.category);
  33.131 -                buf.append("\"");
  33.132 -                sep=",";
  33.133 -            }
  33.134 -            return this == NONE ? "" :
  33.135 -                "@SuppressWarnings({" + buf.toString() + "})";
  33.136 +        String getSuppressAnno() {
  33.137 +            return "@SuppressWarnings(\"" + lint + "\")";
  33.138          }
  33.139      }
  33.140  
  33.141      enum Signature {
  33.142 -
  33.143 -        EXTENDS_TVAR("<Z> void #name(List<? extends Z>#arity arg) { #body }",
  33.144 -            new Warning[][] {both, both, both, both, error, both, both, both, error}),
  33.145 -        SUPER_TVAR("<Z> void #name(List<? super Z>#arity arg) { #body }",
  33.146 -            new Warning[][] {error, both, error, both, error, error, both, both, error}),
  33.147          UNBOUND("void #name(List<?>#arity arg) { #body }",
  33.148 -            new Warning[][] {none, none, none, none, none, none, none, none, error}),
  33.149 +            new Warning[][] {none, none, none, none, error}),
  33.150          INVARIANT_TVAR("<Z> void #name(List<Z>#arity arg) { #body }",
  33.151 -            new Warning[][] {both, both, both, both, error, both, both, both, error}),
  33.152 +            new Warning[][] {both, both, error, both, error}),
  33.153          TVAR("<Z> void #name(Z#arity arg) { #body }",
  33.154 -            new Warning[][] {both, both, both, both, both, both, both, both, vararg}),
  33.155 -        EXTENDS("void #name(List<? extends String>#arity arg) { #body }",
  33.156 -            new Warning[][] {error, error, error, error, error, both, error, both, error}),
  33.157 -        SUPER("void #name(List<? super String>#arity arg) { #body }",
  33.158 -            new Warning[][] {error, error, error, error, error, error, both, both, error}),
  33.159 +            new Warning[][] {both, both, both, both, vararg}),
  33.160          INVARIANT("void #name(List<String>#arity arg) { #body }",
  33.161 -            new Warning[][] {error, error, error, error, error, error, error, both, error}),
  33.162 +            new Warning[][] {error, error, error, both, error}),
  33.163          UNPARAMETERIZED("void #name(String#arity arg) { #body }",
  33.164 -            new Warning[][] {error, error, error, error, error, error, error, error, none});
  33.165 +            new Warning[][] {error, error, error, error, none});
  33.166  
  33.167          String template;
  33.168          Warning[][] warnings;
  33.169 @@ -163,15 +162,24 @@
  33.170      }
  33.171  
  33.172      public static void main(String... args) throws Exception {
  33.173 -        for (XlintOption xlint : XlintOption.values()) {
  33.174 -            for (SuppressLevel suppressLevel : SuppressLevel.values()) {
  33.175 -                for (Signature vararg_meth : Signature.values()) {
  33.176 -                    for (Signature client_meth : Signature.values()) {
  33.177 -                        if (vararg_meth.isApplicableTo(client_meth)) {
  33.178 -                            test(xlint,
  33.179 -                                    suppressLevel,
  33.180 -                                    vararg_meth,
  33.181 -                                    client_meth);
  33.182 +        for (SourceLevel sourceLevel : SourceLevel.values()) {
  33.183 +            for (TrustMe trustMe : TrustMe.values()) {
  33.184 +                for (SuppressLevel suppressLevelClient : SuppressLevel.values()) {
  33.185 +                    for (SuppressLevel suppressLevelDecl : SuppressLevel.values()) {
  33.186 +                        for (ModifierKind modKind : ModifierKind.values()) {
  33.187 +                            for (Signature vararg_meth : Signature.values()) {
  33.188 +                                for (Signature client_meth : Signature.values()) {
  33.189 +                                    if (vararg_meth.isApplicableTo(client_meth)) {
  33.190 +                                        test(sourceLevel,
  33.191 +                                                trustMe,
  33.192 +                                                suppressLevelClient,
  33.193 +                                                suppressLevelDecl,
  33.194 +                                                modKind,
  33.195 +                                                vararg_meth,
  33.196 +                                                client_meth);
  33.197 +                                    }
  33.198 +                                }
  33.199 +                            }
  33.200                          }
  33.201                      }
  33.202                  }
  33.203 @@ -179,37 +187,37 @@
  33.204          }
  33.205      }
  33.206  
  33.207 -    static void test(XlintOption xlint, SuppressLevel suppressLevel,
  33.208 -            Signature vararg_meth, Signature client_meth) throws Exception {
  33.209 +    static void test(SourceLevel sourceLevel, TrustMe trustMe, SuppressLevel suppressLevelClient,
  33.210 +            SuppressLevel suppressLevelDecl, ModifierKind modKind, Signature vararg_meth, Signature client_meth) throws Exception {
  33.211          final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  33.212 -        JavaSource source = new JavaSource(suppressLevel, vararg_meth, client_meth);
  33.213 +        JavaSource source = new JavaSource(trustMe, suppressLevelClient, suppressLevelDecl, modKind, vararg_meth, client_meth);
  33.214          DiagnosticChecker dc = new DiagnosticChecker();
  33.215          JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
  33.216 -                Arrays.asList(xlint.getXlintOption()), null, Arrays.asList(source));
  33.217 +                Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
  33.218 +                null, Arrays.asList(source));
  33.219          ct.generate(); //to get mandatory notes
  33.220 -        check(dc.warnings,
  33.221 -                dc.notes,
  33.222 +        check(dc.warnings, sourceLevel,
  33.223                  new boolean[] {vararg_meth.giveUnchecked(client_meth),
  33.224                                 vararg_meth.giveVarargs(client_meth)},
  33.225 -                source, xlint, suppressLevel);
  33.226 +                source, trustMe, suppressLevelClient, suppressLevelDecl, modKind);
  33.227      }
  33.228  
  33.229 -    static void check(Set<Warning> warnings, Set<Warning> notes, boolean[] warnArr, JavaSource source, XlintOption xlint, SuppressLevel suppressLevel) {
  33.230 +    static void check(Set<Warning> warnings, SourceLevel sourceLevel, boolean[] warnArr, JavaSource source,
  33.231 +            TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl, ModifierKind modKind) {
  33.232          boolean badOutput = false;
  33.233          for (Warning wkind : Warning.values()) {
  33.234 -            badOutput |= (warnArr[wkind.ordinal()] && !wkind.isSuppressed(suppressLevel)) !=
  33.235 -                    (wkind.isEnabled(xlint, suppressLevel) ?
  33.236 -                        warnings.contains(wkind) :
  33.237 -                        notes.contains(wkind));
  33.238 +            boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
  33.239 +                    suppressLevelClient, suppressLevelDecl, modKind);
  33.240 +            System.out.println("SUPPRESSED = " + isSuppressed);
  33.241 +            badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != warnings.contains(wkind);
  33.242          }
  33.243          if (badOutput) {
  33.244              throw new Error("invalid diagnostics for source:\n" +
  33.245                      source.getCharContent(true) +
  33.246 -                    "\nOptions: " + xlint.getXlintOption() +
  33.247                      "\nExpected unchecked warning: " + warnArr[0] +
  33.248                      "\nExpected unsafe vararg warning: " + warnArr[1] +
  33.249                      "\nWarnings: " + warnings +
  33.250 -                    "\nNotes: " + notes);
  33.251 +                    "\nSource level: " + sourceLevel);
  33.252          }
  33.253      }
  33.254  
  33.255 @@ -217,18 +225,20 @@
  33.256  
  33.257          String source;
  33.258  
  33.259 -        public JavaSource(SuppressLevel suppressLevel, Signature vararg_meth, Signature client_meth) {
  33.260 +        public JavaSource(TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
  33.261 +                ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
  33.262              super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
  33.263              String meth1 = vararg_meth.template.replace("#arity", "...");
  33.264              meth1 = meth1.replace("#name", "m");
  33.265              meth1 = meth1.replace("#body", "");
  33.266 -            meth1 = suppressLevel.getSuppressAnnotation() + meth1;
  33.267 +            meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() + modKind.mod + meth1;
  33.268              String meth2 = client_meth.template.replace("#arity", "");
  33.269              meth2 = meth2.replace("#name", "test");
  33.270              meth2 = meth2.replace("#body", "m(arg);");
  33.271 +            meth2 = suppressLevelClient.getSuppressAnno() + meth2;
  33.272              source = "import java.util.List;\n" +
  33.273 -               "class Test {\n" + meth1 +
  33.274 -               "\n" + meth2 + "\n}\n";
  33.275 +                     "class Test {\n" + meth1 +
  33.276 +                     "\n" + meth2 + "\n}\n";
  33.277          }
  33.278  
  33.279          @Override
  33.280 @@ -240,19 +250,15 @@
  33.281      static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
  33.282  
  33.283          Set<Warning> warnings = new HashSet<>();
  33.284 -        Set<Warning> notes = new HashSet<>();
  33.285  
  33.286          public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  33.287              if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING ||
  33.288                      diagnostic.getKind() == Diagnostic.Kind.WARNING) {
  33.289 -                warnings.add(diagnostic.getCode().contains("varargs") ?
  33.290 -                    Warning.VARARGS :
  33.291 -                    Warning.UNCHECKED);
  33.292 -            }
  33.293 -            else if (diagnostic.getKind() == Diagnostic.Kind.NOTE) {
  33.294 -                notes.add(diagnostic.getCode().contains("varargs") ?
  33.295 -                    Warning.VARARGS :
  33.296 -                    Warning.UNCHECKED);
  33.297 +                if (diagnostic.getCode().contains(Warning.VARARGS.key)) {
  33.298 +                    warnings.add(Warning.VARARGS);
  33.299 +                } else if(diagnostic.getCode().contains(Warning.UNCHECKED.key)) {
  33.300 +                    warnings.add(Warning.UNCHECKED);
  33.301 +                }
  33.302              }
  33.303          }
  33.304      }
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/test/tools/javac/varargs/warning/Warn5.java	Mon Dec 13 15:11:00 2010 -0800
    34.3 @@ -0,0 +1,293 @@
    34.4 +/*
    34.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    34.7 + *
    34.8 + * This code is free software; you can redistribute it and/or modify it
    34.9 + * under the terms of the GNU General Public License version 2 only, as
   34.10 + * published by the Free Software Foundation.
   34.11 + *
   34.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   34.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   34.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   34.15 + * version 2 for more details (a copy is included in the LICENSE file that
   34.16 + * accompanied this code).
   34.17 + *
   34.18 + * You should have received a copy of the GNU General Public License version
   34.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   34.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   34.21 + *
   34.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   34.23 + * or visit www.oracle.com if you need additional information or have any
   34.24 + * questions.
   34.25 + */
   34.26 +
   34.27 +/**
   34.28 + * @test
   34.29 + * @bug     6993978
   34.30 + * @summary Project Coin: Annotation to reduce varargs warnings
   34.31 + * @author  mcimadamore
   34.32 + * @run main Warn5
   34.33 + */
   34.34 +import com.sun.source.util.JavacTask;
   34.35 +import java.net.URI;
   34.36 +import java.util.ArrayList;
   34.37 +import java.util.Arrays;
   34.38 +import javax.tools.Diagnostic;
   34.39 +import javax.tools.JavaCompiler;
   34.40 +import javax.tools.JavaFileObject;
   34.41 +import javax.tools.SimpleJavaFileObject;
   34.42 +import javax.tools.ToolProvider;
   34.43 +
   34.44 +public class Warn5 {
   34.45 +
   34.46 +    enum XlintOption {
   34.47 +        NONE("none"),
   34.48 +        ALL("all");
   34.49 +
   34.50 +        String opt;
   34.51 +
   34.52 +        XlintOption(String opt) {
   34.53 +            this.opt = opt;
   34.54 +        }
   34.55 +
   34.56 +        String getXlintOption() {
   34.57 +            return "-Xlint:" + opt;
   34.58 +        }
   34.59 +    }
   34.60 +
   34.61 +    enum TrustMe {
   34.62 +        DONT_TRUST(""),
   34.63 +        TRUST("@java.lang.SafeVarargs");
   34.64 +
   34.65 +        String anno;
   34.66 +
   34.67 +        TrustMe(String anno) {
   34.68 +            this.anno = anno;
   34.69 +        }
   34.70 +    }
   34.71 +
   34.72 +    enum SuppressLevel {
   34.73 +        NONE,
   34.74 +        VARARGS;
   34.75 +
   34.76 +        String getSuppressAnno() {
   34.77 +            return this == VARARGS ?
   34.78 +                "@SuppressWarnings(\"varargs\")" :
   34.79 +                "";
   34.80 +        }
   34.81 +    }
   34.82 +
   34.83 +    enum ModifierKind {
   34.84 +        NONE(""),
   34.85 +        FINAL("final"),
   34.86 +        STATIC("static");
   34.87 +
   34.88 +        String mod;
   34.89 +
   34.90 +        ModifierKind(String mod) {
   34.91 +            this.mod = mod;
   34.92 +        }
   34.93 +    }
   34.94 +
   34.95 +    enum MethodKind {
   34.96 +        METHOD("void m"),
   34.97 +        CONSTRUCTOR("Test");
   34.98 +
   34.99 +
  34.100 +        String name;
  34.101 +
  34.102 +        MethodKind(String name) {
  34.103 +            this.name = name;
  34.104 +        }
  34.105 +    }
  34.106 +
  34.107 +    enum SourceLevel {
  34.108 +        JDK_6("6"),
  34.109 +        JDK_7("7");
  34.110 +
  34.111 +        String sourceKey;
  34.112 +
  34.113 +        SourceLevel(String sourceKey) {
  34.114 +            this.sourceKey = sourceKey;
  34.115 +        }
  34.116 +    }
  34.117 +
  34.118 +    enum SignatureKind {
  34.119 +        VARARGS_X("#K <X>#N(X... x)", false, true),
  34.120 +        VARARGS_STRING("#K #N(String... x)", true, true),
  34.121 +        ARRAY_X("#K <X>#N(X[] x)", false, false),
  34.122 +        ARRAY_STRING("#K #N(String[] x)", true, false);
  34.123 +
  34.124 +        String stub;
  34.125 +        boolean isReifiableArg;
  34.126 +        boolean isVarargs;
  34.127 +
  34.128 +        SignatureKind(String stub, boolean isReifiableArg, boolean isVarargs) {
  34.129 +            this.stub = stub;
  34.130 +            this.isReifiableArg = isReifiableArg;
  34.131 +            this.isVarargs = isVarargs;
  34.132 +        }
  34.133 +
  34.134 +        String getSignature(ModifierKind modKind, MethodKind methKind) {
  34.135 +            return methKind != MethodKind.CONSTRUCTOR ?
  34.136 +                stub.replace("#K", modKind.mod).replace("#N", methKind.name) :
  34.137 +                stub.replace("#K", "").replace("#N", methKind.name);
  34.138 +        }
  34.139 +    }
  34.140 +
  34.141 +    enum BodyKind {
  34.142 +        ASSIGN("Object o = x;", true),
  34.143 +        CAST("Object o = (Object)x;", true),
  34.144 +        METH("test(x);", true),
  34.145 +        PRINT("System.out.println(x.toString());", false),
  34.146 +        ARRAY_ASSIGN("Object[] o = x;", true),
  34.147 +        ARRAY_CAST("Object[] o = (Object[])x;", true),
  34.148 +        ARRAY_METH("testArr(x);", true);
  34.149 +
  34.150 +        String body;
  34.151 +        boolean hasAliasing;
  34.152 +
  34.153 +        BodyKind(String body, boolean hasAliasing) {
  34.154 +            this.body = body;
  34.155 +            this.hasAliasing = hasAliasing;
  34.156 +        }
  34.157 +    }
  34.158 +
  34.159 +    static class JavaSource extends SimpleJavaFileObject {
  34.160 +
  34.161 +        String template = "import com.sun.tools.javac.api.*;\n" +
  34.162 +                          "import java.util.List;\n" +
  34.163 +                          "class Test {\n" +
  34.164 +                          "   static void test(Object o) {}\n" +
  34.165 +                          "   static void testArr(Object[] o) {}\n" +
  34.166 +                          "   #T \n #S #M { #B }\n" +
  34.167 +                          "}\n";
  34.168 +
  34.169 +        String source;
  34.170 +
  34.171 +        public JavaSource(TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
  34.172 +                MethodKind methKind, SignatureKind meth, BodyKind body) {
  34.173 +            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
  34.174 +            source = template.replace("#T", trustMe.anno).
  34.175 +                    replace("#S", suppressLevel.getSuppressAnno()).
  34.176 +                    replace("#M", meth.getSignature(modKind, methKind)).
  34.177 +                    replace("#B", body.body);
  34.178 +        }
  34.179 +
  34.180 +        @Override
  34.181 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  34.182 +            return source;
  34.183 +        }
  34.184 +    }
  34.185 +
  34.186 +    public static void main(String... args) throws Exception {
  34.187 +        for (SourceLevel sourceLevel : SourceLevel.values()) {
  34.188 +            for (XlintOption xlint : XlintOption.values()) {
  34.189 +                for (TrustMe trustMe : TrustMe.values()) {
  34.190 +                    for (SuppressLevel suppressLevel : SuppressLevel.values()) {
  34.191 +                        for (ModifierKind modKind : ModifierKind.values()) {
  34.192 +                            for (MethodKind methKind : MethodKind.values()) {
  34.193 +                                for (SignatureKind sig : SignatureKind.values()) {
  34.194 +                                    for (BodyKind body : BodyKind.values()) {
  34.195 +                                        test(sourceLevel,
  34.196 +                                                xlint,
  34.197 +                                                trustMe,
  34.198 +                                                suppressLevel,
  34.199 +                                                modKind,
  34.200 +                                                methKind,
  34.201 +                                                sig,
  34.202 +                                                body);
  34.203 +                                    }
  34.204 +                                }
  34.205 +                            }
  34.206 +                        }
  34.207 +                    }
  34.208 +                }
  34.209 +            }
  34.210 +        }
  34.211 +    }
  34.212 +
  34.213 +    static void test(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel,
  34.214 +            ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) throws Exception {
  34.215 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  34.216 +        JavaSource source = new JavaSource(trustMe, suppressLevel, modKind, methKind, sig, body);
  34.217 +        DiagnosticChecker dc = new DiagnosticChecker();
  34.218 +        JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
  34.219 +                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
  34.220 +        ct.analyze();
  34.221 +        check(sourceLevel, dc, source, xlint, trustMe,
  34.222 +                suppressLevel, modKind, methKind, sig, body);
  34.223 +    }
  34.224 +
  34.225 +    static void check(SourceLevel sourceLevel, DiagnosticChecker dc, JavaSource source,
  34.226 +            XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind,
  34.227 +            MethodKind methKind, SignatureKind meth, BodyKind body) {
  34.228 +
  34.229 +        boolean hasPotentiallyUnsafeBody = sourceLevel == SourceLevel.JDK_7 &&
  34.230 +                trustMe == TrustMe.TRUST &&
  34.231 +                suppressLevel != SuppressLevel.VARARGS &&
  34.232 +                xlint != XlintOption.NONE &&
  34.233 +                meth.isVarargs && !meth.isReifiableArg && body.hasAliasing &&
  34.234 +                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE));
  34.235 +
  34.236 +        boolean hasPotentiallyPollutingDecl = sourceLevel == SourceLevel.JDK_7 &&
  34.237 +                trustMe == TrustMe.DONT_TRUST &&
  34.238 +                meth.isVarargs &&
  34.239 +                !meth.isReifiableArg &&
  34.240 +                xlint == XlintOption.ALL;
  34.241 +
  34.242 +        boolean hasMalformedAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
  34.243 +                trustMe == TrustMe.TRUST &&
  34.244 +                (!meth.isVarargs ||
  34.245 +                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD));
  34.246 +
  34.247 +        boolean hasRedundantAnnoInDecl = sourceLevel == SourceLevel.JDK_7 &&
  34.248 +                trustMe == TrustMe.TRUST &&
  34.249 +                xlint != XlintOption.NONE &&
  34.250 +                suppressLevel != SuppressLevel.VARARGS &&
  34.251 +                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
  34.252 +                meth.isVarargs &&
  34.253 +                meth.isReifiableArg;
  34.254 +
  34.255 +        if (hasPotentiallyUnsafeBody != dc.hasPotentiallyUnsafeBody ||
  34.256 +                hasPotentiallyPollutingDecl != dc.hasPotentiallyPollutingDecl ||
  34.257 +                hasMalformedAnnoInDecl != dc.hasMalformedAnnoInDecl ||
  34.258 +                hasRedundantAnnoInDecl != dc.hasRedundantAnnoInDecl) {
  34.259 +            throw new Error("invalid diagnostics for source:\n" +
  34.260 +                    source.getCharContent(true) +
  34.261 +                    "\nOptions: " + xlint.getXlintOption() +
  34.262 +                    "\nExpected potentially unsafe body warning: " + hasPotentiallyUnsafeBody +
  34.263 +                    "\nExpected potentially polluting decl warning: " + hasPotentiallyPollutingDecl +
  34.264 +                    "\nExpected malformed anno error: " + hasMalformedAnnoInDecl +
  34.265 +                    "\nExpected redundant anno warning: " + hasRedundantAnnoInDecl +
  34.266 +                    "\nFound potentially unsafe body warning: " + dc.hasPotentiallyUnsafeBody +
  34.267 +                    "\nFound potentially polluting decl warning: " + dc.hasPotentiallyPollutingDecl +
  34.268 +                    "\nFound malformed anno error: " + dc.hasMalformedAnnoInDecl +
  34.269 +                    "\nFound redundant anno warning: " + dc.hasRedundantAnnoInDecl);
  34.270 +        }
  34.271 +    }
  34.272 +
  34.273 +    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
  34.274 +
  34.275 +        boolean hasPotentiallyUnsafeBody = false;
  34.276 +        boolean hasPotentiallyPollutingDecl = false;
  34.277 +        boolean hasMalformedAnnoInDecl = false;
  34.278 +        boolean hasRedundantAnnoInDecl = false;
  34.279 +
  34.280 +        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  34.281 +            if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
  34.282 +                    if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
  34.283 +                        hasPotentiallyUnsafeBody = true;
  34.284 +                    } else if (diagnostic.getCode().contains("redundant.trustme")) {
  34.285 +                        hasRedundantAnnoInDecl = true;
  34.286 +                    }
  34.287 +            } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
  34.288 +                    diagnostic.getCode().contains("varargs.non.reifiable.type")) {
  34.289 +                hasPotentiallyPollutingDecl = true;
  34.290 +            } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
  34.291 +                    diagnostic.getCode().contains("invalid.trustme")) {
  34.292 +                hasMalformedAnnoInDecl = true;
  34.293 +            }
  34.294 +        }
  34.295 +    }
  34.296 +}

mercurial