- versions used (SonarQube 6.7, SonarAnalyzer (Java))
In the example below, the rule will complain on C.
The reason is that as soon as a parent with final equals method is found the rule should go out of the while loop. The current implementation continues to check the parents, even after having found a final equals.
see source code
public class A {
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
public class B extends A {
@Override
public final boolean equals(Object obj) {
return super.equals(obj);
}
}
public class C extends B {
private String newField;
}
A possible fix could be
private static boolean parentClassImplementsEquals(ClassTree tree) {
TypeTree superClass = tree.superClass();
if (superClass != null) {
Type superClassType = superClass.symbolType();
while (superClassType.symbol().isTypeSymbol() && !superClassType.is("java.lang.Object")) {
Symbol.TypeSymbol superClassSymbol = superClassType.symbol();
if (hasNotFinalEqualsMethod(superClassSymbol)) {
return true;
} else if (hasFinalEqualsMethod(superClassSymbol)) {
return false;
}
superClassType = superClassSymbol.superClass();
}
}
return false;
}
private static boolean hasFinalEqualsMethod(Symbol.TypeSymbol superClassSymbol) {
return superClassSymbol.lookupSymbols("equals").stream().anyMatch(symbol -> EQUALS_MATCHER.matches(symbol) && symbol.isFinal());
}
Feel free to rewrite this to make it clearer/more performant!