Merge branch 'pr-1134'
This commit is contained in:
+23
-3
@@ -8,11 +8,13 @@ import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTInitializer;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.AccessNode;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.properties.PropertyDescriptor;
|
||||
@@ -31,7 +33,7 @@ public class ClassNamingConventionsRule extends AbstractJavaRule {
|
||||
private static final RegexProperty INTERFACE_REGEX = defaultProp("interface").build();
|
||||
private static final RegexProperty ENUMERATION_REGEX = defaultProp("enum").build();
|
||||
private static final RegexProperty ANNOTATION_REGEX = defaultProp("annotation").build();
|
||||
private static final RegexProperty UTILITY_CLASS_REGEX = defaultProp("utility class").defaultValue("[A-Z][a-zA-Z]+Util").build();
|
||||
private static final RegexProperty UTILITY_CLASS_REGEX = defaultProp("utility class").defaultValue("[A-Z][a-zA-Z0-9]+(Utils?|Helper)").build();
|
||||
|
||||
|
||||
public ClassNamingConventionsRule() {
|
||||
@@ -58,7 +60,6 @@ public class ClassNamingConventionsRule extends AbstractJavaRule {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This could probably be moved to ClassOrInterfaceDeclaration
|
||||
// to share the implementation and be used from XPath
|
||||
private boolean isUtilityClass(ASTAnyTypeDeclaration node) {
|
||||
@@ -81,7 +82,7 @@ public class ClassNamingConventionsRule extends AbstractJavaRule {
|
||||
switch (decl.getKind()) {
|
||||
case FIELD:
|
||||
case METHOD:
|
||||
hasAny = true;
|
||||
hasAny = isNonPrivate(decl) && !isMainMethod(decl);
|
||||
if (!((AccessNode) decl.getDeclarationNode()).isStatic()) {
|
||||
return false;
|
||||
}
|
||||
@@ -101,6 +102,25 @@ public class ClassNamingConventionsRule extends AbstractJavaRule {
|
||||
return hasAny;
|
||||
}
|
||||
|
||||
private boolean isNonPrivate(ASTAnyTypeBodyDeclaration decl) {
|
||||
return !((AccessNode) decl.getDeclarationNode()).isPrivate();
|
||||
}
|
||||
|
||||
|
||||
private boolean isMainMethod(ASTAnyTypeBodyDeclaration bodyDeclaration) {
|
||||
if (DeclarationKind.METHOD != bodyDeclaration.getKind()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ASTMethodDeclaration decl = (ASTMethodDeclaration) bodyDeclaration.getDeclarationNode();
|
||||
|
||||
return decl.isStatic()
|
||||
&& "main".equals(decl.getMethodName())
|
||||
&& decl.getResultType().isVoid()
|
||||
&& decl.getFormalParameters().getParameterCount() == 1
|
||||
&& String[].class.equals(decl.getFormalParameters().iterator().next().getType());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
||||
|
||||
@@ -387,8 +387,8 @@ public class Foo extends Bar{
|
||||
<example>
|
||||
<![CDATA[
|
||||
// This is Pascal case, the recommended naming convention in Java
|
||||
// Note that the default values of this rule don't allow numbers,
|
||||
// underscores, or accented characters in type names
|
||||
// Note that the default values of this rule don't allow underscores
|
||||
// or accented characters in type names
|
||||
public class FooBar {}
|
||||
|
||||
// You may want abstract classes to be named 'AbstractXXX',
|
||||
|
||||
+42
-2
@@ -53,7 +53,7 @@
|
||||
<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-Z]+Util'</message>
|
||||
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z0-9]+(Utils?|Helper)'</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@@ -144,7 +144,7 @@
|
||||
<description>Class with only static members except constructors should be a utility class</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z]+Util'</message>
|
||||
<message>The utility class name 'Foo' doesn't match '[A-Z][a-zA-Z0-9]+(Utils?|Helper)'</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@@ -215,4 +215,44 @@
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Class with only main method should not be utility class</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class MyException {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// whitelisted
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Class with only main method should not be utility class - varargs case</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class MyException {
|
||||
|
||||
public static void main(String... args) {
|
||||
// whitelisted
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Class with main method and private static fields should not be utility class</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class MyException {
|
||||
private static final String foo = "FOOO";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// whitelisted
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
</test-data>
|
||||
|
||||
Reference in New Issue
Block a user