提交 5f1c7194 编写于 作者: V vromero

8009138: javac, equals-hashCode warning tuning

Reviewed-by: mcimadamore
上级 b7bf3363
......@@ -237,7 +237,7 @@ public abstract class Symbol implements Element {
}
/** Has this symbol an empty name? This includes anonymous
* inner classses.
* inner classes.
*/
public boolean isAnonymous() {
return name.isEmpty();
......
......@@ -148,6 +148,7 @@ public class Symtab {
public final Type listType;
public final Type collectionsType;
public final Type comparableType;
public final Type comparatorType;
public final Type arraysType;
public final Type iterableType;
public final Type iteratorType;
......@@ -502,6 +503,7 @@ public class Symtab {
listType = enterClass("java.util.List");
collectionsType = enterClass("java.util.Collections");
comparableType = enterClass("java.lang.Comparable");
comparatorType = enterClass("java.util.Comparator");
arraysType = enterClass("java.util.Arrays");
iterableType = target.hasIterable()
? enterClass("java.lang.Iterable")
......
......@@ -4016,7 +4016,7 @@ public class Attr extends JCTree.Visitor {
attribClassBody(env, c);
chk.checkDeprecatedAnnotation(env.tree.pos(), c);
chk.checkClassOverrideEqualsAndHash(env.tree.pos(), c);
chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
} finally {
env.info.returnResult = prevReturnRes;
log.useSource(prev);
......
......@@ -1972,14 +1972,32 @@ public class Check {
}
};
public void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
ClassSymbol someClass) {
/* At present, annotations cannot possibly have a method that is override
* equivalent with Object.equals(Object) but in any case the condition is
* fine for completeness.
*/
if (someClass == (ClassSymbol)syms.objectType.tsym ||
someClass.isInterface() || someClass.isEnum() ||
(someClass.flags() & ANNOTATION) != 0 ||
(someClass.flags() & ABSTRACT) != 0) return;
//anonymous inner classes implementing interfaces need especial treatment
if (someClass.isAnonymous()) {
List<Type> interfaces = types.interfaces(someClass.type);
if (interfaces != null && !interfaces.isEmpty() &&
interfaces.head.tsym == syms.comparatorType.tsym) return;
}
checkClassOverrideEqualsAndHash(pos, someClass);
}
private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
ClassSymbol someClass) {
if (lint.isEnabled(LintCategory.OVERRIDES)) {
MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
.tsym.members().lookup(names.equals).sym;
MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
.tsym.members().lookup(names.hashCode).sym;
boolean overridesEquals = types.implementation(equalsAtObject,
someClass, false, equalsHasCodeFilter).owner == someClass;
boolean overridesHashCode = types.implementation(hashCodeAtObject,
......@@ -1987,7 +2005,7 @@ public class Check {
if (overridesEquals && !overridesHashCode) {
log.warning(LintCategory.OVERRIDES, pos,
"override.equals.but.not.hashcode", someClass.fullname);
"override.equals.but.not.hashcode", someClass);
}
}
}
......
......@@ -2077,7 +2077,7 @@ compiler.warn.override.unchecked.thrown=\
{0}\n\
overridden method does not throw {1}
# 0: class name
# 0: symbol
compiler.warn.override.equals.but.not.hashcode=\
Class {0} overrides equals, but neither it nor any superclass overrides hashCode method
......
/*
* @test /nodynamiccopyright/
* @bug 6563143 8008436
* @bug 6563143 8008436 8009138
* @summary javac should issue a warning for overriding equals without hashCode
* @summary javac should not issue a warning for overriding equals without hasCode
* @summary javac, equals-hashCode warning tuning
* if hashCode has been overriden by a superclass
* @compile/ref=OverridesEqualsButNotHashCodeTest.out -Xlint:overrides -XDrawDiagnostics OverridesEqualsButNotHashCodeTest.java
* @compile/ref=EqualsHashCodeWarningTest.out -Xlint:overrides -XDrawDiagnostics EqualsHashCodeWarningTest.java
*/
public class OverridesEqualsButNotHashCodeTest {
import java.util.Comparator;
public class EqualsHashCodeWarningTest {
@Override
public boolean equals(Object o) {
return o == this;
......@@ -17,20 +20,32 @@ public class OverridesEqualsButNotHashCodeTest {
public int hashCode() {
return 0;
}
public Comparator m() {
return new Comparator() {
@Override
public boolean equals(Object o) {return true;}
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
}
}
class SubClass extends OverridesEqualsButNotHashCodeTest {
class SubClass extends EqualsHashCodeWarningTest {
@Override
public boolean equals(Object o) {
return o == this;
return true;
}
}
@SuppressWarnings("overrides")
class NoWarning {
class DontWarnMe {
@Override
public boolean equals(Object o) {
return o == this;
return true;
}
}
......@@ -40,3 +55,17 @@ class DoWarnMe {
return o == this;
}
}
abstract class IamAbstractGetMeOutOfHere {
public boolean equals(Object o){return true;}
}
interface I {
public boolean equals(Object o);
}
enum E {
A, B
}
@interface anno {}
EqualsHashCodeWarningTest.java:52:1: compiler.warn.override.equals.but.not.hashcode: DoWarnMe
1 warning
OverridesEqualsButNotHashCodeTest.java:37:1: compiler.warn.override.equals.but.not.hashcode: DoWarnMe
1 warning
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册