8008436: javac should not issue a warning for overriding equals without hasCode if hashCode has been overriden by a superclass

Tue, 26 Feb 2013 09:04:19 +0000

author
vromero
date
Tue, 26 Feb 2013 09:04:19 +0000
changeset 1607
bd49e0304281
parent 1606
ccbe7ffdd867
child 1608
133a0a0c2cbc

8008436: javac should not issue a warning for overriding equals without hasCode if hashCode has been overriden by a superclass
Reviewed-by: jjg, mcimadamore

src/share/classes/com/sun/tools/javac/code/Symbol.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/resources/compiler.properties file | annotate | diff | comparison | revisions
test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.java file | annotate | diff | comparison | revisions
test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.out file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Sun Feb 24 11:36:58 2013 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Feb 26 09:04:19 2013 +0000
     1.3 @@ -1305,7 +1305,7 @@
     1.4              return implementation(origin, types, checkResult, implementation_filter);
     1.5          }
     1.6          // where
     1.7 -            private static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
     1.8 +            public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
     1.9                  public boolean accepts(Symbol s) {
    1.10                      return s.kind == Kinds.MTH &&
    1.11                              (s.flags() & SYNTHETIC) == 0;
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sun Feb 24 11:36:58 2013 -0800
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Feb 26 09:04:19 2013 +0000
     2.3 @@ -3992,7 +3992,7 @@
     2.4                  attribClassBody(env, c);
     2.5  
     2.6                  chk.checkDeprecatedAnnotation(env.tree.pos(), c);
     2.7 -                chk.checkClassOverrideEqualsAndHash(c);
     2.8 +                chk.checkClassOverrideEqualsAndHash(env.tree.pos(), c);
     2.9              } finally {
    2.10                  env.info.returnResult = prevReturnRes;
    2.11                  log.useSource(prev);
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Feb 24 11:36:58 2013 -0800
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Tue Feb 26 09:04:19 2013 +0000
     3.3 @@ -1964,28 +1964,29 @@
     3.4          }
     3.5      }
     3.6  
     3.7 -    public void checkClassOverrideEqualsAndHash(ClassSymbol someClass) {
     3.8 +    private Filter<Symbol> equalsHasCodeFilter = new Filter<Symbol>() {
     3.9 +        public boolean accepts(Symbol s) {
    3.10 +            return MethodSymbol.implementation_filter.accepts(s) &&
    3.11 +                    (s.flags() & BAD_OVERRIDE) == 0;
    3.12 +
    3.13 +        }
    3.14 +    };
    3.15 +
    3.16 +    public void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
    3.17 +            ClassSymbol someClass) {
    3.18          if (lint.isEnabled(LintCategory.OVERRIDES)) {
    3.19 -            boolean hasEquals = false;
    3.20 -            boolean hasHashCode = false;
    3.21 -
    3.22 -            Scope.Entry equalsAtObject = syms.objectType.tsym.members().lookup(names.equals);
    3.23 -            Scope.Entry hashCodeAtObject = syms.objectType.tsym.members().lookup(names.hashCode);
    3.24 -            for (Symbol s: someClass.members().getElements(new Filter<Symbol>() {
    3.25 -                    public boolean accepts(Symbol s) {
    3.26 -                        return s.kind == Kinds.MTH &&
    3.27 -                                (s.flags() & BAD_OVERRIDE) == 0;
    3.28 -                    }
    3.29 -                })) {
    3.30 -                MethodSymbol m = (MethodSymbol)s;
    3.31 -                hasEquals |= m.name.equals(names.equals) &&
    3.32 -                        m.overrides(equalsAtObject.sym, someClass, types, false);
    3.33 -
    3.34 -                hasHashCode |= m.name.equals(names.hashCode) &&
    3.35 -                        m.overrides(hashCodeAtObject.sym, someClass, types, false);
    3.36 -            }
    3.37 -            if (hasEquals && !hasHashCode) {
    3.38 -                log.warning(LintCategory.OVERRIDES, (DiagnosticPosition) null,
    3.39 +            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
    3.40 +                    .tsym.members().lookup(names.equals).sym;
    3.41 +            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
    3.42 +                    .tsym.members().lookup(names.hashCode).sym;
    3.43 +
    3.44 +            boolean overridesEquals = types.implementation(equalsAtObject,
    3.45 +                someClass, false, equalsHasCodeFilter).owner == someClass;
    3.46 +            boolean overridesHashCode = types.implementation(hashCodeAtObject,
    3.47 +                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
    3.48 +
    3.49 +            if (overridesEquals && !overridesHashCode) {
    3.50 +                log.warning(LintCategory.OVERRIDES, pos,
    3.51                          "override.equals.but.not.hashcode", someClass.fullname);
    3.52              }
    3.53          }
     4.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Sun Feb 24 11:36:58 2013 -0800
     4.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Feb 26 09:04:19 2013 +0000
     4.3 @@ -2071,8 +2071,7 @@
     4.4  
     4.5  # 0: class name
     4.6  compiler.warn.override.equals.but.not.hashcode=\
     4.7 -    Class {0}\n\
     4.8 -    overrides method equals but does not overrides method hashCode from Object
     4.9 +    Class {0} overrides equals, but neither it nor any superclass overrides hashCode method
    4.10  
    4.11  ## The following are all possible strings for the first argument ({0}) of the
    4.12  ## above strings.
     5.1 --- a/test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.java	Sun Feb 24 11:36:58 2013 -0800
     5.2 +++ b/test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.java	Tue Feb 26 09:04:19 2013 +0000
     5.3 @@ -1,22 +1,42 @@
     5.4  /*
     5.5   * @test /nodynamiccopyright/
     5.6 - * @bug 6563143
     5.7 + * @bug 6563143 8008436
     5.8   * @summary javac should issue a warning for overriding equals without hashCode
     5.9 + * @summary javac should not issue a warning for overriding equals without hasCode
    5.10 + * if hashCode has been overriden by a superclass
    5.11   * @compile/ref=OverridesEqualsButNotHashCodeTest.out -Xlint:overrides -XDrawDiagnostics OverridesEqualsButNotHashCodeTest.java
    5.12   */
    5.13  
    5.14 -@SuppressWarnings("overrides")
    5.15  public class OverridesEqualsButNotHashCodeTest {
    5.16      @Override
    5.17      public boolean equals(Object o) {
    5.18          return o == this;
    5.19      }
    5.20 +
    5.21 +    @Override
    5.22 +    public int hashCode() {
    5.23 +        return 0;
    5.24 +    }
    5.25 +}
    5.26 +
    5.27 +class SubClass extends OverridesEqualsButNotHashCodeTest {
    5.28 +    @Override
    5.29 +    public boolean equals(Object o) {
    5.30 +        return o == this;
    5.31 +    }
    5.32  }
    5.33  
    5.34 -class Other {
    5.35 +@SuppressWarnings("overrides")
    5.36 +class NoWarning {
    5.37      @Override
    5.38      public boolean equals(Object o) {
    5.39          return o == this;
    5.40      }
    5.41  }
    5.42  
    5.43 +class DoWarnMe {
    5.44 +    @Override
    5.45 +    public boolean equals(Object o) {
    5.46 +        return o == this;
    5.47 +    }
    5.48 +}
     6.1 --- a/test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.out	Sun Feb 24 11:36:58 2013 -0800
     6.2 +++ b/test/tools/javac/6563143/OverridesEqualsButNotHashCodeTest.out	Tue Feb 26 09:04:19 2013 +0000
     6.3 @@ -1,2 +1,2 @@
     6.4 -- compiler.warn.override.equals.but.not.hashcode: Other
     6.5 +OverridesEqualsButNotHashCodeTest.java:37:1: compiler.warn.override.equals.but.not.hashcode: DoWarnMe
     6.6  1 warning

mercurial