[java] Update rule OverrideBothEqualsAndHashcode
This commit is contained in:
@ -240,7 +240,7 @@
|
||||
<!-- <rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/> -->
|
||||
<rule ref="category/java/errorprone.xml/NonStaticInitializer"/>
|
||||
<!-- <rule ref="category/java/errorprone.xml/NullAssignment"/> -->
|
||||
<!-- <rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/> -->
|
||||
<rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/>
|
||||
<!-- <rule ref="category/java/errorprone.xml/ProperCloneImplementation"/> -->
|
||||
<!-- <rule ref="category/java/errorprone.xml/ProperLogger"/> -->
|
||||
<!-- <rule ref="category/java/errorprone.xml/ReturnEmptyArrayRatherThanNull"/> -->
|
||||
|
@ -4,16 +4,13 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.errorprone;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImplementsList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.java.types.TypeTestUtil;
|
||||
|
||||
public class OverrideBothEqualsAndHashcodeRule extends AbstractJavaRule {
|
||||
|
||||
@ -46,51 +43,30 @@ public class OverrideBothEqualsAndHashcodeRule extends AbstractJavaRule {
|
||||
|
||||
@Override
|
||||
public Object visit(ASTImplementsList node, Object data) {
|
||||
for (int ix = 0; ix < node.getNumChildren(); ix++) {
|
||||
if (node.getChild(ix) instanceof ASTClassOrInterfaceType) {
|
||||
ASTClassOrInterfaceType cit = (ASTClassOrInterfaceType) node.getChild(ix);
|
||||
Class<?> clazz = cit.getType();
|
||||
if (clazz != null && node.getChild(ix).hasImageEqualTo("Comparable")) {
|
||||
implementsComparable = true;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
implementsComparable = node.children().filter(child -> TypeTestUtil.isA(Comparable.class, child)).nonEmpty();
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethodDeclarator node, Object data) {
|
||||
public Object visit(ASTMethodDeclaration node, Object data) {
|
||||
if (implementsComparable) {
|
||||
return data;
|
||||
}
|
||||
|
||||
int iFormalParams = 0;
|
||||
String paramName = null;
|
||||
for (int ix = 0; ix < node.getNumChildren(); ix++) {
|
||||
Node sn = node.getChild(ix);
|
||||
if (sn instanceof ASTFormalParameters) {
|
||||
List<ASTFormalParameter> allParams = ((ASTFormalParameters) sn)
|
||||
.findChildrenOfType(ASTFormalParameter.class);
|
||||
for (ASTFormalParameter formalParam : allParams) {
|
||||
iFormalParams++;
|
||||
ASTClassOrInterfaceType param = formalParam.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
|
||||
if (param != null) {
|
||||
paramName = param.getImage();
|
||||
}
|
||||
}
|
||||
}
|
||||
int formalParamsCount = node.getFormalParameters().size();
|
||||
ASTFormalParameter formalParam = null;
|
||||
if (formalParamsCount > 0) {
|
||||
formalParam = node.getFormalParameters().get(0);
|
||||
}
|
||||
|
||||
if (iFormalParams == 0 && node.hasImageEqualTo("hashCode")) {
|
||||
if (formalParamsCount == 0 && "hashCode".equals(node.getName())) {
|
||||
containsHashCode = true;
|
||||
nodeFound = node;
|
||||
} else if (iFormalParams == 1 && node.hasImageEqualTo("equals")
|
||||
&& ("Object".equals(paramName) || "java.lang.Object".equals(paramName))) {
|
||||
} else if (formalParamsCount == 1 && "equals".equals(node.getName())
|
||||
&& TypeTestUtil.isExactlyA(Object.class, formalParam)) {
|
||||
containsEquals = true;
|
||||
nodeFound = node;
|
||||
}
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.errorprone;
|
||||
|
||||
import net.sourceforge.pmd.testframework.PmdRuleTst;
|
||||
|
||||
@org.junit.Ignore("Rule has not been updated yet")
|
||||
public class OverrideBothEqualsAndHashcodeTest extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
<test-code>
|
||||
<description>hash code only</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>2</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public int hashCode() {}
|
||||
@ -17,6 +18,7 @@ public class Foo {
|
||||
<test-code>
|
||||
<description>equals only</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>2</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public boolean equals(Object other) {}
|
||||
@ -46,6 +48,7 @@ public class Foo {}
|
||||
<test-code>
|
||||
<description>equals sig uses String, not Object</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>5</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public boolean equals(String o) {
|
||||
@ -133,6 +136,7 @@ public class Foo {
|
||||
<test-code>
|
||||
<description>overloaded hashCode, should fail on equals</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>2</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public boolean equals(Object o1) { return false; }
|
||||
@ -156,6 +160,7 @@ public class Foo {
|
||||
<test-code>
|
||||
<description>implements interface other than Comparable, not resolvable</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>2</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo implements C {
|
||||
public boolean equals(Object other) { return false; }
|
||||
@ -167,6 +172,7 @@ public class Foo implements C {
|
||||
<test-code>
|
||||
<description>implements interface other than Comparable, resolvable (#1303 OverrideBothEqualsAndHashcodeRule does not work on class implements resolvable interfaces)</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>2</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo implements Runnable {
|
||||
public boolean equals(Object other) { return false; }
|
||||
|
Reference in New Issue
Block a user