forked from detekt/detekt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FunctionSuppressor.kt
53 lines (49 loc) · 2.17 KB
/
FunctionSuppressor.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
package io.gitlab.arturbosch.detekt.core.suppressors
import io.github.detekt.tooling.api.FunctionMatcher
import io.gitlab.arturbosch.detekt.api.ConfigAware
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
/**
* Suppress any issue raised under a function definition that matches the signatures defined at `ignoreFunction`.
*
* *Note*: this Suppressor doesn't suppress issues found when you call these functions. It just suppresses the ones in
* the function **definition**.
*
* @config ignoreFunction: List<String> The signature of the function. You can ignore all the overloads of a function
* defining just its name like `java.time.LocalDate.now` or you can specify the parameters to only suppress one:
* `java.time.LocalDate(java.time.Clock)`.
*
* *Note:* you need to write all the types with fully qualified names e.g. `org.example.foo(kotlin.String)`. It
* is important to add `kotlin.String`. Just adding `String` will not work.
*/
internal fun functionSuppressorFactory(rule: ConfigAware, bindingContext: BindingContext): Suppressor? {
val functionMatchers = rule.valueOrDefault("ignoreFunction", emptyList<String>())
.map(FunctionMatcher::fromFunctionSignature)
return if (functionMatchers.isNotEmpty()) {
Suppressor { finding ->
val element = finding.entity.ktElement
element != null && functionSuppressor(element, bindingContext, functionMatchers)
}
} else {
null
}
}
private fun functionSuppressor(
element: KtElement,
bindingContext: BindingContext,
functionMatchers: List<FunctionMatcher>
): Boolean {
return element.isInFunctionNamed(bindingContext, functionMatchers)
}
private fun KtElement.isInFunctionNamed(
bindingContext: BindingContext,
functionMatchers: List<FunctionMatcher>
): Boolean {
return if (this is KtNamedFunction && functionMatchers.any { it.match(this, bindingContext) }) {
true
} else {
getStrictParentOfType<KtNamedFunction>()?.isInFunctionNamed(bindingContext, functionMatchers) ?: false
}
}