Skip to content

Add new rule SleepInsteadOfDelay - #3335

Merged
schalkms merged 8 commits into
detekt:masterfrom
severn-everett:sleep_instead_of_delay
Jan 14, 2021
Merged

Add new rule SleepInsteadOfDelay#3335
schalkms merged 8 commits into
detekt:masterfrom
severn-everett:sleep_instead_of_delay

Conversation

@severn-everett

Copy link
Copy Markdown
Contributor

Added new SleepInsteadOfDelay rule for checking for whether Thread.sleep() is being used in suspend functions and coroutines.

Added SleepInsteadOfDelay rule
Added entry to mention the new contribution in README.md
@codecov

codecov Bot commented Dec 30, 2020

Copy link
Copy Markdown

Codecov Report

Merging #3335 (22ba632) into master (77a2d7f) will decrease coverage by 0.18%.
The diff coverage is 75.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #3335      +/-   ##
============================================
- Coverage     80.44%   80.25%   -0.19%     
- Complexity     2721     2727       +6     
============================================
  Files           445      446       +1     
  Lines          8250     8262      +12     
  Branches       1566     1568       +2     
============================================
- Hits           6637     6631       -6     
- Misses          772      785      +13     
- Partials        841      846       +5     
Impacted Files Coverage Δ Complexity Δ
...sch/detekt/rules/coroutines/SleepInsteadOfDelay.kt 73.91% <73.91%> (ø) 10.00 <10.00> (?)
...osch/detekt/rules/coroutines/CoroutinesProvider.kt 100.00% <100.00%> (ø) 3.00 <0.00> (ø)
...lab/arturbosch/detekt/internal/ClassLoaderCache.kt 31.57% <0.00%> (-58.90%) 0.00% <0.00%> (ø%)
...ekt/rules/style/RedundantVisibilityModifierRule.kt 91.48% <0.00%> (-4.43%) 11.00% <0.00%> (-3.00%)
...io/github/detekt/report/sarif/SarifOutputReport.kt 90.62% <0.00%> (-4.12%) 4.00% <0.00%> (ø%)
.../io/gitlab/arturbosch/detekt/internal/DetektJvm.kt 57.69% <0.00%> (-1.57%) 4.00% <0.00%> (-1.00%)
...n/kotlin/io/github/detekt/report/sarif/SarifDsl.kt 100.00% <0.00%> (ø) 0.00% <0.00%> (ø%)
...tlab/arturbosch/detekt/core/reporting/Reporting.kt 94.11% <0.00%> (ø) 0.00% <0.00%> (ø%)
.../main/kotlin/io/github/detekt/parser/KtCompiler.kt 81.81% <0.00%> (+4.54%) 8.00% <0.00%> (ø%)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a17b7f9...9d8d0dc. Read the comment docs.

@BraisGabin BraisGabin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks good :) just one more test and it's good to go for my end.

Added positive unit test for SleepInsteadOfDelay rule
?.resultingDescriptor
?.fqNameOrNull()
?.asString()
if (fqName == LAUNCH_COROUTINE_NAME) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should also check async here. This could be in a follow-up PR.

}

override fun visitImportDirective(importDirective: KtImportDirective) {
sleepImported = importDirective.importedFqName?.asString() in IMPORT_PATHS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is sleepImported needed at all? You're checking the fully qualified name of the Thread.sleep function below (line 92) so it should be irrelevant if sleep was imported or not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sleepImported is there to avoid having to search through all KtCallExpression descendents, given that there will only be dot-qualified expressions of Thread.sleep() if sleepImported is false.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

to avoid having to search through all KtCallExpression descendents

Are you trying to avoid this for performance reasons?

Added check for CoroutineScope.async(); Added @requiresTypeResolution for documentation
Removing active declaration for rule
Added test for sleep() invocation when Thread.sleep is imported and executed in a Coroutine block; Fixed bug where sleepImported could be set to false after visiting other import statements in a file
@severn-everett

Copy link
Copy Markdown
Contributor Author

Suggestions for additional tests to increase code coverage would be welcome.

@severn-everett

severn-everett commented Jan 6, 2021 via email

Copy link
Copy Markdown
Contributor Author

@cortinico

Copy link
Copy Markdown
Member

Yes, basically. If Thread.sleep isn't imported, then there wouldn't be any non dot-qualified expressions of the function, correct? In that case, the rule could skip parsing through expressions that it wouldn't have an expectation of finding the sleep() function.

I would say that in this case the readability outweighs the performance benefits. It was not immediately clear to me why you were interested in the checking if sleep() was imported or not.

I would simplify the checkDescendants function with

    private fun PsiElement.checkDescendants(message: String) {
        forEachDescendantOfType<KtCallExpression> { it.verifyExpression(message) }
        forEachDescendantOfType<KtDotQualifiedExpression> { it.verifyExpression(message) }
    }

You're anyway running verifyExpression for all the KtDotQualifiedExpression, I don't see the benefit of optionally skipping the KtCallExpression occurrences only. You can then remove all the postVisit and visitImportDirective code as well as the specific cases in the tests.

Reducing granularity of checks for Thread.sleep() invocations, just checking on all KtCallExpression instances
@cortinico cortinico changed the title sleep_instead_of_delay Add new rule SleepInsteadOfDelay Jan 13, 2021

@cortinico cortinico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@schalkms
schalkms merged commit e5a694c into detekt:master Jan 14, 2021
@arturbosch arturbosch added this to the 1.16.0 milestone Jan 18, 2021
@mhernand40

Copy link
Copy Markdown
Contributor

It seems that although 1.16.0 has not been released yet, this new rule has been published in https://detekt.github.io/detekt/coroutines.html#sleepinsteadofdelay.

For me, this led to

> Run failed with 1 invalid config property.
  	- Property 'coroutines>SleepInsteadOfDelay' is misspelled or does not exist.

When I unknowingly tried to enable this with version 1.15.0.

@cortinico

Copy link
Copy Markdown
Member

It seems that although 1.16.0 has not been released yet, this new rule has been published in detekt.github.io/detekt/coroutines.html#sleepinsteadofdelay.

That's expected as the documentation website follows the status of the current master. If you want to use SleepInsteadOfDelay you can consider using our snapshot version https://detekt.github.io/detekt/snapshots.html or wait for 1.16.0 to be released.

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.

7 participants