Merge pull request #3584 from adangel:issue-3563-classnamingconventions

[java] ClassNamingConventions: Disable utilityClassPattern by default
#3584
This commit is contained in:
Andreas Dangel
2021-10-29 19:16:58 +02:00
4 changed files with 67 additions and 11 deletions

View File

@@ -112,6 +112,29 @@ This is a {{ site.pmd.release_type }} release.
}
```
* The Java rule {% rule java/codestyle/ClassNamingConventions %} uses a different default value of the
property `utilityClassPattern`: This rule was detecting utility classes by default since PMD 6.3.0
and enforcing the naming convention that utility classes has to be suffixed with Util or Helper or Constants.
However this turned out to be not so useful as a default configuration, as there is no standard
naming convention for utility classes.
With PMD 6.40.0, the default value of this property has been changed to `[A-Z][a-zA-Z0-9]*`
(Pascal case), effectively disabling the special handling of utility classes. This is the same default
pattern used for concrete classes.
This means, that the feature to enforce a naming convention for utility classes is now a opt-in
feature and can be enabled on demand.
To use the old behaviour, the property needs to be configured as follows:
```xml
<rule ref="category/java/codestyle.xml/ClassNamingConventions">
<properties>
<property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)" />
</properties>
</rule>
### Fixed Issues
* apex
@@ -126,6 +149,9 @@ This is a {{ site.pmd.release_type }} release.
* [#3579](https://github.com/pmd/pmd/issues/3579): \[apex] ApexCRUDViolation: false negative with undelete
* java-bestpractices
* [#3542](https://github.com/pmd/pmd/issues/3542): \[java] MissingOverride: False negative for enum method
* java-codestyle
* [#1595](https://github.com/pmd/pmd/issues/1595): \[java] Discuss default for utility classes in ClassNamingConventions
* [#3563](https://github.com/pmd/pmd/issues/3563): \[java] The ClassNamingConventionsRule false-positive's on the class name "Constants"
* java-errorprone
* [#3560](https://github.com/pmd/pmd/issues/3560): \[java] InvalidLogMessageFormat: False positive with message and exception in a block inside a lambda
* java-performance

View File

@@ -30,7 +30,7 @@ public class ClassNamingConventionsRule extends AbstractNamingConventionRule<AST
private final PropertyDescriptor<Pattern> interfaceRegex = defaultProp("interface").build();
private final PropertyDescriptor<Pattern> enumerationRegex = defaultProp("enum").build();
private final PropertyDescriptor<Pattern> annotationRegex = defaultProp("annotation").build();
private final PropertyDescriptor<Pattern> utilityClassRegex = defaultProp("utility class").defaultValue("[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)").build();
private final PropertyDescriptor<Pattern> utilityClassRegex = defaultProp("utility class").build();
public ClassNamingConventionsRule() {

View File

@@ -398,8 +398,16 @@ public class Foo extends Bar{
specific kind (e.g. enum or interface). Each regex can be configured through
properties.
By default this rule uses the standard Java naming convention (Pascal case),
and reports utility class names not ending with 'Util'.
By default this rule uses the standard Java naming convention (Pascal case).
The rule can detect utility classes and enforce a different naming convention
on those. E.g. setting the property `utilityClassPattern` to
`[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)` reports any utility class, whose name
does not end in "Util(s)", "Helper" or "Constants".
For this rule, a utility class is defined as: a concrete class that does not
inherit from a super class or implement any interface and only has static fields
or methods.
</description>
<priority>1</priority>
<example>

View File

@@ -47,13 +47,7 @@ public class foo {
]]></code>
</test-code>
<test-code>
<description>Utility class convention</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)'</message>
</expected-messages>
<code><![CDATA[
<code-fragment id="utility-class"><![CDATA[
public class Foo {
static final int ZERO = 0;
@@ -68,11 +62,28 @@ public class Foo {
}
}
]]></code>
]]></code-fragment>
<test-code>
<description>Utility class convention (default) - #3563</description>
<expected-problems>0</expected-problems>
<code-ref id="utility-class"/>
</test-code>
<test-code>
<description>Utility class convention</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>1</expected-problems>
<expected-linenumbers>1</expected-linenumbers>
<expected-messages>
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)'</message>
</expected-messages>
<code-ref id="utility-class"/>
</test-code>
<test-code>
<description>Class with only empty decls should not be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
@@ -83,6 +94,7 @@ public class Foo {
<test-code>
<description>Class with some instance fields should not be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Position {
@@ -105,6 +117,7 @@ public class Position {
<test-code>
<description>Class with static initializer alone should not be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
@@ -119,6 +132,7 @@ public class Foo {
<test-code>
<description>Class with instance initializer should not be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
@@ -140,6 +154,7 @@ public class Foo {
<test-code>
<description>Class with only static members except constructors should be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>1</expected-problems>
<expected-messages>
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)'</message>
@@ -168,6 +183,7 @@ public class Foo {
<test-code>
<description>Class with only constructors should not be a utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
@@ -190,6 +206,7 @@ public class Md5Checksum {
<test-code>
<description>Class extending another class should not be utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class StringList extends ArrayList<String> {
@@ -202,6 +219,7 @@ public class StringList extends ArrayList<String> {
<test-code>
<description>Class extending another class should not be utility class 2</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
// I couldn't reproduce the original failure, but we can use another regression test.
@@ -215,6 +233,7 @@ public class MyException extends RuntimeException {
<test-code>
<description>Class with only main method should not be utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class MyException {
@@ -228,6 +247,7 @@ public class MyException {
<test-code>
<description>Class with only main method should not be utility class - varargs case</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class MyException {
@@ -241,6 +261,7 @@ public class MyException {
<test-code>
<description>Class with main method and private static fields should not be utility class</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class MyException {
@@ -255,6 +276,7 @@ public class MyException {
<test-code>
<description>Utility class can have name constants</description>
<rule-property name="utilityClassPattern">[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class MyConstants {