forked from detekt/detekt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ForbiddenImport.kt
72 lines (60 loc) · 2.82 KB
/
ForbiddenImport.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
63
64
65
66
67
68
69
70
71
72
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.config
import io.gitlab.arturbosch.detekt.api.internal.Configuration
import io.gitlab.arturbosch.detekt.api.simplePatternToRegex
import io.gitlab.arturbosch.detekt.api.valuesWithReason
import org.jetbrains.kotlin.psi.KtImportDirective
/**
* This rule allows to set a list of forbidden imports. This can be used to discourage the use of unstable, experimental
* or deprecated APIs. Detekt will then report all imports that are forbidden.
*
* <noncompliant>
* import kotlin.jvm.JvmField
* import kotlin.SinceKotlin
* </noncompliant>
*/
class ForbiddenImport(config: Config = Config.empty) : Rule(config) {
override val issue = Issue(
javaClass.simpleName,
Severity.Style,
"Mark forbidden imports. A forbidden import could be an import for an unstable / experimental api " +
"and hence you might want to mark it as forbidden in order to get warned about the usage.",
Debt.TEN_MINS
)
@Configuration("imports which should not be used")
private val imports: List<Forbidden> by config(valuesWithReason()) { list ->
list.map { Forbidden(it.value.simplePatternToRegex(), it.reason) }
}
@Configuration("reports imports which match the specified regular expression. For example `net.*R`.")
private val forbiddenPatterns: Regex by config("", String::toRegex)
override fun visitImportDirective(importDirective: KtImportDirective) {
super.visitImportDirective(importDirective)
val import = importDirective.importedFqName?.asString().orEmpty()
val forbidden = imports.find { it.import.matches(import) }
val reason = if (forbidden != null) {
if (forbidden.reason != null) {
"The import `$import` has been forbidden: ${forbidden.reason}"
} else {
defaultReason(import)
}
} else {
if (containsForbiddenPattern(import)) defaultReason(import) else null
}
if (reason != null) {
report(CodeSmell(issue, Entity.from(importDirective), reason))
}
}
private fun defaultReason(forbiddenImport: String): String {
return "The import `$forbiddenImport` has been forbidden in the detekt config."
}
private fun containsForbiddenPattern(import: String): Boolean =
forbiddenPatterns.pattern.isNotEmpty() && forbiddenPatterns.containsMatchIn(import)
}
private data class Forbidden(val import: Regex, val reason: String?)