-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix cyclomatic complexity #12
Conversation
Correctly compute cyclomatic complexity based on SSA.
Fixes #5 |
Merged in my cumulative improvements fork: https://github.com/gm42/gocyclo |
Hey @nodirt, I believe this is incorrect - on the surface thinking about "the number of linearly independent paths" is somewhat ambiguous, but if you try drawing a Control flow graph as mentioned on the page you linked (https://en.wikipedia.org/wiki/Cyclomatic_complexity), you'll see that the two examples you gave produce graphs which have equivalent number of edges and nodes. For a more concrete demonstration, I've put together a Gist containing a Java Checkstyle Cyclomatic Complexity Example. Provided you have Java installed on your machine, if you download all of those files to one directory and run the |
Hey @ryan0x44, The examples you gave are not equivalent to mine, specifically some of the "if" statements do not have "else" blocks. Here are the analysis for my examples. Example 1Code: if a {
if b {} else {}
} else {} Edges:
Linearly independent paths:
Example 2Code: if a {} else {}
if b {} else {} Edges:
Linearly independent paths:
|
I think since is searched max complexity it is better to leave old implementation |
Hi @sanieales. I didn’t understand your reasoning. |
Hey @nodirt, they are equivalent, if you add else statements you will get the exact same result - I just omitted them for brevity. The given "Linearly independent paths" examples are not control flow graphs which is what I was suggesting be used to demonstrate, and Cyclomatic complexity isn't calculated by adding the number of linearly independent graphs that way (see the wikipedia page for an explanation and formulas). |
Any conclusion on this? My instinct is that if we look at a similar tool in the Java world hopefully we could find one undiscussed canonical/reference implementation to use here too.. Edit: I was wrong, situation is not that clear in Java world either. After some digging the best I could find is the Metrics Reloaded plugin for IntelliJ, and the relevant code snippet can be studied from here: https://github.com/BasLeijdekkers/MetricsReloaded/blob/master/stockmetrics/src/com/sixrr/stockmetrics/methodCalculators/ComplexityCalculator.java It seems to be using a method walker approach. |
I've incorrectly assumed cyclomatic complexity is the number of independent execution paths. Wikipedia says:
which implies cyclomatic complexity is only a proxy to the number of code paths. Java's checkstyle has a separate check NPathsComplexity for this reason I believe the "number of code paths" metric better represents complexity, e.g. in example2, code readers have to think about the difference between cases (!a && b) and (!a && !b). In example2, they don't have to, there is only one code block for !a, thus the code is simpler. However, this repo is about cyclomatic complexity, so there is nothing to fix. |
Look at McCabe's original paper on cyclomatic complexity. He showed that counting branch points is enough. Count "if", but not "else" and non-default cases in switch & select. Also short-circuited and/or. What I'm not clear about is anonymous and inner functions. Do inner functions have separate complexities? |
https://en.wikipedia.org/wiki/Cyclomatic_complexity has the following definition
The current version of the code does not count linearly independent code paths. Instead it counts branch points. This is different. For example, cyclomatic complexity of
and
must be different, but current implementation would return same value.
This PR rewrites the computation algorithm.