Merge branch 'fp-unnecessary-modifier-enum'
This commit is contained in:
@ -13,12 +13,19 @@ This is a minor release.
|
||||
### Table Of Contents
|
||||
|
||||
* [New and noteworthy](#new-and-noteworthy)
|
||||
* [Modified Rules](#modified-rules)
|
||||
* [Fixed Issues](#fixed-issues)
|
||||
* [API Changes](#api-changes)
|
||||
* [External Contributions](#external-contributions)
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Modified Rules
|
||||
|
||||
* The Java rule [UnnecessaryModifier](pmd_rules_java_codestyle.html#unnecessarymodifier) (`java-codestyle`)
|
||||
now detects enum constrcutors with explicit `private` modifier. The rule now produces better error messages
|
||||
letting you know exactly which modifiers are redundant at each declaration.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* all
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public class ASTAnnotationMethodDeclaration extends AbstractJavaAccessNode {
|
||||
public class ASTAnnotationMethodDeclaration extends AbstractMethodLikeNode {
|
||||
public ASTAnnotationMethodDeclaration(int id) {
|
||||
super(id);
|
||||
}
|
||||
@ -19,6 +19,12 @@ public class ASTAnnotationMethodDeclaration extends AbstractJavaAccessNode {
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodLikeKind getKind() {
|
||||
return MethodLikeKind.METHOD;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* JavaCC - OriginalChecksum=f6dd440446f8aa5c9c191ae760080ee0 (do not edit this
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
@ -26,9 +27,6 @@ public abstract class AbstractAnyTypeDeclaration extends AbstractJavaAccessTypeN
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this type declaration is nested inside an interface, class or annotation.
|
||||
*/
|
||||
@Override
|
||||
public final boolean isNested() {
|
||||
return jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration
|
||||
@ -36,6 +34,46 @@ public abstract class AbstractAnyTypeDeclaration extends AbstractJavaAccessTypeN
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the enclosing type of this type declaration
|
||||
* is any of the given kinds. If this declaration is a top-level
|
||||
* declaration, returns false. This won't consider anonymous classes
|
||||
* until #905 is tackled. TODO 7.0.0
|
||||
*
|
||||
* @param kinds Kinds to test
|
||||
*/
|
||||
// TODO 7.0.0 move that up to ASTAnyTypeDeclaration
|
||||
public final boolean enclosingTypeIsA(TypeKind... kinds) {
|
||||
|
||||
ASTAnyTypeDeclaration parent = getEnclosingTypeDeclaration();
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TypeKind k : kinds) {
|
||||
if (parent.getTypeKind() == k) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the enclosing type of this type, if it is nested.
|
||||
* Otherwise returns null. This won't consider anonymous classes
|
||||
* until #905 is tackled. TODO 7.0.0
|
||||
*/
|
||||
public final ASTAnyTypeDeclaration getEnclosingTypeDeclaration() {
|
||||
if (!isNested()) {
|
||||
return null;
|
||||
}
|
||||
Node parent = getNthParent(3);
|
||||
|
||||
return parent instanceof ASTAnyTypeDeclaration ? (ASTAnyTypeDeclaration) parent : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JavaTypeQualifiedName getQualifiedName() {
|
||||
return qualifiedName;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1634,7 +1634,7 @@ public class Foo {
|
||||
<rule name="UnnecessaryModifier"
|
||||
language="java"
|
||||
since="1.02"
|
||||
message="Avoid modifiers which are implied by the context"
|
||||
message="Unnecessary modifier{0} on {1} ''{2}''{3}"
|
||||
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryModifierRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarymodifier">
|
||||
<description>
|
||||
|
@ -195,6 +195,10 @@ public class Foo {
|
||||
Unneeded 'public static final' in interface field inside another interface
|
||||
]]></description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'public' on interface 'Bar': members of interface types are implicitly public</message>
|
||||
<message>Unnecessary modifiers 'public static final' on field 'X': the field is declared in an interface type</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public interface Foo {
|
||||
public interface Bar {
|
||||
@ -205,6 +209,23 @@ public interface Foo {
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Unneeded 'public static final' in annotation field inside another interface
|
||||
]]></description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'public' on annotation 'Bar': members of interface types are implicitly public</message>
|
||||
<message>Unnecessary modifiers 'public static final' on field 'X': the field is declared in an annotation type</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public interface Foo {
|
||||
public @interface Bar {
|
||||
public static final int X = 0;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
OK in interface field inside another interface
|
||||
]]></description>
|
||||
<expected-problems>0</expected-problems>
|
||||
@ -303,6 +324,9 @@ public enum TestEnum {
|
||||
<test-code>
|
||||
<description>Unnecessary public on annotation element</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'public' on method 'message': the method is declared in an annotation type</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public @interface TestAnnotation {
|
||||
public String message();
|
||||
@ -312,6 +336,9 @@ public @interface TestAnnotation {
|
||||
<test-code>
|
||||
<description>Unnecessary abstract on annotation element</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'abstract' on method 'message': the method is declared in an annotation type</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public @interface TestAnnotation {
|
||||
abstract String message();
|
||||
@ -387,7 +414,11 @@ public @interface TestAnnotation {
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Unnecessary static on annotation nested enum</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'public' on enum 'Inner': the enum is declared in an annotation type</message>
|
||||
<message>Unnecessary modifier 'static' on enum 'Inner': nested enums are implicitly static</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public @interface TestAnnotation {
|
||||
public static enum Inner {
|
||||
@ -397,7 +428,11 @@ public @interface TestAnnotation {
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Unnecessary static on interface nested enum</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'public' on enum 'Inner': the enum is declared in an interface type</message>
|
||||
<message>Unnecessary modifier 'static' on enum 'Inner': nested enums are implicitly static</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public interface TestInterface {
|
||||
public static enum Inner {
|
||||
@ -408,6 +443,9 @@ public interface TestInterface {
|
||||
<test-code>
|
||||
<description>Unnecessary static on class nested enum</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'static' on enum 'Inner': nested enums are implicitly static</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class TestClass {
|
||||
public static enum Inner {
|
||||
@ -418,6 +456,9 @@ public class TestClass {
|
||||
<test-code>
|
||||
<description>Unnecessary abstract on interface</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'abstract' on interface 'TestInterface': interface types are implicitly abstract</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public abstract interface TestInterface {
|
||||
}
|
||||
@ -426,6 +467,9 @@ public abstract interface TestInterface {
|
||||
<test-code>
|
||||
<description>Unnecessary abstract on annotation</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'abstract' on annotation 'TestAnnotation': annotations types are implicitly abstract</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public abstract @interface TestAnnotation {
|
||||
}
|
||||
@ -443,9 +487,7 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
final and non-final methods mixed
|
||||
]]></description>
|
||||
<description>final and non-final methods mixed</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@ -459,6 +501,9 @@ public class Foo {
|
||||
final method on a final class
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on method 'foo': the method is already in a final class</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public final class Foo {
|
||||
public final void foo() { }
|
||||
@ -470,6 +515,9 @@ public final class Foo {
|
||||
mixed final and non-final methods on final class
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on method 'foo': the method is already in a final class</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public final class Foo {
|
||||
public final void foo() { }
|
||||
@ -509,6 +557,9 @@ public final class Foo {
|
||||
final method in inner final class
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on method 'buz': the method is already in a final class</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public final class Foo {
|
||||
public final class Bar {
|
||||
@ -539,6 +590,9 @@ public final class InboxContents2 {
|
||||
<test-code>
|
||||
<description>Unnecessary final of private method</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on method 'getValue': private methods cannot be overridden</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class TestClass {
|
||||
private final int getValue() {
|
||||
@ -550,6 +604,9 @@ public class TestClass {
|
||||
<test-code>
|
||||
<description>Unnecessary final of enum method</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on method 'magic': an anonymous class cannot be extended</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public enum Foo {
|
||||
BAR {
|
||||
@ -578,6 +635,9 @@ public class Foo {
|
||||
<test-code>
|
||||
<description>Unnecessary final of try-with-resources resource</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'final' on resource specification 'fw': resource specifications are implicitly final</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void stuff() {
|
||||
@ -595,6 +655,24 @@ public class Foo {
|
||||
class Foo {
|
||||
@Bar
|
||||
final void method() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Private constructor of enum</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>Unnecessary modifier 'private' on constructor 'Foo(String)': enum constructors are implicitly private</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
enum Foo {
|
||||
BAR("bar");
|
||||
|
||||
private String name;
|
||||
|
||||
private Foo(String s) {
|
||||
name = s;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user