NamedArguments rule: fix false positive with trailing lambda (#3661)

This commit is contained in:
Toshiaki Kameyama
2021-04-12 06:01:57 +09:00
committed by GitHub
parent 13a838952f
commit 3fb459cd14
2 changed files with 43 additions and 2 deletions

View File

@@ -9,6 +9,7 @@ import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.api.ThresholdRule
import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtLambdaArgument
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
@@ -53,11 +54,13 @@ class NamedArguments(
}
}
@Suppress("ReturnCount")
private fun KtCallExpression.canNameArguments(): Boolean {
val unnamedArguments = valueArguments.filterNot { it.isNamed() || it is KtLambdaArgument }
if (unnamedArguments.isEmpty()) return false
val resolvedCall = getResolvedCall(bindingContext) ?: return false
if (!resolvedCall.candidateDescriptor.hasStableParameterNames()) return false
val unnamedArguments = valueArguments.filter { !it.isNamed() }
return unnamedArguments.isNotEmpty() && unnamedArguments.all {
return unnamedArguments.all {
resolvedCall.getParameterForArgument(it)?.varargElementType == null || it.getSpreadElement() != null
}
}

View File

@@ -150,5 +150,43 @@ class NamedArgumentsSpec : Spek({
val findings = namedArguments.compileAndLintWithContext(env, code)
assertThat(findings).hasSize(1)
}
context("lambda argument") {
it("inner lambda argument") {
val code = """
fun foo(a: Int, b: Int, c: Int, block: ((Int) -> Int)) {}
fun test() {
foo(a = 1, b = 2, c = 3, { it })
}
"""
val findings = namedArguments.compileAndLintWithContext(env, code)
assertThat(findings).hasSize(1)
}
it("outer lambda argument") {
val code = """
fun foo(a: Int, b: Int, c: Int, block: ((Int) -> Int)) {}
fun test() {
foo(a = 1, b = 2, c = 3) { it }
}
"""
val findings = namedArguments.compileAndLintWithContext(env, code)
assertThat(findings).hasSize(0)
}
it("unnamed argument and outer argument") {
val code = """
fun foo(a: Int, b: Int, c: Int, block: ((Int) -> Int)) {}
fun test() {
foo(a = 1, b = 2, 3) { it }
}
"""
val findings = namedArguments.compileAndLintWithContext(env, code)
assertThat(findings).hasSize(1)
}
}
}
})