6594914: @SuppressWarnings("deprecation") does not not work for the type of a variable
authormcimadamore
Thu, 03 Feb 2011 09:35:21 +0000
changeset 8236 0d8646b7c602
parent 8235 0f7e1f7a6a4b
child 8237 d5ef8db7ad09
6594914: @SuppressWarnings("deprecation") does not not work for the type of a variable Summary: Lint warnings generated during MemberEnter might ignore @SuppressWarnings annotations Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/test/tools/javac/warnings/6594914/DeprecatedClass.java
langtools/test/tools/javac/warnings/6594914/T6594914a.java
langtools/test/tools/javac/warnings/6594914/T6594914a.out
langtools/test/tools/javac/warnings/6594914/T6594914b.java
langtools/test/tools/javac/warnings/6594914/T6594914b.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+
+/**
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class DeferredLintHandler {
+    protected static final Context.Key<DeferredLintHandler> deferredLintHandlerKey =
+        new Context.Key<DeferredLintHandler>();
+
+    public static DeferredLintHandler instance(Context context) {
+        DeferredLintHandler instance = context.get(deferredLintHandlerKey);
+        if (instance == null)
+            instance = new DeferredLintHandler(context);
+        return instance;
+    }
+
+    protected DeferredLintHandler(Context context) {
+        context.put(deferredLintHandlerKey, this);
+    }
+
+    private DeferredLintHandler() {}
+
+    public interface LintLogger {
+        void report();
+    }
+
+    private DiagnosticPosition currentPos;
+    private Map<DiagnosticPosition, ListBuffer<LintLogger>> loggersQueue = new HashMap<DiagnosticPosition, ListBuffer<LintLogger>>();
+
+    public void report(LintLogger logger) {
+        ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
+        Assert.checkNonNull(loggers);
+        loggers.append(logger);
+    }
+
+    public void flush(DiagnosticPosition pos) {
+        ListBuffer<LintLogger> loggers = loggersQueue.get(pos);
+        if (loggers != null) {
+            for (LintLogger lintLogger : loggers) {
+                lintLogger.report();
+            }
+            loggersQueue.remove(pos);
+        }
+    }
+
+    public DeferredLintHandler setPos(DiagnosticPosition currentPos) {
+        this.currentPos = currentPos;
+        loggersQueue.put(currentPos, ListBuffer.<LintLogger>lb());
+        return this;
+    }
+
+    public static final DeferredLintHandler immediateHandler = new DeferredLintHandler() {
+        @Override
+        public void report(LintLogger logger) {
+            logger.report();
+        }
+    };
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Feb 01 10:11:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Feb 03 09:35:21 2011 +0000
@@ -83,6 +83,7 @@
     final Types types;
     final JCDiagnostic.Factory diags;
     final Annotate annotate;
+    final DeferredLintHandler deferredLintHandler;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -108,6 +109,7 @@
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         annotate = Annotate.instance(context);
+        deferredLintHandler = DeferredLintHandler.instance(context);
 
         Options options = Options.instance(context);
 
@@ -125,7 +127,6 @@
         findDiamonds = options.get("findDiamond") != null &&
                  source.allowDiamond();
         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
-        enableSunApiLintControl = options.isSet("enableSunApiLintControl");
     }
 
     /** Switch: relax some constraints for retrofit mode.
@@ -174,12 +175,6 @@
     boolean useBeforeDeclarationWarning;
 
     /**
-     * Switch: allow lint infrastructure to control proprietary
-     * API warnings.
-     */
-    boolean enableSunApiLintControl;
-
-    /**
      * Switch: allow strings in switch?
      */
     boolean allowStringsInSwitch;
