-
-
Notifications
You must be signed in to change notification settings - Fork 779
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
Initial MCC change #1793
Initial MCC change #1793
Conversation
detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt
Show resolved
Hide resolved
detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt
Outdated
Show resolved
Hide resolved
@@ -26,9 +26,10 @@ import org.jetbrains.kotlin.psi.KtWhenExpression | |||
* Complex methods use too many of the following statements. | |||
* Each one of them adds one to the complexity count. | |||
* | |||
* - __Conditional statements__ - `if`, `else`, `when` | |||
* - __Conditional statements__ - `if`, `else if`, `when` | |||
* - __Loops__ - `for`, `while`, `do-while`, `forEach` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we move forEach to the scope functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. I think it's also okay to have it in the loops
section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion the safe navigation operator ?.
and the null coalescing operator ?:
also needs to be added. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make this configurable. Most users wont like this change, however per definition this makes sense and they add a bit of clutter.
If you inspect the bytecode there are new paths, but they do not add to mental complexity...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you inspect the bytecode there are new paths, but they do not add to mental complexity
I mean it's all about the code paths, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree here. The cyclomatic complexity also determines the number of test cases required for a function. A programmer could trick the analyzer in rewriting the following code. The first example reports 2 the second example 1. Anyways, the programmer needs to write two test cases covering both branches. I know that some users may not like it, but other handle this similarly. We might want to increase the allowed complexity from 10 to 15 for instance.
fun f() {
if (foo != null)
foo.bar()
}
fun f() {
foo?.bar()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, what do you think about chained safe navigation foo?.bar?.toString() ?: "bla"
?
Would you count all ?
or just one because obviously only the non-null and the ?: case are interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I need to do further research in that regard.
I will change the obvious things in this PR (if I have time).
- try/catch count
- if logic (with || and &&) because every other tool does it that way
We mention this in the changelog and we will be fine.
The rest is subject for research and perhaps for another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO a strict check should consider all the branches in chained safe navigation, and not only the first one. For eg: Jacoco considers all branches of chained safe navigation for code coverage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@amitdash291 Jacoco works on the lower-level bytecode, whereas detekt uses the PSI.
detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt
Outdated
Show resolved
Hide resolved
I'll proceed with this PR and update the obvious elements (for instance the try/catch blocks). |
@@ -3,11 +3,11 @@ package cases | |||
import org.jetbrains.kotlin.utils.sure | |||
|
|||
@Suppress("unused") | |||
class ComplexClass {// McCabe: 56, LLOC: 20 + 20 + 4x4 | |||
class ComplexClass {// McCabe: 44, LLOC: 20 + 20 + 4x4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test cases need to be moved to multiple unit tests.
Furthermore, we should test the McCabeVisitor.kt
class intensively and not every usage of it.
I'd still merge this for the next version, since it fixes the wrong calculation. |
Sorry, I expect multiple issues to be raised for different releases when we break/change this rule. |
@arturbosch I see. However, I'd then recommend having more than 1 PR. |
* Initial MCC change reference https://www.ndepend.com/docs/code-metrics#CC * Update MCC according to requirements
* Initial MCC change reference https://www.ndepend.com/docs/code-metrics#CC * Update MCC according to requirements
reference https://www.ndepend.com/docs/code-metrics#CC