Tslint: Cyclomatic Complexity

Created on 18 Jul 2016  路  5Comments  路  Source: palantir/tslint

Clicked post to early, will flesh this out and re-open

Fixed Rule Suggestion

Most helpful comment

I am interested in making a Cyclomatic Complexity rule based on the one included in JSHint and am just checking for opinions before proceeding.

The basic algorithm attributes a base complexity of 1 for each function and increases it in the following cases:

  • ||
  • ? :, if else
  • catch
  • loops: while, do, for
  • case in a switch statement

The rule should be applied to functions which use both the function(){} and ()=>{} syntax, and also class constructors and methods

A numerical value could be provided above which the rule would fail. A default value (10?) would be assumed if none is provided.

One thing the JSHint algorithm doesn't consider AFAICT is nested functions which definitely could be considered "increasers" of complexity as any loop could be recreated as a recursive function. Perhaps this could be considered as an option? Promises would be another example where control flow takes the form of functions.

All 5 comments

I am interested in making a Cyclomatic Complexity rule based on the one included in JSHint and am just checking for opinions before proceeding.

The basic algorithm attributes a base complexity of 1 for each function and increases it in the following cases:

  • ||
  • ? :, if else
  • catch
  • loops: while, do, for
  • case in a switch statement

The rule should be applied to functions which use both the function(){} and ()=>{} syntax, and also class constructors and methods

A numerical value could be provided above which the rule would fail. A default value (10?) would be assumed if none is provided.

One thing the JSHint algorithm doesn't consider AFAICT is nested functions which definitely could be considered "increasers" of complexity as any loop could be recreated as a recursive function. Perhaps this could be considered as an option? Promises would be another example where control flow takes the form of functions.

I'm not all that familiar with the theory behind Cyclomatic Complexity. It seems to me, though, that complexity should be increased for nested functions, since they have access to all data of the parent functions. If this is difficult though, an initial implementation of this rule wouldn't have to handle this. The ESLint rule seems pretty simple overall too.

One thing to note with both the JSHint and ESLint rule is that they both only increase complexity for the || logical operator. I am assuming this is because JavaScript has short circuit-evaluation and the right hand side of the operation could only be executed in some cases, but this seems to be the same for && as well:

if(false || console.log("1")) {
}
if(true || console.log("2")) {
}
if(false && console.log("3")) {
}
if(true && console.log("4")) {
}
// Output is 1 and 4

// A real life example
ctx = canvas.getContext && canvas.getContext('2d');

It seems to me that && should be counted as a code branch as well, unless anyone can point out something I am missing.

Unsure as well, it seems to me that && and || should be treated the same

Using && and || as logical checking could be considered a language quirk. I would consider them at the same level as syntactic sugar.

The following two options are the same, and so should probably be considered the same for any complexity analyzer.

// Option A
ctx = canvas.getContext && canvas.getContext('2d');

// Option B
var ctx;
if (canvas.getContext) {
    ctx = canvas.getContext('2d');
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

zewa666 picture zewa666  路  3Comments

ypresto picture ypresto  路  3Comments

CSchulz picture CSchulz  路  3Comments

ghost picture ghost  路  3Comments