6594914: @SuppressWarnings("deprecation") does not not work for the type of a variable
Lint warnings generated during MemberEnter might ignore @SuppressWarnings annotations Reviewed-by: jjg
This commit is contained in:
parent
9be3c0f789
commit
79d1b7b1e1
@ -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();
|
||||
}
|
||||
};
|
||||
}
|
@ -83,6 +83,7 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
findDiamonds = options.get("findDiamond") != null &&
|
||||
source.allowDiamond();
|
||||
useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
|
||||
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
|
||||
}
|
||||
|
||||
/** Switch: relax some constraints for retrofit mode.
|
||||
@ -173,12 +174,6 @@ public class Attr extends JCTree.Visitor {
|
||||
*/
|
||||
boolean useBeforeDeclarationWarning;
|
||||
|
||||
/**
|
||||
* Switch: allow lint infrastructure to control proprietary
|
||||
* API warnings.
|
||||
*/
|
||||
boolean enableSunApiLintControl;
|
||||
|
||||
/**
|
||||
* Switch: allow strings in switch?
|
||||
*/
|
||||
@ -707,6 +702,7 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
// 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 @@ public class Attr extends JCTree.Visitor {
|
||||
// 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
|
||||
|
@ -60,7 +60,6 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
*/
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
}
|
||||
|
||||
// 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 @@ public class Check {
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
**************************************************************************/
|
||||
|
@ -75,9 +75,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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
|
||||
|
@ -1638,10 +1638,7 @@ public class Resolve {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 {}
|
29
langtools/test/tools/javac/warnings/6594914/T6594914a.java
Normal file
29
langtools/test/tools/javac/warnings/6594914/T6594914a.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
29
langtools/test/tools/javac/warnings/6594914/T6594914b.java
Normal file
29
langtools/test/tools/javac/warnings/6594914/T6594914b.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
Loading…
Reference in New Issue
Block a user