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

Add list of functions to skip in IgnoredReturnValue rule #4434

Merged
merged 9 commits into from Jan 28, 2022
1 change: 1 addition & 0 deletions detekt-core/src/main/resources/default-detekt-config.yml
Expand Up @@ -552,6 +552,7 @@ potential-bugs:
- '*.CheckReturnValue'
ignoreReturnValueAnnotations:
- '*.CanIgnoreReturnValue'
ignoreFunctionCall: []
ImplicitDefaultLocale:
active: true
ImplicitUnitReturnType:
Expand Down
1 change: 1 addition & 0 deletions detekt-rules-errorprone/build.gradle.kts
Expand Up @@ -4,6 +4,7 @@ plugins {

dependencies {
compileOnly(projects.detektApi)
implementation(projects.detektTooling)
testImplementation(projects.detektTest)
testImplementation(libs.bundles.testImplementation)
testRuntimeOnly(libs.spek.runner)
Expand Down
@@ -1,5 +1,6 @@
package io.gitlab.arturbosch.detekt.rules.bugs

import io.github.detekt.tooling.api.FunctionMatcher
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
Expand Down Expand Up @@ -58,6 +59,17 @@ class IgnoredReturnValue(config: Config = Config.empty) : Rule(config) {
it.map(String::simplePatternToRegex)
}

@Configuration(
"List of function signatures which should be ignored by this rule. " +
"Specifying fully-qualified function signature with name only (i.e. `java.time.LocalDate.now`) will ignore " +
"all function calls matching the name. Specifying fully-qualified function signature with parameters" +
"(i.e. `java.time.LocalDate.now(java.time.Clock)`) will ignore only function calls matching the name " +
"and parameters exactly."
)
private val ignoreFunctionCall: List<FunctionMatcher> by config(emptyList<String>()) {
it.map(FunctionMatcher::fromFunctionSignature)
}

@Suppress("ReturnCount")
override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
Expand All @@ -68,6 +80,8 @@ class IgnoredReturnValue(config: Config = Config.empty) : Rule(config) {
val resultingDescriptor = expression.getResolvedCall(bindingContext)?.resultingDescriptor ?: return
if (resultingDescriptor.returnType?.isUnit() == true) return

if (ignoreFunctionCall.any { it.match(resultingDescriptor) }) return

val annotations = resultingDescriptor.annotations
if (annotations.any { it in ignoreReturnValueAnnotations }) return
if (restrictToAnnotatedMethods &&
Expand Down
Expand Up @@ -813,5 +813,28 @@ object IgnoredReturnValueSpec : Spek({
val findings = rule.compileAndLintWithContext(env, code)
assertThat(findings).isEmpty()
}

it("does not report when a function is in ignoreFunctionCall") {
val code = """
package foo

fun listOfChecked(value: String) = listOf(value)

fun foo() : Int {
listOfChecked("hello")
return 42
}
"""
val rule = IgnoredReturnValue(
TestConfig(
mapOf(
"ignoreFunctionCall" to listOf("foo.listOfChecked"),
"restrictToAnnotatedMethods" to false
)
)
)
val findings = rule.compileAndLintWithContext(env, code)
assertThat(findings).isEmpty()
}
}
})