io.gitlab.arturbosch.detekt.rules.style.ExplicitItLambdaParameter.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of detekt-rules-style Show documentation
Show all versions of detekt-rules-style Show documentation
Static code analysis for Kotlin
The newest version!
package io.gitlab.arturbosch.detekt.rules.style
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault
import io.gitlab.arturbosch.detekt.rules.IT_LITERAL
import org.jetbrains.kotlin.psi.KtLambdaExpression
/**
* Lambda expressions are one of the core features of the language. They often include very small chunks of
* code using only one parameter. In this cases Kotlin can supply the implicit `it` parameter
* to make code more concise. It fits most use cases, but when faced larger or nested chunks of code,
* you might want to add an explicit name for the parameter. Naming it just `it` is meaningless and only
* makes your code misleading, especially when dealing with nested functions.
*
*
* a?.let { it -> it.plus(1) }
* foo.flatMapObservable { it -> Observable.fromIterable(it) }
* listOfPairs.map(::second).forEach { it ->
* it.execute()
* }
* collection.zipWithNext { it, next -> Pair(it, next) }
*
*
*
* a?.let { it.plus(1) } // Much better to use implicit it
* a?.let { value: Int -> value.plus(1) } // Better as states the type more clearly
* foo.flatMapObservable(Observable::fromIterable) // Here we can have a method reference
*
* // For multiline blocks it is usually better come up with a clear and more meaningful name
* listOfPairs.map(::second).forEach { apiRequest ->
* apiRequest.execute()
* }
*
* // Lambdas with multiple parameter should be named clearly, using it for one of them can be confusing
* collection.zipWithNext { prev, next ->
* Pair(prev, next)
* }
*
*/
@ActiveByDefault(since = "1.21.0")
class ExplicitItLambdaParameter(val config: Config) : Rule(config) {
override val issue = Issue(
javaClass.simpleName,
Severity.Style,
"Declaring lambda parameters as `it` is redundant.",
Debt.FIVE_MINS
)
override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {
super.visitLambdaExpression(lambdaExpression)
val parameterNames = lambdaExpression.valueParameters.map { it.name }
if (IT_LITERAL in parameterNames) {
val message =
if (
parameterNames.size == 1 &&
lambdaExpression.valueParameters[0].typeReference == null
) {
"This explicit usage of `it` as the lambda parameter name can be omitted."
} else {
"`it` should not be used as name for a lambda parameter."
}
report(
CodeSmell(
issue,
Entity.from(lambdaExpression),
message
)
)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy