[java] MissingOverride: False negative for enum method #3542
Improves type resolution to support enum constants
This commit is contained in:
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user