Skip to content

Commit

Permalink
Add support for reasons in ForbiddenMethodCall
Browse files Browse the repository at this point in the history
  • Loading branch information
BraisGabin committed Jun 4, 2022
1 parent 04a4eb5 commit 079779f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
6 changes: 4 additions & 2 deletions detekt-core/src/main/resources/default-detekt-config.yml
Expand Up @@ -527,8 +527,10 @@ style:
ForbiddenMethodCall:
active: false
methods:
- 'kotlin.io.print'
- 'kotlin.io.println'
- reason: 'print doesn't allow you to configure the output stream. Use a logger instead.'
value: 'kotlin.io.print'
- reason: 'println doesn't allow you to configure the output stream. Use a logger instead.'
value: 'kotlin.io.println'
ForbiddenPublicDataClass:
active: true
excludes: ['**']
Expand Down
@@ -1,6 +1,7 @@
package io.gitlab.arturbosch.detekt.rules.style

import io.github.detekt.tooling.api.FunctionMatcher
import io.github.detekt.tooling.api.FunctionMatcher.Companion.fromFunctionSignature
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
Expand All @@ -11,6 +12,7 @@ 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.internal.RequiresTypeResolution
import io.gitlab.arturbosch.detekt.api.valuesWithReason
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtExpression
Expand Down Expand Up @@ -52,12 +54,14 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) {
"`fun String.hello(a: Int)` you should add the receiver parameter as the first parameter like this: " +
"`hello(kotlin.String, kotlin.Int)`"
)
private val methods: List<FunctionMatcher> by config(
listOf(
"kotlin.io.print",
"kotlin.io.println",
private val methods: List<Forbidden> by config(
valuesWithReason(
"kotlin.io.print" to "print doesn't allow you to configure the output stream. Use a logger instead.",
"kotlin.io.println" to "println doesn't allow you to configure the output stream. Use a logger instead.",
)
) { it.map(FunctionMatcher::fromFunctionSignature) }
) { list ->
list.map { Forbidden(fromFunctionSignature(it.value), it.reason) }
}

override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
Expand Down Expand Up @@ -87,10 +91,16 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) {
} ?: return

for (descriptor in descriptors) {
methods.find { it.match(descriptor) }?.let { functionMatcher ->
val message = "The method `$functionMatcher` has been forbidden in the Detekt config."
methods.find { it.value.match(descriptor) }?.let { forbidden ->
val message = if (forbidden.reason != null) {
"The method `${forbidden.value}` has been forbidden: ${forbidden.reason}"
} else {
"The method `${forbidden.value}` has been forbidden in the Detekt config."
}
report(CodeSmell(issue, Entity.from(expression), message))
}
}
}
}

private data class Forbidden(val value: FunctionMatcher, val reason: String?)
Expand Up @@ -28,8 +28,10 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) {
SourceLocation(2, 5),
SourceLocation(3, 5)
)
assertThat(findings[0]).hasMessage("The method `kotlin.io.print` has been forbidden in the Detekt config.")
assertThat(findings[1]).hasMessage("The method `kotlin.io.println` has been forbidden in the Detekt config.")
assertThat(findings[0])
.hasMessage("The method `kotlin.io.print` has been forbidden: print doesn't allow you to configure the output stream. Use a logger instead.")
assertThat(findings[1])
.hasMessage("The method `kotlin.io.println` has been forbidden: println doesn't allow you to configure the output stream. Use a logger instead.")
}

@Test
Expand Down

0 comments on commit 079779f

Please sign in to comment.