@@ -707,6 +702,7 @@
         Lint prevLint = chk.setLint(lint);
         MethodSymbol prevMethod = chk.setMethod(m);
         try {
+            deferredLintHandler.flush(tree.pos());
             chk.checkDeprecatedAnnotation(tree.pos(), m);
 
             attribBounds(tree.typarams);
@@ -849,6 +845,7 @@
 
         // Check that the variable's declared type is well-formed.
         chk.validate(tree.vartype, env);
+        deferredLintHandler.flush(tree.pos());
 
         try {
             chk.checkDeprecatedAnnotation(tree.pos(), v);
@@ -2578,17 +2575,10 @@
             // Test (1): emit a `deprecation' warning if symbol is deprecated.
             // (for constructors, the error was given when the constructor was
             // resolved)
-            if (sym.name != names.init &&
-                (sym.flags() & DEPRECATED) != 0 &&
-                (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
-                sym.outermostClass() != env.info.scope.owner.outermostClass())
-                chk.warnDeprecated(tree.pos(), sym);
-
-            if ((sym.flags() & PROPRIETARY) != 0) {
-                if (enableSunApiLintControl)
-                  chk.warnSunApi(tree.pos(), "sun.proprietary", sym);
-                else
-                  log.strictWarning(tree.pos(), "sun.proprietary", sym);
+
+            if (sym.name != names.init) {
+                chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
+                chk.checkSunAPI(tree.pos(), sym);
             }
 
             // Test (3): if symbol is a variable, check that its type and
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Tue Feb 01 10:11:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Feb 03 09:35:21 2011 +0000
@@ -60,7 +60,6 @@
 
     private final Names names;
     private final Log log;
-    private final Resolve rs;
     private final Symtab syms;
     private final Enter enter;
     private final Infer infer;
@@ -69,6 +68,7 @@
     private final boolean skipAnnotations;
     private boolean warnOnSyntheticConflicts;
     private boolean suppressAbortOnBadClassFile;
+    private boolean enableSunApiLintControl;
     private final TreeInfo treeinfo;
 
     // The set of lint options currently in effect. It is initialized
@@ -92,7 +92,6 @@
 
         names = Names.instance(context);
         log = Log.instance(context);
-        rs = Resolve.instance(context);
         syms = Symtab.instance(context);
         enter = Enter.instance(context);
         infer = Infer.instance(context);
@@ -111,13 +110,13 @@
         skipAnnotations = options.isSet("skipAnnotations");
         warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
         suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
+        enableSunApiLintControl = options.isSet("enableSunApiLintControl");
 
         Target target = Target.instance(context);
         syntheticNameChar = target.syntheticNameChar();
 
         boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
         boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
-        boolean verboseVarargs = lint.isEnabled(LintCategory.VARARGS);
         boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI);
         boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
 
@@ -125,10 +124,10 @@
                 enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
         uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
                 enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
-        unsafeVarargsHandler = new MandatoryWarningHandler(log, verboseVarargs,
-                enforceMandatoryWarnings, "varargs", LintCategory.VARARGS);
         sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
                 enforceMandatoryWarnings, "sunapi", null);
+
+        deferredLintHandler = DeferredLintHandler.immediateHandler;
     }
 
     /** Switch: generics enabled?
@@ -168,14 +167,14 @@
      */
     private MandatoryWarningHandler uncheckedHandler;
 
-    /** A handler for messages about unchecked or unsafe vararg method decl.
-     */
-    private MandatoryWarningHandler unsafeVarargsHandler;
-
     /** A handler for messages about using proprietary API.
      */
     private MandatoryWarningHandler sunApiHandler;
 
+    /** A handler for deferred lint warnings.
+     */
+    private DeferredLintHandler deferredLintHandler;
+
 /* *************************************************************************
  * Errors and Warnings
  **************************************************************************/
@@ -186,6 +185,12 @@
         return prev;
     }
 
+    DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) {
+        DeferredLintHandler prev = deferredLintHandler;
+        deferredLintHandler = newDeferredLintHandler;
+        return prev;
+    }
+
     MethodSymbol setMethod(MethodSymbol newMethod) {
         MethodSymbol prev = method;
         method = newMethod;
@@ -1096,6 +1101,7 @@
                     log.error(tree.pos(), "improperly.formed.type.param.missing");
             }
         }
+
         public void visitSelectInternal(JCFieldAccess tree) {
             if (tree.type.tsym.isStatic() &&
                 tree.selected.type.isParameterized()) {
@@ -1465,11 +1471,8 @@
         }
 
         // Warn if a deprecated method overridden by a non-deprecated one.
-        if ((other.flags() & DEPRECATED) != 0
-            && (m.flags() & DEPRECATED) == 0
-            && m.outermostClass() != other.outermostClass()
-            && !isDeprecatedOverrideIgnorable(other, origin)) {
-            warnDeprecated(TreeInfo.diagnosticPositionFor(m, tree), other);
+        if (!isDeprecatedOverrideIgnorable(other, origin)) {
+            checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
         }
     }
     // where
@@ -2412,6 +2415,32 @@
         }
     }
 
+    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
+        if ((s.flags() & DEPRECATED) != 0 &&
+                (other.flags() & DEPRECATED) == 0 &&
+                s.outermostClass() != other.outermostClass()) {
+            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
+                @Override
+                public void report() {
+                    warnDeprecated(pos, s);
+                }
+            });
+        };
+    }
+
+    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
+        if ((s.flags() & PROPRIETARY) != 0) {
+            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
+                public void report() {
+                    if (enableSunApiLintControl)
+                      warnSunApi(pos, "sun.proprietary", s);
+                    else
+                      log.strictWarning(pos, "sun.proprietary", s);
+                }
+            });
+        }
+    }
+
 /* *************************************************************************
  * Check for recursive annotation elements.
  **************************************************************************/
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Feb 01 10:11:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Feb 03 09:35:21 2011 +0000
@@ -75,9 +75,9 @@
     private final Types types;
     private final JCDiagnostic.Factory diags;
     private final Target target;
+    private final DeferredLintHandler deferredLintHandler;
 
     private final boolean skipAnnotations;
