2

Suppose that I have the following code.

map.forEach((key, value) -> { //No Sonar cyclomatic complexity score

  for (String s : value) {   //Sonar lint : +2 (including 1 for nesting) 
    if (condition) {...}     //Sonar lint : +3 (including 2 for nesting)
  }

}

As mentioned above for the for loop Sonar assign a score of 2, considering both facts of linear structure breaking and nesting altogether. That's perfectly fine.

map.forEach((key, value) -> { //No Sonar cyclomatic complexity score

  value.forEach(s-> {        //No Sonar cyclomatic complexity score
    if (condition) {...}     //Sonar lint : +3 (including 2 for nesting)
  }); 

}

But if I refactor the for loop for a forEach loop as above, all the Sonar complaints on cyclomatic complexities for the for loop will go away. But as you can see for the if statement cyclomatic complexity is the same. That means for the if statement Sonar considers the same score (score of 2) for the nesting, implying that it is nested 2 levels below (since it is under two forEach statements).

My question is what is the logic behind Sonar not calculating cyclomatic complexity for forEach loop in both structural and nesting wise though it has calculated the structural and nested cyclomatic complexities for the if statement. Is this correct or some bug in SonarLint plugin?

Insightcoder
  • 506
  • 4
  • 14

1 Answers1

2

The cyclomatic complexity of a method (or constructor) is the number of possible linearly-independent execution paths through that method (see [Wikipedia]). It was originally introduced as a complexity measure by Thomas McCabe [McCabe].

This is not about the for-each vs for-loop, It's just because of the lambda expression, lambda expression makes it an anonymous method invocation hence it is not considered cyclomatic complexity of your method, as it becomes a linear path in your method.

Shailesh Chandra
  • 2,164
  • 2
  • 17
  • 25