Merge branch 'docs-metrics' of https://github.com/oowekyala/pmd into pr-548
This commit is contained in:
@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.metrics.impl.visitors;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAssertStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCatchStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
@ -220,4 +221,10 @@ public class DefaultNcssVisitor extends JavaParserVisitorAdapter {
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTAssertStatement node, Object data) {
|
||||
((MutableInt) data).increment();
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,51 +16,46 @@
|
||||
metrics="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#CyclomaticComplexity">
|
||||
<description>
|
||||
<![CDATA[
|
||||
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
||||
plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
|
||||
Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
|
||||
high complexity, and 11+ is very high complexity.
|
||||
]]>
|
||||
The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic
|
||||
in a single method makes its behaviour hard to read and change.
|
||||
|
||||
Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method,
|
||||
plus one for the method entry. Decision points are places where the control flow jumps to another place in the
|
||||
program. As such, they include all control flow statements, such as `if`, `while`, `for`, and `case`. For more
|
||||
details on the calculation, see the documentation of the [Cyclo metric](/pmd_java_metrics_index.html#cyclomatic-complexity-cyclo).
|
||||
|
||||
Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
|
||||
high complexity, and 11+ is very high complexity.
|
||||
|
||||
Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down
|
||||
into subcomponents.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo { // This has a Cyclomatic Complexity = 12
|
||||
1 public void example() {
|
||||
2 if (a == b) {
|
||||
3 if (a1 == b1) {
|
||||
fiddle();
|
||||
4 } else if a2 == b2) {
|
||||
fiddle();
|
||||
} else {
|
||||
fiddle();
|
||||
}
|
||||
5 } else if (c == d) {
|
||||
6 while (c == d) {
|
||||
fiddle();
|
||||
}
|
||||
7 } else if (e == f) {
|
||||
8 for (int n = 0; n < h; n++) {
|
||||
fiddle();
|
||||
}
|
||||
} else{
|
||||
switch (z) {
|
||||
9 case 1:
|
||||
fiddle();
|
||||
break;
|
||||
10 case 2:
|
||||
fiddle();
|
||||
break;
|
||||
11 case 3:
|
||||
fiddle();
|
||||
break;
|
||||
12 default:
|
||||
fiddle();
|
||||
break;
|
||||
}
|
||||
class Foo {
|
||||
void baseCyclo() { // Cyclo = 1
|
||||
highCyclo();
|
||||
}
|
||||
|
||||
void highCyclo() { // Cyclo = 10: reported!
|
||||
int x = 0, y = 2;
|
||||
boolean a = false, b = true;
|
||||
|
||||
if (a && (y == 1 ? b : true)) { // +3
|
||||
if (y == x) { // +1
|
||||
while (true) { // +1
|
||||
if (x++ < 20) { // +1
|
||||
break; // +1
|
||||
}
|
||||
}
|
||||
} else if (y == t && !d) { // +2
|
||||
x = a ? y : x; // +1
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
@ -71,24 +66,38 @@ public class Foo { // This has a Cyclomatic Complexity = 12
|
||||
since="3.9"
|
||||
class="net.sourceforge.pmd.lang.java.metrics.rule.NcssCountRule"
|
||||
metrics="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#NcssTypeCount">
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#NcssCount">
|
||||
<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.
|
||||
This rule uses the NCSS (Non-Commenting Source Statements) metric to determine the number of lines
|
||||
of code in a class, method or constructor. NCSS ignores comments, blank lines, and only counts actual
|
||||
statements. For more details on the calculation, see the documentation ofthe[NCSSmetric](/pmd_java_metrics_index.html#non-commenting-source-statements-ncss).
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo extends Bar {
|
||||
public Foo() { //this class only has 4 NCSS lines
|
||||
super();
|
||||
import java.util.Collections; // +0
|
||||
import java.io.IOException; // +0
|
||||
|
||||
class Foo { // +1, total Ncss = 12
|
||||
|
||||
public void bigMethod() // +1
|
||||
throws IOException {
|
||||
int x = 0, y = 2; // +1
|
||||
boolean a = false, b = true; // +1
|
||||
|
||||
if (a || b) { // +1
|
||||
try { // +1
|
||||
do { // +1
|
||||
x += 2; // +1
|
||||
} while (x < 12);
|
||||
|
||||
|
||||
super.foo();
|
||||
System.exit(0); // +1
|
||||
} catch (IOException ioe) { // +1
|
||||
throw new PatheticFailException(ioe); // +1
|
||||
}
|
||||
} else {
|
||||
assert false; // +1
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
@ -103,41 +112,51 @@ public class Foo extends Bar {
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#NPathComplexity">
|
||||
<description>
|
||||
The NPath complexity of a method is the number of acyclic execution paths through that method.
|
||||
While cyclomatic complexity counts the number of decision points in a method, NPath counts the number of
|
||||
full paths from the beginning to the end of the block of the method. That metric grows exponentially, as
|
||||
it multiplies the complexity of statements in the same block. For more details on the calculation, see the
|
||||
documentation of the [NPath metric](/pmd_java_metrics_index.html#npath-complexity-npath).
|
||||
|
||||
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();
|
||||
}
|
||||
public class Foo {
|
||||
public static void bar() { // Ncss = 252: reported!
|
||||
boolean a, b = true;
|
||||
try { // 2 * 2 + 2 = 6
|
||||
if (true) { // 2
|
||||
List buz = new ArrayList();
|
||||
}
|
||||
|
||||
for(int i = 0; i < 19; i++) { // * 2
|
||||
List buz = new ArrayList();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
if (true) { // 2
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if ( r - n > 45) {
|
||||
while (doMagic()) {
|
||||
findRabbits();
|
||||
}
|
||||
|
||||
while (j++ < 20) { // * 2
|
||||
List buz = new ArrayList();
|
||||
}
|
||||
try {
|
||||
doSomethingDangerous();
|
||||
} catch (Exception ex) {
|
||||
makeAmends();
|
||||
} finally {
|
||||
dontDoItAgain();
|
||||
|
||||
switch(j) { // * 7
|
||||
case 1:
|
||||
case 2: break;
|
||||
case 3: j = 5; break;
|
||||
case 4: if (b && a) { bar(); } break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
do { // * 3
|
||||
List buz = new ArrayList();
|
||||
} while (a && j++ < 30);
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
@ -104,6 +104,7 @@
|
||||
e.printStackTrace();
|
||||
} catch (ThemAll pokemon) {
|
||||
pokemon.train();
|
||||
assert pokemon.level > 12;
|
||||
} finally {
|
||||
// Do nothing
|
||||
}
|
||||
@ -125,11 +126,11 @@
|
||||
<rule-property name="reportClasses">true</rule-property>
|
||||
<expected-problems>5</expected-problems>
|
||||
<expected-messages>
|
||||
<message>'com.company.money.Foo' has value 65 highest 20.</message>
|
||||
<message>'com.company.money.Foo' has value 66 highest 21.</message>
|
||||
<message>'com.company.money.Foo#Foo()' has value 2.</message>
|
||||
<message>'com.company.money.Foo#Foo(int)' has value 13.</message>
|
||||
<message>'com.company.money.Foo#foo()' has value 14.</message>
|
||||
<message>'com.company.money.Foo#main(String)' has value 20.</message>
|
||||
<message>'com.company.money.Foo#main(String)' has value 21.</message>
|
||||
</expected-messages>
|
||||
<code-ref id="full-example"/>
|
||||
</test-code>
|
||||
@ -140,11 +141,11 @@
|
||||
<rule-property name="metricVersion">javaNcss</rule-property>
|
||||
<expected-problems>5</expected-problems>
|
||||
<expected-messages>
|
||||
<message>'com.company.money.Foo' has value 68 highest 20.</message>
|
||||
<message>'com.company.money.Foo' has value 69 highest 21.</message>
|
||||
<message>'com.company.money.Foo#Foo()' has value 2.</message>
|
||||
<message>'com.company.money.Foo#Foo(int)' has value 13.</message>
|
||||
<message>'com.company.money.Foo#foo()' has value 14.</message>
|
||||
<message>'com.company.money.Foo#main(String)' has value 20.</message>
|
||||
<message>'com.company.money.Foo#main(String)' has value 21.</message>
|
||||
</expected-messages>
|
||||
<code-ref id="full-example"/>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user