Cyclomatic Complexity rule yields multiple messages for same scope
Description
Under particular circumstances, the present implementation of the Cyclomatic Complexity rule FL0071 will necessarily generate multiple messages when the complexity exceeds the configurable maximum.
Repro steps
As an example: running the linter on the following snippet of code with a maxComplexity of 5 yields the output below.
snippet:
let multipleStrCases (str: string) =
match str with
| "C01" -> match str with
| "A" -> ()
| "B" -> ()
| "C02" -> match str with
| "A" -> ()
| "B" -> ()
| "C03" -> match str with
| "A" -> ()
| "B" -> ()
| "C04" -> match str with
| "A" -> ()
| "B" -> ()
| "C05" -> match str with
| "A" -> ()
| "B" -> ()
| "C06" -> match str with
| "A" -> ()
| "B" -> ()
| "C07" -> match str with
| "A" -> ()
| "B" -> ()
| "C08" -> match str with
| "A" -> ()
| "B" -> ()
| "C09" -> match str with
| "A" -> ()
| "B" -> ()
| "C010" -> match str with
| "A" -> ()
| "B" -> ()
| _ -> ()
output:
The cyclomatic complexity of this section is 31, which exceeds the maximum suggested complexity of 5.
Error on line 7 starting at column 6
let multipleStrCases (str: string) =
^
--------------------------------------------------------------------------------
The cyclomatic complexity of this section is 29, which exceeds the maximum suggested complexity of 5.
Error on line 7 starting at column 6
let multipleStrCases (str: string) =
^
--------------------------------------------------------------------------------
The cyclomatic complexity of this section is 27, which exceeds the maximum suggested complexity of 5.
Error on line 7 starting at column 6
let multipleStrCases (str: string) =
^
...and so on.
Expected behavior
Only one message should be reported, indicating the highest cyclomatic complexity (31 in the example above).
Actual behavior
See above.
Known workarounds
The linter is still usable in its current state, but the over-reporting of messages is confusing and annoying.
Related information
The cause of the issue is that the runner in the CyclomaticComplexity module is issuing a warning for all bindings pushed off the stack when the binding is advanced, even if the start of the binding is the same. It should cut these down to only those with the maximum cyclomatic complexity.
I have a fix for this, I've just got to clean it up and write an accompanying test; I will generate a PR when that is ready.