Merge branch 'npath' of https://github.com/oowekyala/pmd into pr-557
This commit is contained in:
@ -171,7 +171,16 @@ public class DefaultNpathVisitor extends JavaParserVisitorReducedAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visit(ASTConditionalExpression node, Object data) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
public class Foo {
|
public class Foo {
|
||||||
public static void bar() {
|
public static void bar() {
|
||||||
boolean a, b = true;
|
boolean a, b = true;
|
||||||
try { // total 6
|
try { // total 8
|
||||||
if (true) { // 2
|
if (true) { // 2
|
||||||
List buz = new ArrayList();
|
List buz = new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 19; i++) { // 2
|
for(int i = 0; i < 19; i++) { // 3
|
||||||
List buz = new ArrayList();
|
List buz = a ? new ArrayList() : null;
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
if (true) { // 2
|
if (true) { // 2
|
||||||
@ -23,8 +23,12 @@ public class Foo {
|
|||||||
if (true || a && b) { // 4
|
if (true || a && b) { // 4
|
||||||
j = 10;
|
j = 10;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
j = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j = a || b ? j + 1 : j; // 3
|
||||||
|
|
||||||
while (j++ < 20) { // 2
|
while (j++ < 20) { // 2
|
||||||
List buz = new ArrayList();
|
List buz = new ArrayList();
|
||||||
}
|
}
|
||||||
@ -53,7 +57,7 @@ public class Foo {
|
|||||||
<description>Full example</description>
|
<description>Full example</description>
|
||||||
<expected-problems>1</expected-problems>
|
<expected-problems>1</expected-problems>
|
||||||
<expected-messages>
|
<expected-messages>
|
||||||
<message>'.Foo#bar()' has value 2016.</message>
|
<message>'.Foo#bar()' has value 8064.</message>
|
||||||
</expected-messages>
|
</expected-messages>
|
||||||
<code-ref id="full-example"/>
|
<code-ref id="full-example"/>
|
||||||
</test-code>
|
</test-code>
|
||||||
@ -266,11 +270,11 @@ class Bar {
|
|||||||
]]></code-fragment>
|
]]></code-fragment>
|
||||||
|
|
||||||
<test-code>
|
<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-problems>3</expected-problems>
|
||||||
<expected-messages>
|
<expected-messages>
|
||||||
<message>'.Bar#x(boolean, boolean)' has value 25.</message>
|
<message>'.Bar#x(boolean, boolean)' has value 4.</message>
|
||||||
<message>'.Bar#y(boolean, boolean)' has value 25.</message>
|
<message>'.Bar#y(boolean, boolean)' has value 4.</message>
|
||||||
<message>'.Bar#z(int, int)' has value 1.</message>
|
<message>'.Bar#z(int, int)' has value 1.</message>
|
||||||
</expected-messages>
|
</expected-messages>
|
||||||
<code-ref id="bug3484404"/>
|
<code-ref id="bug3484404"/>
|
||||||
@ -300,4 +304,156 @@ class Bar {
|
|||||||
]]></code>
|
]]></code>
|
||||||
</test-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>
|
</test-data>
|
||||||
|
@ -160,11 +160,11 @@ class Bar {
|
|||||||
|
|
||||||
<test-code>
|
<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>
|
||||||
<rule-property name="reportLevel">5</rule-property>
|
<rule-property name="reportLevel">4</rule-property>
|
||||||
<expected-problems>2</expected-problems>
|
<expected-problems>2</expected-problems>
|
||||||
<expected-messages>
|
<expected-messages>
|
||||||
<message>The method 'x(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 25</message>
|
<message>The method 'y(boolean, boolean)' has an NPath complexity of 4</message>
|
||||||
</expected-messages>
|
</expected-messages>
|
||||||
<code-ref id="bug3484404"/>
|
<code-ref id="bug3484404"/>
|
||||||
</test-code>
|
</test-code>
|
||||||
|
Reference in New Issue
Block a user