diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/visitors/DefaultNpathVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/visitors/DefaultNpathVisitor.java
index bcbe3a3fe..86ca22c81 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/visitors/DefaultNpathVisitor.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/visitors/DefaultNpathVisitor.java
@@ -171,7 +171,16 @@ public Object visit(ASTSwitchStatement node, Object data) {
@Override
public Object visit(ASTConditionalExpression node, Object data) {
- return node.isTernary() ? sumChildrenComplexities(node, data) + 2 : 1;
+ // bool comp of guard clause + complexity of last two children (= total - 1)
+
+ if (node.isTernary()) {
+ ASTExpression wrapper = new ASTExpression(Integer.MAX_VALUE);
+ wrapper.jjtAddChild(node.jjtGetChild(0), 0);
+ int boolCompTernary = CycloMetric.booleanExpressionComplexity(wrapper);
+
+ return boolCompTernary + sumChildrenComplexities(node, data) - 1;
+ }
+ return 1;
}
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NPathTest.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NPathTest.xml
index 8c2387f79..2b5bebe73 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NPathTest.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NPathTest.xml
@@ -5,13 +5,13 @@
public class Foo {
public static void bar() {
boolean a, b = true;
- try { // total 6
+ try { // total 8
if (true) { // 2
List buz = new ArrayList();
}
- for(int i = 0; i < 19; i++) { // 2
- List buz = new ArrayList();
+ for(int i = 0; i < 19; i++) { // 3
+ List buz = a ? new ArrayList() : null;
}
} catch(Exception e) {
if (true) { // 2
@@ -23,8 +23,12 @@ public class Foo {
if (true || a && b) { // 4
j = 10;
return;
+ } else {
+ j = 12;
}
+ j = a || b ? j + 1 : j; // 3
+
while (j++ < 20) { // 2
List buz = new ArrayList();
}
@@ -53,7 +57,7 @@ public class Foo {
Full example
1
- '.Foo#bar()' has value 2016.
+ '.Foo#bar()' has value 8064.
@@ -266,11 +270,11 @@ class Bar {
]]>
- test case for bug 3484404 (Invalid NPath calculation in return statement)
+ Test case for bug 3484404 (Invalid NPath calculation in return statement)
3
- '.Bar#x(boolean, boolean)' has value 25.
- '.Bar#y(boolean, boolean)' has value 25.
+ '.Bar#x(boolean, boolean)' has value 4.
+ '.Bar#y(boolean, boolean)' has value 4.
'.Bar#z(int, int)' has value 1.
@@ -300,4 +304,156 @@ class Bar {
]]>
+
+ NPath should count the boolean complexity of ternaries
+ 1
+
+ '.Test#method(Date)' has value 4.
+
+
+
+
+
+ #01 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)
+ 1
+
+ '.Test#method(Date)' has value 2.
+
+
+
+
+
+ #02 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)
+ 1
+
+ '.Test#method(Date)' has value 2.
+
+
+
+
+
+ #1 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)
+ 6
+ 1
+
+ '.SOFExample#usefulMethod(List)' has value 272.
+
+ magicMap = new HashMap();
+ protected static final long UNKNOWN = 0L;
+ private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}
+
+ public void usefulMethod(final List myCals) {
+
+ final Date a = magicMap.get("a");
+ final Date b = magicMap.get("b");
+ final Date c = magicMap.get("c");
+ final Date d = magicMap.get("d");
+
+ final long aTime = a == null ? UNKNOWN : a.getTime();
+ final long bTime = b == null ? UNKNOWN : b.getTime();
+ final long cTime = c == null ? UNKNOWN : c.getTime();
+ final long dTime = d == null ? UNKNOWN : d.getTime();
+
+ for (MyCal myCal : myCals) {
+ if(myCal.aTime == UNKNOWN) myCal.aTime = aTime;
+ if(myCal.bTime == UNKNOWN) myCal.bTime = bTime;
+ if(myCal.cTime == UNKNOWN) myCal.cTime = cTime;
+ if(myCal.dTime == UNKNOWN) myCal.dTime = dTime;
+ }
+ }
+ }
+ ]]>
+
+
+
+ #2 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)
+ 6
+ 1
+
+ '.SOFExample#usefulMethod(List)' has value 272.
+
+ magicMap = new HashMap();
+ protected static final long UNKNOWN = 0L;
+ private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}
+
+ public void usefulMethod(final List myCals) {
+
+ final Date a = magicMap.get("a");
+ final Date b = magicMap.get("b");
+ final Date c = magicMap.get("c");
+ final Date d = magicMap.get("d");
+
+ final long aTime;
+ if (a == null) {
+ aTime = a.getTime();
+ } else {
+ aTime = UNKNOWN;
+ }
+
+ final long bTime;
+ if (b == null) {
+ bTime = b.getTime();
+ } else {
+ bTime = UNKNOWN;
+ }
+
+ final long cTime;
+ if (c == null) {
+ cTime = c.getTime();
+ } else {
+ cTime = UNKNOWN;
+ }
+
+ final long dTime;
+ if (d == null) {
+ dTime = d.getTime();
+ } else {
+ dTime = UNKNOWN;
+ }
+
+ for (MyCal myCal : myCals) {
+ if(myCal.aTime == UNKNOWN) myCal.aTime = aTime;
+ if(myCal.bTime == UNKNOWN) myCal.bTime = bTime;
+ if(myCal.cTime == UNKNOWN) myCal.cTime = cTime;
+ if(myCal.dTime == UNKNOWN) myCal.dTime = dTime;
+ }
+ }
+ }
+ ]]>
+
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/metrics/xml/NPathComplexity.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/metrics/xml/NPathComplexity.xml
index 491811515..d72c8b90f 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/metrics/xml/NPathComplexity.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/metrics/xml/NPathComplexity.xml
@@ -160,11 +160,11 @@ class Bar {
test case for bug 3484404 (Invalid NPath calculation in return statement)
- 5
+ 4
2
- The method 'x(boolean, boolean)' has an NPath complexity of 25
- The method 'y(boolean, boolean)' has an NPath complexity of 25
+ The method 'x(boolean, boolean)' has an NPath complexity of 4
+ The method 'y(boolean, boolean)' has an NPath complexity of 4
diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md
index 0fc7526c0..72fcbc4d9 100644
--- a/src/site/markdown/overview/changelog.md
+++ b/src/site/markdown/overview/changelog.md
@@ -168,4 +168,5 @@ All existing rules have been updated to reflect these changes. If you have custo
* [#548](https://github.com/pmd/pmd/pull/548): \[java] Metrics documentation - [Clément Fournier](https://github.com/oowekyala)
* [#550](https://github.com/pmd/pmd/pull/550): \[java] Add basic resolution to type inference - [Bendegúz Nagy](https://github.com/WinterGrascph)
* [#555](https://github.com/pmd/pmd/pull/555): \[java] Changed metrics/CyclomaticComplexityRule to use WMC when reporting classes - [Clément Fournier](https://github.com/oowekyala)
+* [#557](https://github.com/pmd/pmd/pull/557): \[java] Fix NPath metric not counting ternaries correctly - [Clément Fournier](https://github.com/oowekyala)