[java] Make CommentDefaultAccessModifier work for top-level classes, enums and annotations
This commit is contained in:
@ -11,10 +11,12 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
|
||||
@ -84,11 +86,28 @@ public class CommentDefaultAccessModifierRule extends AbstractIgnoredAnnotationR
|
||||
return super.visit(decl, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTAnnotationTypeDeclaration decl, final Object data) {
|
||||
if (!decl.isNested() && shouldReportTypeDeclaration(decl)) { // check for top-level annotation declarations
|
||||
addViolationWithMessage(data, decl, String.format(MESSAGE, decl.getImage(), "top-level annotation"));
|
||||
}
|
||||
return super.visit(decl, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTEnumDeclaration decl, final Object data) {
|
||||
if (!decl.isNested() && shouldReportTypeDeclaration(decl)) { // check for top-level enums
|
||||
addViolationWithMessage(data, decl, String.format(MESSAGE, decl.getImage(), "top-level enum"));
|
||||
}
|
||||
return super.visit(decl, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTClassOrInterfaceDeclaration decl, final Object data) {
|
||||
// check for nested classes
|
||||
if (decl.isNested() && shouldReport(decl)) {
|
||||
if (decl.isNested() && shouldReport(decl)) { // check for nested classes
|
||||
addViolationWithMessage(data, decl, String.format(MESSAGE, decl.getImage(), "nested class"));
|
||||
} else if (!decl.isNested() && shouldReportTypeDeclaration(decl)) { // and for top-level ones
|
||||
addViolationWithMessage(data, decl, String.format(MESSAGE, decl.getImage(), "top-level class"));
|
||||
}
|
||||
return super.visit(decl, data);
|
||||
}
|
||||
@ -106,14 +125,15 @@ public class CommentDefaultAccessModifierRule extends AbstractIgnoredAnnotationR
|
||||
.getFirstParentOfType(AbstractAnyTypeDeclaration.class);
|
||||
|
||||
boolean isConcreteClass = parentClassOrInterface.getTypeKind() == ASTAnyTypeDeclaration.TypeKind.CLASS;
|
||||
boolean isEnumConstructor = parentClassOrInterface.getTypeKind() == ASTAnyTypeDeclaration.TypeKind.ENUM
|
||||
&& decl instanceof ASTConstructorDeclaration;
|
||||
|
||||
// ignore if it's an Interface / Annotation / Enum constructor
|
||||
return isConcreteClass && !isEnumConstructor
|
||||
// check if the field/method/nested class has a default access
|
||||
// modifier
|
||||
&& decl.isPackagePrivate()
|
||||
// ignore if it's an Interface / Annotation
|
||||
return isConcreteClass && shouldReportTypeDeclaration(decl);
|
||||
}
|
||||
|
||||
private boolean shouldReportTypeDeclaration(final AbstractJavaAccessNode decl) {
|
||||
// check if the class/method/field has a default access
|
||||
// modifier
|
||||
return decl.isPackagePrivate()
|
||||
// if is a default access modifier check if there is a comment
|
||||
// in this line
|
||||
&& !interestingLineNumberComments.contains(decl.getBeginLine())
|
||||
|
@ -402,7 +402,7 @@ public class Éléphant {}
|
||||
message="Missing commented default access modifier"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier">
|
||||
<description>
|
||||
To avoid mistakes if we want that a Method, Constructor, Field or Nested class have a default access modifier
|
||||
To avoid mistakes if we want that an Annotation, Class, Enum, Method, Constructor or Field have a default access modifier
|
||||
we must add a comment at the beginning of it's declaration.
|
||||
By default the comment must be `/* default */` or `/* package */`, if you want another, you have to provide a regular expression.
|
||||
This rule ignores by default all cases that have a @VisibleForTesting annotation. Use the
|
||||
|
@ -115,6 +115,66 @@ public class Foo {
|
||||
<code-ref id="nested-class-with-default-access-modifier"/>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="top-level-annotations-with-default-access-modifier"><![CDATA[
|
||||
@interface Bar {}
|
||||
|
||||
public @interface Foo {}
|
||||
|
||||
@SomeAnnotation
|
||||
@interface Baz {}
|
||||
|
||||
@VisibleForTesting
|
||||
@interface Foobar {}
|
||||
|
||||
/* default */ @interface FoobarWithComment {}
|
||||
]]></code-fragment>
|
||||
<test-code>
|
||||
<description>Top-level annotations with default access modifier</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>1,6</expected-linenumbers>
|
||||
<code-ref id="top-level-annotations-with-default-access-modifier"/>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="top-level-enums-with-default-access-modifier"><![CDATA[
|
||||
enum Bar {}
|
||||
|
||||
public enum Foo {}
|
||||
|
||||
@SomeAnnotation
|
||||
enum Baz {}
|
||||
|
||||
@VisibleForTesting
|
||||
enum Foobar {}
|
||||
|
||||
/* default */ enum FoobarWithComment {}
|
||||
]]></code-fragment>
|
||||
<test-code>
|
||||
<description>Top-level enums with default access modifier</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>1,6</expected-linenumbers>
|
||||
<code-ref id="top-level-enums-with-default-access-modifier"/>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="top-level-classes-with-default-access-modifier"><![CDATA[
|
||||
class Bar {}
|
||||
|
||||
public class Foo {}
|
||||
|
||||
@SomeAnnotation
|
||||
class Baz {}
|
||||
|
||||
@VisibleForTesting
|
||||
class Foobar {}
|
||||
|
||||
/* default */ class FoobarWithComment {}
|
||||
]]></code-fragment>
|
||||
<test-code>
|
||||
<description>Top-level classes with default access modifier</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>1,6</expected-linenumbers>
|
||||
<code-ref id="top-level-classes-with-default-access-modifier"/>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="own-regex-to-default-access-modifier-rule"><![CDATA[
|
||||
public class Foo {
|
||||
/* default */ final String stringValue = "stringValue";
|
||||
|
Reference in New Issue
Block a user