Merge branch 'npath' of https://github.com/oowekyala/pmd into pr-557

This commit is contained in:
Andreas Dangel
2017-08-15 20:35:30 +02:00
3 changed files with 176 additions and 11 deletions

View File

@ -171,7 +171,16 @@ public class DefaultNpathVisitor extends JavaParserVisitorReducedAdapter {
@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;
}

View File

@ -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 {
<description>Full example</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.Foo#bar()' has value 2016.</message>
<message>'.Foo#bar()' has value 8064.</message>
</expected-messages>
<code-ref id="full-example"/>
</test-code>
@ -266,11 +270,11 @@ class Bar {
]]></code-fragment>
<test-code>
<description>test case for bug 3484404 (Invalid NPath calculation in return statement)</description>
<description>Test case for bug 3484404 (Invalid NPath calculation in return statement)</description>
<expected-problems>3</expected-problems>
<expected-messages>
<message>'.Bar#x(boolean, boolean)' has value 25.</message>
<message>'.Bar#y(boolean, boolean)' has value 25.</message>
<message>'.Bar#x(boolean, boolean)' has value 4.</message>
<message>'.Bar#y(boolean, boolean)' has value 4.</message>
<message>'.Bar#z(int, int)' has value 1.</message>
</expected-messages>
<code-ref id="bug3484404"/>
@ -300,4 +304,156 @@ class Bar {
]]></code>
</test-code>
<test-code>
<description>NPath should count the boolean complexity of ternaries</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.Test#method(Date)' has value 4.</message>
</expected-messages>
<code><![CDATA[
public class Test {
public void method(Date a) {
final long aTime = (a == null && a || b) ? 0L : a.getTime();
}
}
]]></code>
</test-code>
<test-code>
<description>#01 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.Test#method(Date)' has value 2.</message>
</expected-messages>
<code><![CDATA[
public class Test {
private static final long UNKNOWN = -1;
public void method(Date a) {
long aTime;
if (a == null) {
aTime = UNKNOWN;
} else {
aTime = a.getTime();
}
}
}
]]></code>
</test-code>
<test-code>
<description>#02 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.Test#method(Date)' has value 2.</message>
</expected-messages>
<code><![CDATA[
public class Test {
private static final long UNKNOWN = -1;
public void method(Date a) {
final long aTime = a == null ? UNKNOWN : a.getTime();
}
}
]]></code>
</test-code>
<test-code>
<description>#1 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
<rule-property name="reportLevel">6</rule-property>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.SOFExample#usefulMethod(List)' has value 272.</message>
</expected-messages>
<code><![CDATA[
public class SOFExample {
private final Map<String, Date> magicMap = new HashMap<String, Date>();
protected static final long UNKNOWN = 0L;
private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}
public void usefulMethod(final List<MyCal> 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;
}
}
}
]]></code>
</test-code>
<test-code>
<description>#2 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
<rule-property name="reportLevel">6</rule-property>
<expected-problems>1</expected-problems>
<expected-messages>
<message>'.SOFExample#usefulMethod(List)' has value 272.</message>
</expected-messages>
<code><![CDATA[
public class SOFExample {
private final Map<String, Date> magicMap = new HashMap<String, Date>();
protected static final long UNKNOWN = 0L;
private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}
public void usefulMethod(final List<MyCal> 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;
}
}
}
]]></code>
</test-code>
</test-data>

View File

@ -160,11 +160,11 @@ class Bar {
<test-code>
<description>test case for bug 3484404 (Invalid NPath calculation in return statement)</description>
<rule-property name="reportLevel">5</rule-property>
<rule-property name="reportLevel">4</rule-property>
<expected-problems>2</expected-problems>
<expected-messages>
<message>The method 'x(boolean, boolean)' has an NPath complexity of 25</message>
<message>The method 'y(boolean, boolean)' has an NPath complexity of 25</message>
<message>The method 'x(boolean, boolean)' has an NPath complexity of 4</message>
<message>The method 'y(boolean, boolean)' has an NPath complexity of 4</message>
</expected-messages>
<code-ref id="bug3484404"/>
</test-code>