-    private final boolean allowSimplifiedVarargs;
 
     public static MemberEnter instance(Context context) {
         MemberEnter instance = context.get(memberEnterKey);
@@ -102,10 +102,9 @@
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         target = Target.instance(context);
+        deferredLintHandler = DeferredLintHandler.instance(context);
         Options options = Options.instance(context);
         skipAnnotations = options.isSet("skipAnnotations");
-        Source source = Source.instance(context);
-        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
     }
 
     /** A queue for classes whose members still need to be entered into the
@@ -571,10 +570,16 @@
         tree.sym = m;
         Env<AttrContext> localEnv = methodEnv(tree, env);
 
-        // Compute the method type
-        m.type = signature(tree.typarams, tree.params,
-                           tree.restype, tree.thrown,
-                           localEnv);
+        DeferredLintHandler prevLintHandler =
+                chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+        try {
+            // Compute the method type
+            m.type = signature(tree.typarams, tree.params,
+                               tree.restype, tree.thrown,
+                               localEnv);
+        } finally {
+            chk.setDeferredLintHandler(prevLintHandler);
+        }
 
         // Set m.params
         ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
@@ -618,7 +623,14 @@
             localEnv = env.dup(tree, env.info.dup());
             localEnv.info.staticLevel++;
         }
-        attr.attribType(tree.vartype, localEnv);
+        DeferredLintHandler prevLintHandler =
+                chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+        try {
+            attr.attribType(tree.vartype, localEnv);
+        } finally {
+            chk.setDeferredLintHandler(prevLintHandler);
+        }
+
         if ((tree.mods.flags & VARARGS) != 0) {
             //if we are entering a varargs parameter, we need to replace its type
             //(a plain array type) with the more precise VarargsType --- we need
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Feb 01 10:11:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Feb 03 09:35:21 2011 +0000
@@ -1638,10 +1638,7 @@
                                 names.init, argtypes,
                                 typeargtypes, allowBoxing,
                                 useVarargs, false);
-        if ((sym.flags() & DEPRECATED) != 0 &&
-            (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
-            env.info.scope.owner.outermostClass() != sym.outermostClass())
-            chk.warnDeprecated(pos, sym);
+        chk.checkDeprecated(pos, env.info.scope.owner, sym);
         return sym;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6594914/DeprecatedClass.java	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+@Deprecated
+class DeprecatedClass extends Exception {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914a.java	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,29 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6594914
+ * @summary \\@SuppressWarnings("deprecation") does not not work for the type of a variable
+ * @compile/ref=T6594914a.out -XDrawDiagnostics -Xlint:deprecation T6594914a.java
+ */
+
+
+class T6747671a {
+
+    DeprecatedClass a1; //warn
+
+    @SuppressWarnings("deprecation")
+    DeprecatedClass a2;
+
+    <X extends DeprecatedClass> DeprecatedClass m1(DeprecatedClass a)
+            throws DeprecatedClass { return null; } //warn
+
+    @SuppressWarnings("deprecation")
+    <X extends DeprecatedClass> DeprecatedClass m2(DeprecatedClass a)
+            throws DeprecatedClass { return null; }
+
+    void test() {
+        DeprecatedClass a1; //warn
+
+        @SuppressWarnings("deprecation")
+        DeprecatedClass a2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914a.out	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,7 @@
+T6594914a.java:11:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:16:16: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:16:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:17:20: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:24:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+6 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914b.java	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,29 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6594914
+ * @summary \\@SuppressWarnings("deprecation") does not not work for the type of a variable
+ * @compile/ref=T6594914b.out -XDenableSunApiLintControl -XDrawDiagnostics -Xlint:sunapi T6594914b.java
+ */
+
+
+class T6747671b {
+
+    sun.misc.Lock a1; //warn
+
+    @SuppressWarnings("sunapi")
+    sun.misc.Lock a2;
+
+    <X extends sun.misc.Lock> sun.misc.Lock m1(sun.misc.Lock a)
+            throws sun.misc.CEFormatException { return null; } //warn
+
+    @SuppressWarnings("sunapi")
+    <X extends sun.misc.Lock> sun.misc.Lock m2(sun.misc.Lock a)
+            throws sun.misc.CEFormatException { return null; }
+
+    void test() {
+        sun.misc.Lock a1; //warn
+
+        @SuppressWarnings("sunapi")
+        sun.misc.Lock a2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914b.out	Thu Feb 03 09:35:21 2011 +0000
@@ -0,0 +1,7 @@
+T6594914b.java:11:13: compiler.warn.sun.proprietary: sun.misc.Lock
+T6594914b.java:16:24: compiler.warn.sun.proprietary: sun.misc.Lock
+T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock
+T6594914b.java:16:39: compiler.warn.sun.proprietary: sun.misc.Lock
+T6594914b.java:17:28: compiler.warn.sun.proprietary: sun.misc.CEFormatException
+T6594914b.java:24:17: compiler.warn.sun.proprietary: sun.misc.Lock
+6 warnings