mirror of
https://github.com/jlengrand/detekt.git
synced 2026-03-10 08:11:23 +00:00
NamedArguments: fix false positive with varargs (#3294)
This commit is contained in:
committed by
GitHub
parent
3409f39bff
commit
37f0a1d006
@@ -9,6 +9,7 @@ import io.gitlab.arturbosch.detekt.api.Severity
|
||||
import io.gitlab.arturbosch.detekt.api.ThresholdRule
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
|
||||
/**
|
||||
@@ -43,16 +44,22 @@ class NamedArguments(
|
||||
override fun visitCallExpression(expression: KtCallExpression) {
|
||||
if (bindingContext == BindingContext.EMPTY) return
|
||||
val valueArguments = expression.valueArguments
|
||||
if (valueArguments.size > threshold &&
|
||||
valueArguments.any { !it.isNamed() } &&
|
||||
expression.getResolvedCall(bindingContext)?.candidateDescriptor?.hasStableParameterNames() == true
|
||||
) {
|
||||
if (valueArguments.size > threshold && expression.canNameArguments()) {
|
||||
report(CodeSmell(issue, Entity.from(expression), issue.description))
|
||||
} else {
|
||||
super.visitCallExpression(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtCallExpression.canNameArguments(): Boolean {
|
||||
val resolvedCall = getResolvedCall(bindingContext) ?: return false
|
||||
if (!resolvedCall.candidateDescriptor.hasStableParameterNames()) return false
|
||||
val unnamedArguments = valueArguments.filter { !it.isNamed() }
|
||||
return unnamedArguments.isNotEmpty() && unnamedArguments.all {
|
||||
resolvedCall.getParameterForArgument(it)?.varargElementType == null || it.getSpreadElement() != null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_FUNCTION_THRESHOLD = 3
|
||||
}
|
||||
|
||||
@@ -117,14 +117,38 @@ class NamedArgumentsSpec : Spek({
|
||||
|
||||
it("java method invocation should not be flagged") {
|
||||
val code = """
|
||||
import java.time.LocalDateTime
|
||||
|
||||
fun test() {
|
||||
LocalDateTime.of(2020, 3, 13, 14, 0, 0)
|
||||
}
|
||||
import java.time.LocalDateTime
|
||||
|
||||
fun test() {
|
||||
LocalDateTime.of(2020, 3, 13, 14, 0, 0)
|
||||
}
|
||||
"""
|
||||
val findings = namedArguments.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(0)
|
||||
}
|
||||
|
||||
it("invocation with varargs should not be flagged") {
|
||||
val code = """
|
||||
fun foo(vararg i: Int) {}
|
||||
fun bar(a: Int, b: Int, c: Int, vararg s: String) {}
|
||||
fun test() {
|
||||
foo(1, 2, 3, 4, 5)
|
||||
bar(1, 2, 3, "a")
|
||||
}
|
||||
"""
|
||||
val findings = namedArguments.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(0)
|
||||
}
|
||||
|
||||
it("invocation with spread operator should be flagged") {
|
||||
val code = """
|
||||
fun bar(a: Int, b: Int, c: Int, vararg s: String) {}
|
||||
fun test() {
|
||||
bar(1, 2, 3, *arrayOf("a"))
|
||||
}
|
||||
"""
|
||||
val findings = namedArguments.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user