forked from phoedos/pmd
Merge branch 'pr-1155'
This commit is contained in:
@ -27,7 +27,6 @@ This is a minor release.
|
||||
letting you know exactly which modifiers are redundant at each declaration.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* all
|
||||
* [#1168](https://github.com/pmd/pmd/issues/1168): \[core] xml renderer schema definitions (#538) break included xslt files
|
||||
* ecmascript
|
||||
@ -36,6 +35,7 @@ This is a minor release.
|
||||
* [#651](https://github.com/pmd/pmd/issues/651): \[java] SwitchStmtsShouldHaveDefault should be aware of enum types
|
||||
* [#869](https://github.com/pmd/pmd/issues/869): \[java] GuardLogStatement false positive on return statements and Math.log
|
||||
* java-codestyle
|
||||
* [#667](https://github.com/pmd/pmd/issues/667): [java] Make AtLeastOneConstructor Lombok-aware
|
||||
* [#1154](https://github.com/pmd/pmd/pull/1154): [java] CommentDefaultAccessModifierRule FP with nested enums
|
||||
* [#1158](https://github.com/pmd/pmd/issues/1158): \[java] Fix IdenticalCatchBranches false positive
|
||||
* xml
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -33,9 +33,7 @@ public class UnusedPrivateMethodRule extends AbstractIgnoredAnnotationRule {
|
||||
|
||||
@Override
|
||||
protected Collection<String> defaultSuppressionAnnotations() {
|
||||
Collection<String> defaultValues = new ArrayList<>();
|
||||
defaultValues.add("java.lang.Deprecated");
|
||||
return defaultValues;
|
||||
return Collections.singletonList("java.lang.Deprecated");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.codestyle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractIgnoredAnnotationRule;
|
||||
import net.sourceforge.pmd.lang.java.rule.design.UseUtilityClassRule;
|
||||
|
||||
/**
|
||||
* This rule detects non-static classes with no constructors;
|
||||
* requiring even the default constructor to be explicit.
|
||||
* It ignores classes with solely static methods,
|
||||
* use {@link UseUtilityClassRule} to flag those.
|
||||
*/
|
||||
public class AtLeastOneConstructorRule extends AbstractIgnoredAnnotationRule {
|
||||
|
||||
public AtLeastOneConstructorRule() {
|
||||
addRuleChainVisit(ASTClassOrInterfaceDeclaration.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<String> defaultSuppressionAnnotations() {
|
||||
return Arrays.asList("lombok.Data",
|
||||
"lombok.Value",
|
||||
"lombok.Builder",
|
||||
"lombok.NoArgsConstructor",
|
||||
"lombok.RequiredArgsConstructor",
|
||||
"lombok.AllArgsConstructorAtLeastOneConstructor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTClassOrInterfaceDeclaration node, final Object data) {
|
||||
// Ignore interfaces / static classes / classes that have a constructor / classes ignored through annotations
|
||||
if (node.isInterface() || node.isStatic() || node.hasDescendantOfType(ASTConstructorDeclaration.class)
|
||||
|| hasIgnoredAnnotation(node)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
boolean atLeastOneMember = false;
|
||||
|
||||
// Do we have any non-static methods?
|
||||
for (final ASTMethodDeclaration m : node.findDescendantsOfType(ASTMethodDeclaration.class)) {
|
||||
if (!m.isStatic()) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
atLeastOneMember = true;
|
||||
}
|
||||
|
||||
// .. or fields?
|
||||
for (final ASTFieldDeclaration f : node.findDescendantsOfType(ASTFieldDeclaration.class)) {
|
||||
if (!f.isStatic()) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
atLeastOneMember = true;
|
||||
}
|
||||
|
||||
// Class has no declared members
|
||||
if (!atLeastOneMember) {
|
||||
addViolation(data, node);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.codestyle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
@ -26,7 +26,7 @@ public class UnnecessaryConstructorRule extends AbstractIgnoredAnnotationRule {
|
||||
|
||||
@Override
|
||||
protected Collection<String> defaultSuppressionAnnotations() {
|
||||
return Arrays.asList("javax.inject.Inject");
|
||||
return Collections.singletonList("javax.inject.Inject");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,28 +49,15 @@ public abstract class Foo { // should be AbstractFoo
|
||||
language="java"
|
||||
since="1.04"
|
||||
message="Each class should declare at least one constructor"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
class="net.sourceforge.pmd.lang.java.rule.codestyle.AtLeastOneConstructorRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#atleastoneconstructor">
|
||||
<description>
|
||||
Each class should declare at least one constructor.
|
||||
< to detect those.
|
||||
]]>
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration[
|
||||
not(ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)
|
||||
and
|
||||
(@Static = 'false')
|
||||
and
|
||||
(count(./descendant::MethodDeclaration[@Static = 'true']) < 1)
|
||||
]
|
||||
[@Interface='false']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
|
@ -100,8 +100,8 @@ skip classes with only static methods
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public static class Foo {
|
||||
public static void method() {}
|
||||
public static void otherMethods() {}
|
||||
public static void method() {}
|
||||
public static void otherMethods() {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
@ -113,6 +113,37 @@ public class TestAtLeastOneConstructor {
|
||||
public void NotStatic() {
|
||||
System.out.println("This class should have a constructor");
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Ignore classes with lombok-generated constructors</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class TestAtLeastOneConstructor {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Report classes with at least one non-static method</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class TestAtLeastOneConstructor {
|
||||
public static void foo() { }
|
||||
public void bar () { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>Report classes with at least one non-static field</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class TestAtLeastOneConstructor {
|
||||
public int bar;
|
||||
public static void foo() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user