Skip to content
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

#1131 complex method should be less strict with simple when entries #1135

Conversation

rock3r
Copy link
Contributor

@rock3r rock3r commented Sep 17, 2018

This fixes #1131 by weighing simple when entries to 0.5 (was 1.0) by default, and allowing users to customise the weight if they want to.

This requires the McCabe visitor to internally keep a floating-point sum of the complexities, but we still emit an integer value to keep backwards compatibility (and for simplicity).

This PR also improves ComplexMethod's tests, and adds better facilities to test Findings and ThresholdedCodeSmells.

@rock3r
Copy link
Contributor Author

rock3r commented Sep 17, 2018

CC @Mauin

@rock3r
Copy link
Contributor Author

rock3r commented Sep 17, 2018

Hm, we may have hit a bug with this PR. I get a green Travis, but on AppVeyor, I have these flagged:

Ruleset: potential-bugs - 1h debt
	UnsafeCast - [isThresholded] at C:\projects\detekt\detekt-test\src\main\kotlin\io\gitlab\arturbosch\detekt\test\ThresholdedCodeSmellAssert.kt:12:36
	UnsafeCast - [smell] at C:\projects\detekt\detekt-test\src\main\kotlin\io\gitlab\arturbosch\detekt\test\ThresholdedCodeSmellAssert.kt:26:15
	UnsafeCast - [smell] at C:\projects\detekt\detekt-test\src\main\kotlin\io\gitlab\arturbosch\detekt\test\ThresholdedCodeSmellAssert.kt:35:15

But none of those three is an unsafe cast as there are asserts on front of those casts. How is this not flagged in Travis but we get false positived on AppVeyor?

For now I'll suppress and add an issue tracking the problem.

@rock3r
Copy link
Contributor Author

rock3r commented Sep 17, 2018

Ticket opened: #1137

Suppressions pushed.

@rock3r
Copy link
Contributor Author

rock3r commented Sep 17, 2018

@Mauin can you re-trigger the JDK 9 build on AppVeyor? It failed with some random socket error.

…ict_with_simple_when_entries

# Conflicts:
#	detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt
Copy link
Member

@schalkms schalkms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the rework and the idea with the when entry weight! I think this option is a good compromise. I vote for the simpleWhenEntryWeight=1 as the default value.

@@ -77,6 +77,7 @@ complexity:
active: true
threshold: 10
ignoreSingleWhenExpression: false
simpleWhenEntryWeight: 0.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to raise the question, if this should be the default value. I would argue for the value 1. Otherwise, detekt would not comply with the McCabe metric. The class McCabeVisitor would also need another name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm voting for 0.5 simple when entries are simple and one liners.

@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
* @configuration threshold - MCC threshold for a method (default: 10)
* @configuration ignoreSingleWhenExpression - Ignores a complex method if it only contains a single when expression.
* (default: false)
* @configuration simpleWhenEntryWeight - The weight used for simple (braceless) when entries. (default: 0.5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a user of detekt I would like want to have a bit more documentation for this config option. (range, what effect has value x)

val subject = ComplexMethod(config)
val code = """
internal fun Map<String, Any>.asBundle(): Bundle {
val bundle = Bundle(size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this function to not have any dependencies to Android dev?
Can we also just have the when brace, since this test case should only test the weight of the when clause?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no dependency in here, it's just the sample code taken 1:1 from the ticket. Nothing is going to depend on Android because a string contains an Android class — we don't even have imports for it :)

}

it("does not trip for a reasonable amount of simple when entries") {
val config = TestConfig(mapOf(ComplexMethod.SIMPLE_WHEN_ENTRY_WEIGHT to "0.5"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.5 is the default value atm, isn't it? One could remove this statement..

return ThresholdedCodeSmellAssert(actual as ThresholdedCodeSmell?)
}

class ThresholdedCodeSmellAssert(actual: ThresholdedCodeSmell?) :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good! Much needed assert class

@arturbosch
Copy link
Member

To be honest, I do not like this change. As @schalkms mentioned, McCabe is all about "number of linearly independent paths" within a program. When using floating values this should be another rule then.

I propose to not count the complexity of simple paths within when when a config property is true. If all paths are simple, just count the whole when expressions as mccabe=1.

@rock3r
Copy link
Contributor Author

rock3r commented Sep 19, 2018

Happy to make the change if there's a consensus, I take the point.

@rock3r
Copy link
Contributor Author

rock3r commented Sep 19, 2018

I have created a PR on my fork comparing this solution and an ignore-based solution which adheres better to the definition of MCC. Please review it here: rock3r#2

@arturbosch
Copy link
Member

@rock3r jap that's 90% how I would want this rule to be :). The other 10% is when if (entries.filter { it is KtBlockExpression}.size == 0) return 1 :)

@arturbosch
Copy link
Member

I guess we go with the simple=0 variant?
Can you please open a PR with your new branch?/

@rock3r
Copy link
Contributor Author

rock3r commented Sep 24, 2018

@arturbosch I need to finish up the change you asked me (got sidetracked by urgent things), then I'll merge those changes into this branch. Coming soon!

@arturbosch
Copy link
Member

Thank you!

…_strict_with_simple_when_entries

# Conflicts:
#	detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt
@rock3r
Copy link
Contributor Author

rock3r commented Oct 2, 2018

Still WIP but have merged master in, should at least not have conflicts anymore

@rock3r
Copy link
Contributor Author

rock3r commented Oct 6, 2018

Finally managed to get the changes @arturbosch requested in.

@arturbosch
Copy link
Member

Thank you for the changes!
I rebased and merged this manually. Please use rebase when merging the master branch :)
We rebase everything to get a cleaner history ^^

@arturbosch arturbosch closed this Oct 7, 2018
@rock3r rock3r deleted the 1131_ComplexMethod_should_be_less_strict_with_simple_when_entries branch October 10, 2018 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ComplexMethod reports when with many simple branches
5 participants