public static CognitiveComplexity calculateFileComplexity(UastNode compilationUnit) { CognitiveComplexity complexityVisitor = new CognitiveComplexity(null); complexityVisitor.visit(null, compilationUnit); return complexityVisitor; }
private void increaseComplexity(UastNode node, int increase) { this.complexity += increase; addSecondaryLocation(node, increase); }
private void visitNestedChildren(UastNode node) { incrementNesting(); visitChildren(node); decrementNesting(); }
private void visit(@Nullable UastNode parent, UastNode node) { // TODO function recursive call: increaseComplexityByOne BranchLike branchStatement = BranchLike.from(node); if (node.is(UastNode.Kind.FUNCTION)) { visitFunction(node); } else if (parent == null || !inAFunction || ignoredNode.contains(node)) { visitChildren(node); } else if (node.is(UastNode.Kind.ELSE)) { increaseComplexityByOne(keyword(parent, node)); visitChildren(node); } else if (node.is(UastNode.Kind.IF, UastNode.Kind.SWITCH, UastNode.Kind.LOOP)) { increaseComplexityByNesting(keyword(parent, node)); visitNestedChildren(node); } else if (branchStatement != null && branchStatement.label() != null) { increaseComplexityByOne(keyword(parent, node)); } else if (node.is(UastNode.Kind.BINARY_EXPRESSION)) { visitBinaryExpression(node); } else if (node.is(UastNode.Kind.FUNCTION_LITERAL)) { visitNestedChildren(node); } else { visitChildren(node); } }
private void visitBinaryExpression(UastNode node) { List<BinaryExpressionLike> expressionAsList = new ArrayList<>(); flattenBinaryExpressions(node, expressionAsList); UastNode.Kind lastLogicalOperatorKind = null; for (BinaryExpressionLike binaryExpression : expressionAsList) { UastNode.Kind kind = logicalBinaryExpressionKind(binaryExpression); if (kind != null) { if (binaryExpression.node() != node) { ignoredNode.add(binaryExpression.node()); } if (kind != lastLogicalOperatorKind) { increaseComplexityByOne(binaryExpression.operator()); } } lastLogicalOperatorKind = kind; } visitChildren(node); }
@Override public void visitNode(UastNode node) { nestedFunctionLevel++; if (nestedFunctionLevel != 1) { return; } FunctionLike functionNode = FunctionLike.from(node); if (functionNode == null) { return; } CognitiveComplexity complexity = CognitiveComplexity.calculateFunctionComplexity(functionNode.node()); if (complexity.value() > maxComplexity) { String message = "Refactor this function to reduce its Cognitive Complexity from " + complexity.value() + " to the " + maxComplexity + " allowed."; int effortToFix = complexity.value() - maxComplexity; reportIssue(functionNode.name(), functionNode.name(), message, effortToFix, complexity.secondaryLocations()); } }
public void enterFile(UastNode uast) { metrics = new Metrics(); metrics.cognitiveComplexity = CognitiveComplexity.calculateFileComplexity(uast).value(); }
private static void flattenBinaryExpressions(UastNode node, List<BinaryExpressionLike> expressionAsList) { ParenthesizedLike parenthesizedNode = ParenthesizedLike.from(node); if (parenthesizedNode != null) { flattenBinaryExpressions(parenthesizedNode.expression(), expressionAsList); return; } BinaryExpressionLike binaryExpression = BinaryExpressionLike.from(node); if (binaryExpression != null && logicalBinaryExpressionKind(binaryExpression) != null) { flattenBinaryExpressions(binaryExpression.leftOperand(), expressionAsList); expressionAsList.add(binaryExpression); flattenBinaryExpressions(binaryExpression.rightOperand(), expressionAsList); } }
private void increaseComplexityByNesting(UastNode node) { increaseComplexity(node, nesting); }
private void increaseComplexityByOne(UastNode node) { increaseComplexity(node, 1); }
public static CognitiveComplexity calculateFunctionComplexity(UastNode function) { CognitiveComplexity complexityVisitor = new CognitiveComplexity(new ArrayList<>()); complexityVisitor.visit(null, function); return complexityVisitor; }