diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f78c2baa10..24e0613aa7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -41,6 +41,9 @@ datetime field. on the method level. To allow the old behavior, the new property `allowMethodLevelSynchronization` can be enabled. +* The Java rule {% rule "java/design/UseUtilityClass" %} (`java-design`) has a new property `ignoredAnnotations`. + By default, classes that are annotated with Lombok's `@UtilityClass` are ignored now. + ### Fixed Issues * java @@ -48,6 +51,8 @@ datetime field. * java-bestpractices * [#1703](https://github.com/pmd/pmd/issues/1703): \[java] UnusedPrivateField on member annotated with lombok @Delegate * [#1845](https://github.com/pmd/pmd/issues/1845): \[java] Regression in MethodReturnsInternalArray not handling enums +* java-design + * [#1094](https://github.com/pmd/pmd/issues/1094): \[java] UseUtilityClass should be LombokAware * java-multithreading * [#1814](https://github.com/pmd/pmd/issues/1814): \[java] UnsynchronizedStaticFormatter documentation and implementation wrong * [#1815](https://github.com/pmd/pmd/issues/1815): \[java] False negative in UnsynchronizedStaticFormatter diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java index 6273d61bd0..a3fa7780bc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.rule.design; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import net.sourceforge.pmd.lang.ast.Node; @@ -17,24 +19,35 @@ import net.sourceforge.pmd.lang.java.ast.ASTMemberValuePair; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTResultType; -import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; +import net.sourceforge.pmd.lang.java.rule.AbstractLombokAwareRule; -public class UseUtilityClassRule extends AbstractJavaRule { +public class UseUtilityClassRule extends AbstractLombokAwareRule { - public UseUtilityClassRule() { - addRuleChainVisit(ASTClassOrInterfaceBody.class); + @Override + protected Collection defaultSuppressionAnnotations() { + return Arrays.asList("lombok.experimental.UtilityClass"); + } + + @Override + public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { + if (hasIgnoredAnnotation(node)) { + return data; + } + return super.visit(node, data); } @Override public Object visit(ASTClassOrInterfaceBody decl, Object data) { + Object result = super.visit(decl, data); + if (decl.jjtGetParent() instanceof ASTClassOrInterfaceDeclaration) { ASTClassOrInterfaceDeclaration parent = (ASTClassOrInterfaceDeclaration) decl.jjtGetParent(); if (parent.isAbstract() || parent.isInterface() || parent.getSuperClassTypeNode() != null) { - return data; + return result; } - if (isOkUsingLombok(parent)) { - return data; + if (hasLombokNoArgsConstructor(parent)) { + return result; } int i = decl.jjtGetNumChildren(); @@ -81,10 +94,10 @@ public class UseUtilityClassRule extends AbstractJavaRule { addViolation(data, decl); } } - return data; + return result; } - private boolean isOkUsingLombok(ASTClassOrInterfaceDeclaration parent) { + private boolean hasLombokNoArgsConstructor(ASTClassOrInterfaceDeclaration parent) { // check if there's a lombok no arg private constructor, if so skip the rest of the rules ASTAnnotation annotation = parent.getAnnotation("lombok.NoArgsConstructor"); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml index 2540573f5e..a57f064085 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml @@ -360,4 +360,73 @@ public class FooLocal extends ThreadLocal { } ]]> + + + #1094 [java] UseUtilityClass should be LombokAware + 0 + + + + + Inner class in abstract class false-negative + 1 + + + + + Inner class in abstract class false-negative + 1 + + + + + + Inner class in interface false-negative + 1 + + + + + Inner class in sub-class false-negative + 1 + +