Removed NcssCountRules and NPathComplexityRule
This commit is contained in:
@ -1,130 +0,0 @@
|
||||
/**
|
||||
* 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.ASTBreakStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTForEachStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTForLoopStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTIfBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTIfElseBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTReturnStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTThrowStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTTryCatchFinallyBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTWhileLoopStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.rule.AbstractStatisticalApexRule;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.stat.DataPoint;
|
||||
import net.sourceforge.pmd.util.NumericConstants;
|
||||
|
||||
/**
|
||||
* Abstract superclass for NCSS counting methods. Counts tokens according to
|
||||
* <a href="http://www.kclee.de/clemens/java/javancss/">JavaNCSS rules</a>.
|
||||
*
|
||||
* @author ported from original of Jason Bennett
|
||||
*/
|
||||
public abstract class AbstractNcssCountRule extends AbstractStatisticalApexRule {
|
||||
|
||||
private Class<?> nodeClass;
|
||||
|
||||
/**
|
||||
* Count the nodes of the given type using NCSS rules.
|
||||
*
|
||||
* @param nodeClass
|
||||
* class of node to count
|
||||
*/
|
||||
protected AbstractNcssCountRule(Class<?> nodeClass) {
|
||||
this.nodeClass = nodeClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ApexNode<?> node, Object data) {
|
||||
int numNodes = 0;
|
||||
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
ApexNode<?> n = (ApexNode<?>) node.jjtGetChild(i);
|
||||
Integer treeSize = (Integer) n.jjtAccept(this, data);
|
||||
numNodes += treeSize.intValue();
|
||||
}
|
||||
|
||||
if (this.nodeClass.isInstance(node)) {
|
||||
// Add 1 to account for base node
|
||||
numNodes++;
|
||||
DataPoint point = new DataPoint();
|
||||
point.setNode(node);
|
||||
point.setScore(1.0 * numNodes);
|
||||
point.setMessage(getMessage());
|
||||
addDataPoint(point);
|
||||
}
|
||||
|
||||
return Integer.valueOf(numNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of children of the given Java node. Adds one to count
|
||||
* the node itself.
|
||||
*
|
||||
* @param node
|
||||
* java node having children counted
|
||||
* @param data
|
||||
* node data
|
||||
* @return count of the number of children of the node, plus one
|
||||
*/
|
||||
protected Integer countNodeChildren(Node node, Object data) {
|
||||
Integer nodeCount = null;
|
||||
int lineCount = 0;
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
nodeCount = (Integer) ((ApexNode<?>) node.jjtGetChild(i)).jjtAccept(this, data);
|
||||
lineCount += nodeCount.intValue();
|
||||
}
|
||||
return ++lineCount;
|
||||
}
|
||||
|
||||
public Object visit(ASTForEachStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
public Object visit(ASTForLoopStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
public Object visit(ASTIfBlockStatement node, Object data) {
|
||||
|
||||
Integer lineCount = countNodeChildren(node, data);
|
||||
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
public Object visit(ASTIfElseBlockStatement node, Object data) {
|
||||
|
||||
Integer lineCount = countNodeChildren(node, data);
|
||||
lineCount++;
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTWhileLoopStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTBreakStatement node, Object data) {
|
||||
return NumericConstants.ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTTryCatchFinallyBlockStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTReturnStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTThrowStatement node, Object data) {
|
||||
return NumericConstants.ONE;
|
||||
}
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.apex.rule.codesize;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTBooleanExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTForEachStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTForLoopStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTIfBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTIfElseBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTReturnStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTTryCatchFinallyBlockStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTWhileLoopStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.rule.AbstractStatisticalApexRule;
|
||||
import net.sourceforge.pmd.stat.DataPoint;
|
||||
import net.sourceforge.pmd.util.NumericConstants;
|
||||
|
||||
/**
|
||||
* NPath complexity is a measurement of the acyclic execution paths through a
|
||||
* function. See Nejmeh, Communications of the ACM Feb 1988 pp 188-200.
|
||||
*
|
||||
* @author ported from Java version of Jason Bennett
|
||||
*/
|
||||
public class NPathComplexityRule extends AbstractStatisticalApexRule {
|
||||
|
||||
public NPathComplexityRule() {
|
||||
super();
|
||||
setProperty(MINIMUM_DESCRIPTOR, 200d);
|
||||
}
|
||||
|
||||
private int complexityMultipleOf(ApexNode<?> node, int npathStart, Object data) {
|
||||
|
||||
int npath = npathStart;
|
||||
ApexNode<?> n;
|
||||
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
n = (ApexNode<?>) node.jjtGetChild(i);
|
||||
npath *= (Integer) n.jjtAccept(this, data);
|
||||
}
|
||||
|
||||
return npath;
|
||||
}
|
||||
|
||||
private int complexitySumOf(ApexNode<?> node, int npathStart, Object data) {
|
||||
|
||||
int npath = npathStart;
|
||||
ApexNode<?> n;
|
||||
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
n = (ApexNode<?>) node.jjtGetChild(i);
|
||||
npath += (Integer) n.jjtAccept(this, data);
|
||||
}
|
||||
|
||||
return npath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethod node, Object data) {
|
||||
int npath = complexityMultipleOf(node, 1, data);
|
||||
|
||||
DataPoint point = new DataPoint();
|
||||
point.setNode(node);
|
||||
point.setScore(1.0 * npath);
|
||||
point.setMessage(getMessage());
|
||||
addDataPoint(point);
|
||||
|
||||
return Integer.valueOf(npath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ApexNode<?> node, Object data) {
|
||||
int npath = complexityMultipleOf(node, 1, data);
|
||||
return Integer.valueOf(npath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTIfElseBlockStatement node, Object data) {
|
||||
// (npath of if + npath of else (or 1) + bool_comp of if) * npath of
|
||||
// next
|
||||
|
||||
List<ApexNode> statementChildren = new ArrayList<>();
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
if (node.jjtGetChild(i).getClass() == ASTStatement.class) {
|
||||
statementChildren.add((ApexNode<?>) node.jjtGetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (statementChildren.isEmpty() || statementChildren.size() == 1 && true
|
||||
|| statementChildren.size() != 1 && false) {
|
||||
throw new IllegalStateException("If node has wrong number of children");
|
||||
}
|
||||
|
||||
// add path for not taking if
|
||||
int complexity = 1;
|
||||
|
||||
for (ApexNode<?> element : statementChildren) {
|
||||
complexity += (Integer) element.jjtAccept(this, data);
|
||||
}
|
||||
|
||||
int boolCompIf = sumExpressionComplexity(node.getFirstChildOfType(ASTExpression.class));
|
||||
return Integer.valueOf(boolCompIf + complexity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTIfBlockStatement node, Object data) {
|
||||
// (npath of if + npath of else (or 1) + bool_comp of if) * npath of
|
||||
// next
|
||||
|
||||
List<ApexNode> statementChildren = new ArrayList<>();
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
if (node.jjtGetChild(i).getClass() == ASTStatement.class) {
|
||||
statementChildren.add((ApexNode<?>) node.jjtGetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (statementChildren.isEmpty() || statementChildren.size() == 1 && false || statementChildren.size() != 1) {
|
||||
throw new IllegalStateException("If node has wrong number of children");
|
||||
}
|
||||
|
||||
// add path for not taking if
|
||||
int complexity = 0;
|
||||
|
||||
for (ApexNode<?> element : statementChildren) {
|
||||
complexity += (Integer) element.jjtAccept(this, data);
|
||||
}
|
||||
|
||||
int boolCompIf = sumExpressionComplexity(node.getFirstChildOfType(ASTExpression.class));
|
||||
return Integer.valueOf(boolCompIf + complexity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTWhileLoopStatement node, Object data) {
|
||||
// (npath of while + bool_comp of while + 1) * npath of next
|
||||
|
||||
int boolCompWhile = sumExpressionComplexity(node.getFirstChildOfType(ASTExpression.class));
|
||||
|
||||
Integer nPathWhile = (Integer) node.getFirstChildOfType(ASTStatement.class).jjtAccept(this, data);
|
||||
|
||||
return Integer.valueOf(boolCompWhile + nPathWhile + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTForLoopStatement node, Object data) {
|
||||
// (npath of for + bool_comp of for + 1) * npath of next
|
||||
|
||||
int boolCompFor = sumExpressionComplexity(node.getFirstDescendantOfType(ASTExpression.class));
|
||||
|
||||
Integer nPathFor = (Integer) node.getFirstChildOfType(ASTStatement.class).jjtAccept(this, data);
|
||||
|
||||
return Integer.valueOf(boolCompFor + nPathFor + 1);
|
||||
}
|
||||
|
||||
public Object visit(ASTForEachStatement node, Object data) {
|
||||
// (npath of for + bool_comp of for + 1) * npath of next
|
||||
|
||||
int boolCompFor = sumExpressionComplexity(node.getFirstDescendantOfType(ASTExpression.class));
|
||||
|
||||
Integer nPathFor = (Integer) node.getFirstChildOfType(ASTStatement.class).jjtAccept(this, data);
|
||||
|
||||
return Integer.valueOf(boolCompFor + nPathFor + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTReturnStatement node, Object data) {
|
||||
// return statements are valued at 1, or the value of the boolean
|
||||
// expression
|
||||
|
||||
ASTExpression expr = node.getFirstChildOfType(ASTExpression.class);
|
||||
|
||||
if (expr == null) {
|
||||
return NumericConstants.ONE;
|
||||
}
|
||||
|
||||
int boolCompReturn = sumExpressionComplexity(expr);
|
||||
int conditionalExpressionComplexity = complexityMultipleOf(expr, 1, data);
|
||||
|
||||
if (conditionalExpressionComplexity > 1) {
|
||||
boolCompReturn += conditionalExpressionComplexity;
|
||||
}
|
||||
|
||||
if (boolCompReturn > 0) {
|
||||
return Integer.valueOf(boolCompReturn);
|
||||
}
|
||||
return NumericConstants.ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTTryCatchFinallyBlockStatement node, Object data) {
|
||||
/*
|
||||
* This scenario was not addressed by the original paper. Based on the
|
||||
* principles outlined in the paper, as well as the Checkstyle NPath
|
||||
* implementation, this code will add the complexity of the try to the
|
||||
* complexities of the catch and finally blocks.
|
||||
*/
|
||||
int npath = complexitySumOf(node, 0, data);
|
||||
|
||||
return Integer.valueOf(npath);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the boolean complexity of the given expression. NPath boolean
|
||||
* complexity is the sum of && and || tokens. This is calculated by summing
|
||||
* the number of children of the &&'s (minus one) and the children of the
|
||||
* ||'s (minus one).
|
||||
* <p>
|
||||
* Note that this calculation applies to Cyclomatic Complexity as well.
|
||||
*
|
||||
* @param expr
|
||||
* control structure expression
|
||||
* @return complexity of the boolean expression
|
||||
*/
|
||||
public static int sumExpressionComplexity(ASTExpression expr) {
|
||||
if (expr == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int children = 0;
|
||||
|
||||
for (ASTBooleanExpression element : expr.findDescendantsOfType(ASTBooleanExpression.class)) {
|
||||
children += element.jjtGetNumChildren();
|
||||
children--;
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getViolationParameters(DataPoint point) {
|
||||
return new String[] { ((ASTMethod) point.getNode()).getNode().getMethodInfo().getName(),
|
||||
String.valueOf((int) point.getScore()) };
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* 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.ASTMethod;
|
||||
import net.sourceforge.pmd.stat.DataPoint;
|
||||
|
||||
/**
|
||||
* Non-commented source statement counter for methods.
|
||||
*
|
||||
* @author Jason Bennett
|
||||
*/
|
||||
public class NcssMethodCountRule extends AbstractNcssCountRule {
|
||||
|
||||
/**
|
||||
* Count the size of all non-constructor methods.
|
||||
*/
|
||||
public NcssMethodCountRule() {
|
||||
super(ASTMethod.class);
|
||||
setProperty(MINIMUM_DESCRIPTOR, 100d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethod node, Object data) {
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getViolationParameters(DataPoint point) {
|
||||
return new String[] { ((ASTMethod) point.getNode()).getNode().getMethodInfo().getName(),
|
||||
String.valueOf((int) point.getScore()) };
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/**
|
||||
* 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.ast.ASTUserInterface;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTConstructorPreambleStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclaration;
|
||||
import net.sourceforge.pmd.stat.DataPoint;
|
||||
import net.sourceforge.pmd.util.NumericConstants;
|
||||
|
||||
/**
|
||||
* Non-commented source statement counter for type declarations.
|
||||
*
|
||||
* @author Jason Bennett
|
||||
*/
|
||||
public class NcssTypeCountRule extends AbstractNcssCountRule {
|
||||
|
||||
/**
|
||||
* Count type declarations. This includes classes as well as enums and
|
||||
* annotations.
|
||||
*/
|
||||
public NcssTypeCountRule() {
|
||||
super(ASTVariableDeclaration.class);
|
||||
setProperty(MINIMUM_DESCRIPTOR, 1500d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserClass node, Object data) {
|
||||
/*
|
||||
* if (!node.isNested()) { return super.visit(node, data); }
|
||||
*/
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserInterface node, Object data) {
|
||||
/*
|
||||
* if (!node.getNode.isNested()) { return super.visit(node, data); }
|
||||
*/
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTConstructorPreambleStatement node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserEnum node, Object data) {
|
||||
/*
|
||||
* If the enum is a type in and of itself, don't count its declaration
|
||||
* twice.
|
||||
*/
|
||||
if (node.jjtGetParent() instanceof ASTVariableDeclaration) {
|
||||
Integer nodeCount = countNodeChildren(node, data);
|
||||
int count = nodeCount.intValue() - 1;
|
||||
return Integer.valueOf(count);
|
||||
}
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethod node, Object data) {
|
||||
return countNodeChildren(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTFieldDeclaration node, Object data) {
|
||||
return NumericConstants.ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getViolationParameters(DataPoint point) {
|
||||
return new String[] { String.valueOf((int) point.getScore()) };
|
||||
}
|
||||
}
|
@ -8,50 +8,6 @@
|
||||
The Code Size ruleset contains rules that find problems related to code size or complexity.
|
||||
</description>
|
||||
|
||||
<rule name="NPathComplexity" message="The method {0}() has an NPath complexity of {1}"
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.NPathComplexityRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#NPathComplexity">
|
||||
<description>
|
||||
The NPath complexity of a method is the number of acyclic execution paths through that method.
|
||||
A threshold of 200 is generally considered the point where measures should be taken to reduce
|
||||
complexity and increase readability.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
void bar() { // this is something more complex than it needs to be,
|
||||
if (y) { // it should be broken down into smaller methods or functions
|
||||
for (j = 0; j < m; j++) {
|
||||
if (j > r) {
|
||||
doSomething();
|
||||
while (f < 5 ) {
|
||||
anotherThing();
|
||||
f -= 27;
|
||||
}
|
||||
} else {
|
||||
tryThis();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( r - n > 45) {
|
||||
while (doMagic()) {
|
||||
findRabbits();
|
||||
}
|
||||
}
|
||||
try {
|
||||
doSomethingDangerous();
|
||||
} catch (Exception ex) {
|
||||
makeAmends();
|
||||
} finally {
|
||||
dontDoItAgain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="ExcessiveMethodLength" message="Avoid really long methods."
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.ExcessiveMethodLengthRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#ExcessiveMethodLength">
|
||||
@ -72,10 +28,8 @@ public void doSomething() {
|
||||
|
||||
]]>
|
||||
</example>
|
||||
|
||||
</rule>
|
||||
|
||||
|
||||
<rule name="ExcessiveParameterList" message="Avoid long parameter lists."
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.ExcessiveParameterListRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#ExcessiveParameterList">
|
||||
@ -99,10 +53,8 @@ public void addPerson( // preferred approach
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
|
||||
</rule>
|
||||
|
||||
|
||||
<rule name="ExcessiveClassLength" message="Avoid really long classes."
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.ExcessiveClassLengthRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#ExcessiveClassLength">
|
||||
@ -217,93 +169,4 @@ public class Person { // this is more manageable
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="NcssMethodCount" message="The method {0}() has an NCSS line count of {1}"
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.NcssMethodCountRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#NcssMethodCount">
|
||||
<description>
|
||||
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
||||
of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
||||
lines of code that are split are counted as one.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo extends Bar {
|
||||
public int methd() {
|
||||
super.methd();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//this method only has 1 NCSS lines
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="NcssTypeCount" message="The type has an NCSS line count of {0}"
|
||||
class="net.sourceforge.pmd.lang.apex.rule.codesize.NcssTypeCountRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#NcssTypeCount">
|
||||
<description>
|
||||
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
||||
of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
||||
lines of code that are split are counted as one.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo extends Bar {
|
||||
public Foo() {
|
||||
//this class only has 6 NCSS lines
|
||||
super();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
super.foo();
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="TooManyMethods" language="apex"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule" message="This class has too many methods, consider refactoring it."
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/codesize.html#TooManyMethods">
|
||||
<description>
|
||||
<![CDATA[
|
||||
A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to
|
||||
have more fine grained objects.
|
||||
]]>
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="maxmethods" type="Integer"
|
||||
description="The method count reporting threshold" min="1" max="1000"
|
||||
value="10" />
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration/ClassOrInterfaceBody
|
||||
[
|
||||
count(./ClassOrInterfaceBodyDeclaration/MethodDeclaration/MethodDeclarator[
|
||||
not (
|
||||
starts-with(@Image,'get')
|
||||
or
|
||||
starts-with(@Image,'set')
|
||||
or
|
||||
starts-with(@Image,'is')
|
||||
)
|
||||
]) > $maxmethods
|
||||
]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
@ -18,9 +18,5 @@ public class CodesizeRulesTest extends SimpleAggregatorTst {
|
||||
addRule(RULESET, "ExcessiveMethodLength");
|
||||
|
||||
addRule(RULESET, "StdCyclomaticComplexity");
|
||||
|
||||
addRule(RULESET, "NcssMethodCount");
|
||||
addRule(RULESET, "NcssTypeCount");
|
||||
addRule(RULESET, "NPathComplexity");
|
||||
}
|
||||
}
|
||||
|
@ -1,95 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<test-data>
|
||||
<test-code>
|
||||
<description>ok</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public static void bar() {
|
||||
if (true) {List<String> buz = new List<String>();}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>fail, with minimum</description>
|
||||
<rule-property name="minimum">1.0</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>The method bar() has an NPath complexity of 2</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public static void bar() {
|
||||
if (true) {List<String> buz = new List<String>();}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
failure case
|
||||
]]></description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public static Integer bar() {
|
||||
try{
|
||||
if (true) {List<String> buz = new List<String>();}
|
||||
for(Integer i = 0; i < 19; i++) {List<String> buz = new List<String>();}
|
||||
Integer j = 0;
|
||||
if (true) {j = 10;}
|
||||
while (j++ < 20) {List<String> buz = new List<String>();}
|
||||
if (true) {j = 21;}
|
||||
if(false) {j = 0;}
|
||||
do {List<String> buz = new List<String>();} while (j++ < 30);
|
||||
} catch(Exception e){
|
||||
if (true) {e.printStackTrace();}
|
||||
}
|
||||
if (true) {return 1;}
|
||||
else {return 2;}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<code-fragment id="bug3484404"><![CDATA[
|
||||
class Bar
|
||||
{
|
||||
public void x(boolean x, boolean y)
|
||||
{
|
||||
z(
|
||||
(x ? 1 : 2),
|
||||
(y ? 3 : 4)
|
||||
);
|
||||
}
|
||||
|
||||
public Integer y(boolean x, boolean y)
|
||||
{
|
||||
return z(
|
||||
(x ? 1 : 2),
|
||||
(y ? 3 : 4)
|
||||
);
|
||||
}
|
||||
|
||||
public Integer z(Integer x, Integer y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
]]></code-fragment>
|
||||
<test-code>
|
||||
<description>test case for bug 3484404 (Invalid NPath calculation in return statement)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code-ref id="bug3484404"/>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>test case for bug 3484404 (Invalid NPath calculation in return statement) with minimum 25</description>
|
||||
<rule-property name="minimum">25.0</rule-property>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-messages>
|
||||
<message>The method x() has an NPath complexity of 25</message>
|
||||
<message>The method y() has an NPath complexity of 25</message>
|
||||
</expected-messages>
|
||||
<code-ref id="bug3484404"/>
|
||||
</test-code>
|
||||
</test-data>
|
@ -1,82 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<test-data>
|
||||
|
||||
<test-code>
|
||||
<description>short</description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>lots of comments</description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
bar();
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
foo();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="long method"><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
}
|
||||
}
|
||||
]]></code-fragment>
|
||||
|
||||
<test-code>
|
||||
<description>long method</description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code-ref id="long method"/>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>long method - changed minimum</description>
|
||||
<!-- validated this number against NCSS -->
|
||||
<rule-property name="minimum">14</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code-ref id="long method"/>
|
||||
</test-code>
|
||||
|
||||
</test-data>
|
@ -1,83 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<test-data>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
short
|
||||
]]></description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
lots of comments
|
||||
]]></description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
bar();
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
foo();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<code-fragment id="long method"><![CDATA[
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
bar();
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
//nothing to see here
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
foo();
|
||||
}
|
||||
}
|
||||
]]></code-fragment>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
long method
|
||||
]]></description>
|
||||
<rule-property name="minimum">13</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code-ref id="long method"/>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
long method - changed minimum
|
||||
]]></description>
|
||||
<!-- validated this number against NCSS -->
|
||||
<rule-property name="minimum">15</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code-ref id="long method"/>
|
||||
</test-code>
|
||||
</test-data>
|
Reference in New Issue
Block a user