Added ExcessivePublicCountRule

This commit is contained in:
David Renz
2016-04-01 13:33:32 +02:00
parent 1b1f3454d7
commit 1fbfdf3842
4 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,52 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.codesize;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.rule.design.ExcessiveNodeCountRule;
import static apex.jorje.semantic.symbol.type.ModifierTypeInfos.PUBLIC;
import static apex.jorje.semantic.symbol.type.ModifierTypeInfos.STATIC;
import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclarationStatements;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.AccessNode;
import net.sourceforge.pmd.util.NumericConstants;
/**
* @author aglover
* <p/>
* Class Name: ExcessivePublicCount
* <p/>
* Rule attempts to count all public methods and public attributes defined in a class.
* <p/>
* If a class has a high number of public operations, it might be wise to consider whether
* it would be appropriate to divide it into subclasses.
* <p/>
* A large proportion of public members and operations means the class has high potential to be
* affected by external classes. Futhermore, increased effort will be required to
* thoroughly test the class.
*/
public class ExcessivePublicCountRule extends ExcessiveNodeCountRule {
public ExcessivePublicCountRule() {
super(ASTUserClass.class);
setProperty(MINIMUM_DESCRIPTOR, 45d);
}
public Object visit(ASTMethod node, Object data) {
if (node.getNode().getModifiers().has(PUBLIC)) {
return NumericConstants.ONE;
}
return NumericConstants.ZERO;
}
public Object visit(ASTFieldDeclarationStatements node, Object data) {
System.out.println(node.getNode().getModifiers());
if (node.getNode().getModifiers().has(PUBLIC) && !node.getNode().getModifiers().has(STATIC)) {
return NumericConstants.ONE;
}
return NumericConstants.ZERO;
}
}

View File

@ -168,5 +168,34 @@ public class Person { // this is more manageable
]]>
</example>
</rule>
<rule name="ExcessivePublicCount"
since="1.04"
message="This class has a bunch of public methods and attributes"
class="net.sourceforge.pmd.lang.apex.rule.codesize.ExcessivePublicCountRule"
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#ExcessivePublicCount">
<description>
Classes with large numbers of public methods and attributes require disproportionate testing efforts
since combinational side effects grow rapidly and increase risk. Refactoring these classes into
smaller ones not only increases testability and reliability but also allows new variations to be
developed easily.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
public String value;
public Bar something;
public Variable var;
// [... more more public attributes ...]
public void doWork() {}
public void doMoreWork() {}
public void doWorkAgain() {}
// [... more more public methods ...]
}
]]>
</example>
</rule>
</ruleset>

View File

@ -16,6 +16,7 @@ public class CodesizeRulesTest extends SimpleAggregatorTst {
addRule(RULESET, "ExcessiveClassLength");
addRule(RULESET, "ExcessiveParameterList");
addRule(RULESET, "ExcessiveMethodLength");
addRule(RULESET, "ExcessivePublicCount");
addRule(RULESET, "StdCyclomaticComplexity");
}

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data>
<test-code>
<description>Few public fields</description>
<rule-property name="minimum">50</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public int foo;
}
]]></code>
</test-code>
<test-code>
<description>Too many public fields</description>
<rule-property name="minimum">2</rule-property>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public int foo;
public int bif;
public int baz;
public int bof;
}
]]></code>
</test-code>
<test-code>
<description>Static final</description>
<rule-property name="minimum">1</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public static final int foo;
public static final int foo1;
public static final int foo2;
public static final int foo3;
}
]]></code>
</test-code>
<code-fragment id="3 public methods"><![CDATA[
public class Foo {
public int foo1() {return 1;}
public int foo2() {return 1;}
public int foo3() {return 1;}
}
]]></code-fragment>
<test-code>
<description>Some public methods</description>
<rule-property name="minimum">50</rule-property>
<expected-problems>0</expected-problems>
<code-ref id="3 public methods"/>
</test-code>
<test-code>
<description>Reduced minimum</description>
<rule-property name="minimum">2</rule-property>
<expected-problems>1</expected-problems>
<code-ref id="3 public methods"/>
</test-code>
<test-code>
<description>Private fields</description>
<rule-property name="minimum">50</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private static final int foo;
private static final int foo1;
private static final int foo2;
private static final int foo3;
}
]]></code>
</test-code>
<test-code>
<description>Private methods</description>
<rule-property name="minimum">50</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private int foo1() {return 1;}
private int foo2() {return 1;}
private int foo3() {return 1;}
}
]]></code>
</test-code>
</test-data>