diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt index 2febc6aa1..f7930795f 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt @@ -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 } } diff --git a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt index 92dbec9da..632a645ca 100644 --- a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt +++ b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt @@ -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) + } + } } })