Sonar JavaScript max complexity calculation

714 views
Skip to first unread message

mar...@coderats.net

unread,
Aug 18, 2015, 7:21:10 AM8/18/15
to SonarQube
While it’s very good to have code complexity analysis on SonarQube for JavaScript, it’s more strict than perhaps it should be.

When comparing to the most common linting tools JSHint, the results can be quite different.

Here’s an example function compared with both tools:

function textComplexity(args, opts) { // +1
  var x = args || opts, // +1
      y = args && opts, // +1  (+0 in JSHint)
      z = x ? 0 : 1; // +1

  if (x && y) { // +2 (+1 in JSHint)
    switch (x) {
      case 1: // +1
        z = 2;
        break;
      case 2: // +1
        z = 5;
        break;
      case 3: // +1
        z = 11;
        break;
      case 5: // +1
        z = 13;
        break;
      default:
        z = 0;
    }
  } else { // +0
    z = x && y || z; // +2   (+1 in JSHint)
  }

  for (;; false) {} // +1

  try {
    throw new Error(); // +1  (+0 in JSHint, same as return)
  } catch (e) { // +1
    return '+1'; // +1  (+0 in JSHint)
  }

  return x;
} // Total: 16 (11 in JShint)

So there seems to be 2 major differences between measurements – if exiting method early (either throw or return), Sonar increases complexity whereas JSHint does not; and logical (&&) operator also does not increase complexity.


So the question is – is there a way to sync this up? Either by having a way to choose between ruleset or perhaps in the future, reading the rules from the .jshintrc (and .jscsrc by extension) file itself.

Elena Vilchik

unread,
Aug 19, 2015, 3:53:10 AM8/19/15
to SonarQube
Hello!

There is no way to change the way SQ Javascript plugin computes code complexity. Actually, all our plugins have more or less the same rules for that.
Here are the rules:
  • +1 for each function 
  • +1 for logical conjunctions (&&)
  • +1 for logical disjunctions (||)
  • +1 for ternary conditional expressions
  • +1 for Loops
  • +1 for IF / ELSEIF (+0 for the ELSE)
  • +1 for SWTCH CASES (+0 for the DEFAULT CASE and the SWITCH itself)
  • +1 for RETURN, except when it is the very last statement of a function or of an anonymous function or of an accessor's getter
You can create your own plugin, or even easier, implement custom rules, which count complexity the way you want (this will not change complexity displayed in SQ, but at least issues will appear as you expect).

Freddy Mallet

unread,
Aug 24, 2015, 3:15:18 PM8/24/15
to SonarQube
Just as an additional note, I do confirm that for the time being the way we compute the cyclomatic complexity is incorrect in all languages as we mix the cyclomatic complexity and the essential complexity (by incrementing the complexity each time a return, throw, ... statement is encountered). This is planned in version 5.3 of SQ to make it possible for language plugin to stop mixing those two metrics. 

++


Freddy MALLET | SonarSource
Product Director & Co-Founder
http://sonarsource.com

--
You received this message because you are subscribed to the Google Groups "SonarQube" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarqube+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarqube/4aae1ba6-c308-41a6-a7e2-c1ef3c529802%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

newm...@gmail.com

unread,
Jan 25, 2016, 10:12:22 AM1/25/16
to SonarQube, mar...@coderats.net
Any updates?

This causes issues as we use jshint as our linter in our IDEs.  The inconsistency between what jshint calculates and sonarqube calculates makes it hard to determine what we should focus on.  At the very least it would be nice to set sonarqube to use jshint to evaluate complexity.

chris....@wellcentive.com

unread,
Jun 29, 2016, 5:57:55 PM6/29/16
to SonarQube, mar...@coderats.net, newm...@gmail.com
Hi. Just noting that if you're using IntelliJ or Eclipse, but I just found out SonarLint now integrates with SonarQube server and have real-time inspection. Not sure if this is still an issue for you, but just thought I'd throw that out there as an option.
Reply all
Reply to author
Forward
0 new messages