Skip to content
This repository has been archived by the owner on Apr 27, 2021. It is now read-only.

Add cognitive complexity rule #378

Merged
merged 2 commits into from
Dec 21, 2017
Merged

Add cognitive complexity rule #378

merged 2 commits into from
Dec 21, 2017

Conversation

m-g-sonar
Copy link

@m-g-sonar m-g-sonar commented Dec 20, 2017

Fixes #162

I executed current implementation against ruling to see repartition of cognitive complexity by function/method, with the following results. From my point of view, 15 seems to be a good starting value.

criteria total ratio
">0" 32,227 100.00%
">5" 9,153 28.40%
">10" 4,641 14.40%
">15" 2,897 8.99%
">20" 1,885 5.85%
">50" 367 1.14%

image

@ghost ghost assigned m-g-sonar Dec 20, 2017
@ghost ghost added the in progress label Dec 20, 2017
README.md Outdated
@@ -49,6 +49,7 @@ How does it work?
* The output of functions that don't return anything should not be used ([`no-use-of-empty-return-value`]) ([`requires type-check`])
* Variables should be declared before they are used ([`no-variable-usage-before-declaration`]) ([`requires type-check`])
* Type aliases should be used ([`use-type-alias`]) ([`requires type-check`])
* Cognitive Complexity of functions should not be too high ([`cognitive-complexity`])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar we sort rules alphabetically by rule key

README.md Outdated
@@ -84,6 +85,7 @@ How does it work?
[`no-variable-usage-before-declaration`]: ./sonarts-core/docs/rules/no-variable-usage-before-declaration.md
[`use-type-alias`]: ./sonarts-core/docs/rules/use-type-alias.md
[`requires type-check`]: https://palantir.github.io/tslint/usage/type-checking/
[`cognitive-complexity`]: ./sonarts-core/docs/rules/cognitive-complexity.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar same here

@@ -0,0 +1,252 @@
// tslint:disable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar you can drop this line, it's leftover

if (condition) { }
}

get field(): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar field -> property or getter (in JS they don't use term field)

*/
export function runRuleWithLintFile(
Rule: any,
testDirName: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar it's dir here, and ruleName in deeper call. Let's keep one abstraction


## See

* [Cognitive Complexity](http://redirect.sonarsource.com/doc/cognitive-complexity.html)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar add configuration section (like I did for mccabe-complexity)


public visitNode(node: ts.Node): void {
if (is(node, ...Rule.TARGETED_KINDS)) {
const body = (node as ts.FunctionLikeDeclarationBase).body as ts.Node;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar what for this cast as ts.Node? I think you can just drop it

const complexity = this.getComplexity(body);
if (complexity > this.threshold) {
this.addFailureAtNode(
FunctionWalker.reportNode(node),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar why didn't you use functionLikeMainToken from navigation?

}
}

class ComplexityWalker extends tslint.RuleWalker {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar use SyntaxWalker instead

class ComplexityWalker extends tslint.RuleWalker {
private complexity = 0;
private nesting = 0;
private logicalOperationsToIgnore: ts.Node[] = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar can we use a more precise type here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, we only add ts.BinaryExpression here.

}
}

private isEleseIf(node: ts.IfStatement): boolean {
Copy link
Contributor

@vilchik-elena vilchik-elena Dec 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar typo in name

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was sounding nice. but I'll fix :)

}

private isEleseIf(node: ts.IfStatement): boolean {
return (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar what for this parentheses?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not from me. It's Prettier which add it.

}

public visitBinaryExpression(node: ts.BinaryExpression): void {
const opertator = node.operatorToken;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar typo

return false;
}

private static skipParentheses(node: ts.Node): ts.Node {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-g-sonar there is drillDownThroughParenthesis in navigation

@m-g-sonar m-g-sonar assigned m-g-sonar and unassigned vilchik-elena Dec 21, 2017
@vilchik-elena vilchik-elena changed the title Fix #162: Add cognitive complexity rule Add cognitive complexity rule Dec 21, 2017
@m-g-sonar m-g-sonar merged commit 80d4c96 into master Dec 21, 2017
@ghost ghost removed the in progress label Dec 21, 2017
@m-g-sonar m-g-sonar deleted the issue-162 branch December 21, 2017 16:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants