forked from detekt/detekt
/
AlsoCouldBeApply.kt
62 lines (57 loc) · 2.05 KB
/
AlsoCouldBeApply.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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.rules.IT_LITERAL
import io.gitlab.arturbosch.detekt.rules.safeAs
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression
/**
* Detects when an `also` block contains only `it`-started expressions.
*
* By refactoring the `also` block to an `apply` block makes it so that all `it`s can be removed
* thus making the block more concise and easier to read.
*
* <noncompliant>
* Buzz().also {
* it.init()
* it.block()
* }
* </noncompliant>
*
* <compliant>
* Buzz().apply {
* init()
* block()
* }
*
* // Also compliant
* fun foo(a: Int): Int {
* return a.also { println(it) }
* }
* </compliant>
*/
class AlsoCouldBeApply(config: Config = Config.empty) : Rule(config) {
override val issue = Issue(
"AlsoCouldBeApply",
Severity.Style,
"When an `also` block contains only `it`-started expressions, simplify it to the `apply` block.",
Debt.FIVE_MINS
)
@Suppress("ReturnCount")
override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
val callee = expression.calleeExpression?.takeIf { it.text == "also" } ?: return
val lambda = expression.lambdaArguments.singleOrNull()?.getLambdaExpression()
?: expression.valueArguments.singleOrNull()?.getArgumentExpression()?.safeAs()
?: return
val statements = lambda.bodyExpression?.statements.orEmpty().ifEmpty { return }
if (statements.all { it.safeAs<KtQualifiedExpression>()?.receiverExpression?.text == IT_LITERAL }) {
report(CodeSmell(issue, Entity.from(callee), issue.description))
}
}
}