diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/impl/visitors/CognitiveComplexityVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/impl/visitors/CognitiveComplexityVisitor.java index 03b1b5bb4c..de14a62040 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/impl/visitors/CognitiveComplexityVisitor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/impl/visitors/CognitiveComplexityVisitor.java @@ -1,5 +1,7 @@ package net.sourceforge.pmd.lang.apex.metrics.impl.visitors; +import apex.jorje.data.ast.BooleanOp; +import apex.jorje.data.ast.PrefixOp; import net.sourceforge.pmd.lang.apex.ast.*; /** @@ -9,6 +11,7 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter { public static class State { private int complexity = 0; private int nestingLevel = 0; + private BooleanOp currentBooleanOperation = null; public double getComplexity() { return complexity; @@ -22,6 +25,16 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter { complexity += nestingLevel; } + void booleanOperation(BooleanOp op) { + if (currentBooleanOperation != op) { + if (op != null) { + structureComplexity(); + } + + currentBooleanOperation = op; + } + } + void increaseNestingLevel() { structureComplexity(); nestingComplexity(); @@ -133,4 +146,28 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter { return data; } + + @Override + public Object visit(ASTBooleanExpression node, Object data) { + State state = (State) data; + + BooleanOp op = node.getNode().getOp(); + if (op == BooleanOp.AND || op == BooleanOp.OR) { + state.booleanOperation(op); + } + + return super.visit(node, data); + } + + @Override + public Object visit(ASTPrefixExpression node, Object data) { + State state = (State) data; + + PrefixOp op = node.getNode().getOp(); + if (op == PrefixOp.NOT) { + state.booleanOperation(null); + } + + return super.visit(node, data); + } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/impl/xml/CognitiveComplexityTest.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/impl/xml/CognitiveComplexityTest.xml index 300c7d1450..5784716ff1 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/impl/xml/CognitiveComplexityTest.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/impl/xml/CognitiveComplexityTest.xml @@ -290,4 +290,46 @@ ]]> + + + Boolean operators + 5 + + 'c__Foo#a(Integer)' has value 1. + 'c__Foo#b(Integer)' has value 1. + 'c__Foo#c(Integer)' has value 1. + 'c__Foo#d(Boolean,Boolean,Boolean,Boolean,Boolean,Boolean)' has value 3. + 'c__Foo#e(Boolean,Boolean,Boolean)' has value 2. + + + 0 && n > 1; // +1 + } + + Boolean b(Integer n) { + return n > 0 && n > 1 && n > 2; // +1 + } + + Boolean c(Integer n) { + return n > 0 || n < 0; // +1 + } + + Boolean d(Boolean a, Boolean b, Boolean c, Boolean d, Boolean e, Boolean f) { + return (a + && b && c) // +1 + || (d || e) // +1 + && f; // +1 + } + + Boolean e(Boolean a, Boolean b, Boolean c) { + return a + && // +1 + !(b && c); // +1 + } + } + ]]> + + \ No newline at end of file