Skip to content

Commit

Permalink
Add config for negative function name parts
Browse files Browse the repository at this point in the history
  • Loading branch information
drawers committed Mar 27, 2023
1 parent ea570a5 commit df6a662
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
3 changes: 3 additions & 0 deletions detekt-core/src/main/resources/default-detekt-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ style:
active: false
negativeFunctions:
- 'takeUnless'
negativeFunctionNameParts:
- 'not'
- 'non'
EqualsNullCall:
active: true
EqualsOnSignatureLine:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ class DoubleNegativeLambda(config: Config = Config.empty) : Rule(config) {
KtTokens.NOT_IS,
)

private val negatingFunctionNameParts = listOf("not", "non")

@Configuration("Function names expressed in the negative that can form double negatives with their lambda blocks.")
private val negativeFunctions: Set<String> by config(listOf("takeUnless")) { it.toSet() }

@Configuration(
"Function name parts to look for in the lambda block when deciding if the lambda contains a negative."
)
private val negativeFunctionNameParts: Set<String> by config(listOf("not", "non")) { it.toSet() }

override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
val calleeExpression = expression.calleeExpression?.text ?: return
Expand Down Expand Up @@ -81,7 +84,7 @@ class DoubleNegativeLambda(config: Config = Config.empty) : Rule(config) {
return when (this) {
is KtOperationReferenceExpression -> operationSignTokenType in negationTokens
is KtCallExpression -> text == "not()" || text.split(splitCamelCaseRegex).map { it.lowercase() }
.any { it in negatingFunctionNameParts }
.any { it in negativeFunctionNameParts }

else -> false
}
Expand All @@ -91,5 +94,6 @@ class DoubleNegativeLambda(config: Config = Config.empty) : Rule(config) {

companion object {
const val NEGATIVE_FUNCTIONS = "negativeFunctions"
const val NEGATIVE_FUNCTION_NAME_PARTS = "negativeFunctionNameParts"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class DoubleNegativeLambdaSpec {
}

@Test
fun `reports function name from config`() {
fun `reports negative function name from config`() {
val config = TestConfig(DoubleNegativeLambda.NEGATIVE_FUNCTIONS to listOf("none", "filterNot"))
val code = """
fun Int.isEven() = this % 2 == 0
Expand All @@ -144,6 +144,18 @@ class DoubleNegativeLambdaSpec {
assertThat(DoubleNegativeLambda(config).compileAndLint(code)).hasSize(2)
}

@Test
fun `reports negative function name parts from config`() {
val config = TestConfig(DoubleNegativeLambda.NEGATIVE_FUNCTION_NAME_PARTS to listOf("isnt"))
val code = """
import kotlin.random.Random
fun Int.isntOdd() = this % 2 == 0
val rand = Random.Default.nextInt().takeUnless { it.isntOdd() }
""".trimIndent()

assertThat(DoubleNegativeLambda(config).compileAndLint(code)).hasSize(1)
}

@Test
fun `reports multiple negations in message`() {
val code = """
Expand Down

0 comments on commit df6a662

Please sign in to comment.