[java] MissingOverride: False negative for enum method #3542

Improves type resolution to support enum constants
This commit is contained in:
Andreas Dangel
2021-10-07 18:31:03 +02:00
parent c9077e19ea
commit a1a358619c
7 changed files with 103 additions and 22 deletions

View File

@ -19,7 +19,7 @@ import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName;
*
* </pre>
*/
public class ASTEnumConstant extends AbstractJavaNode implements JavaQualifiableNode {
public class ASTEnumConstant extends AbstractJavaTypeNode implements JavaQualifiableNode {
private JavaTypeQualifiedName qualifiedName;

View File

@ -86,15 +86,14 @@ public class MissingOverrideRule extends AbstractJavaRule {
@Override
public Object visit(ASTEnumConstant node, Object data) {
// FIXME, ASTEnumConstant needs typeres support!
// if (node.isAnonymousClass()) {
// currentExploredClass.push(node.getType());
// }
if (node.isAnonymousClass()) {
currentLookup.push(getMethodLookup(node.getType()));
}
super.visit(node, data);
// if (node.isAnonymousClass()) {
// currentExploredClass.pop();
// }
if (node.isAnonymousClass()) {
currentLookup.pop();
}
return data;
}

View File

@ -40,6 +40,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement;
import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
@ -48,6 +49,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalOrExpression;
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant;
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
import net.sourceforge.pmd.lang.java.ast.ASTExclusiveOrExpression;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
@ -258,6 +260,26 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
return data;
}
@Override
public Object visit(ASTEnumConstant node, Object data) {
super.visit(node, data);
if (node.getNumChildren() > 0 && node.getFirstChildOfType(ASTClassOrInterfaceBody.class) != null) {
ASTEnumDeclaration enumDecl = (ASTEnumDeclaration) node.getParent().getParent();
int clazznumber = node.getIndexInParent() + 1;
JavaTypeDefinition enumType = enumDecl.getTypeDefinition();
if (enumType != null) {
String constantType = enumType.getType().getName() + "$" + clazznumber;
Class<?> enumConstantClass = pmdClassLoader.loadClassOrNull(constantType);
if (enumConstantClass != null) {
node.setTypeDefinition(JavaTypeDefinition.forClass(enumConstantClass));
}
}
}
return data;
}
@Override
public Object visit(ASTClassOrInterfaceType node, Object data) {
super.visit(node, data);
@ -265,7 +287,7 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
String typeName = node.getImage();
if (node.isAnonymousClass()) {
QualifiableNode parent = node.getFirstParentOfAnyType(ASTAllocationExpression.class, ASTEnumConstant.class);
QualifiableNode parent = node.getFirstParentOfType(ASTAllocationExpression.class);
if (parent != null) {
typeName = parent.getQualifiedName().toString();

View File

@ -0,0 +1,28 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.bestpractices.missingoverride;
public enum EnumToString {
sub_EnumClazz {
// missing @Override
public String toString() {
return "test";
}
// missing @Override
public void notOverride() {
System.out.println("test");
}
};
// missing @Override
public String toString() {
return "test";
}
public void notOverride() {
System.out.println("test");
}
}

View File

@ -10,15 +10,18 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices.missingoverride;
*/
public enum EnumWithAnonClass {
Foo {
@Override
// missing
public String toString() {
return super.toString();
}
// missing
public String getSomething() {
return null;
}
};
public Object getSomething() {
return null;
}
}

View File

@ -202,17 +202,13 @@ public class ConcreteClassArrayParams extends AbstractClass {
]]></code>
</test-code>
<test-code regressionTest="false"> <!-- FIXME bug in typeres, anon constants are not resolved -->
<description>Consider enum anon class</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>10</expected-linenumbers>
<test-code>
<description>Consider enum anon class (#3542)</description>
<expected-problems>2</expected-problems>
<expected-linenumbers>6,11</expected-linenumbers>
<code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.bestpractices.missingoverride;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.metrics.Metric;
import net.sourceforge.pmd.lang.metrics.MetricKey;
public enum EnumWithAnonClass {
Foo {
// missing
@ -220,14 +216,12 @@ public enum EnumWithAnonClass {
return super.toString();
}
// missing
public String getSomething() {
return null;
}
};
public Object getSomething() {
return null;
}
@ -565,4 +559,36 @@ public record Point(int x, int y) {
]]></code>
<source-type>java 16</source-type>
</test-code>
<test-code>
<description>[java] MissingOverride: False negative for enum method #3542</description>
<expected-problems>3</expected-problems>
<expected-linenumbers>6,11,17</expected-linenumbers>
<code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.bestpractices.missingoverride;
public enum EnumToString {
sub_EnumClazz {
// missing @Override
public String toString() {
return "test";
}
// missing @Override
public void notOverride() {
System.out.println("test");
}
};
// missing @Override
public String toString() {
return "test";
}
public void notOverride() {
System.out.println("test");
}
}
]]></code>
</test-code>
</test-data>