Add the ignoreAnnotated array parameter to the FunctionNaming rule. Add default "Composable" exclusion to ease the use of Jetpack Compose. (#2734)

This commit is contained in:
Charles Anderson
2020-05-26 13:40:14 -04:00
committed by GitHub
parent 233dc3a88e
commit 82f431674c
4 changed files with 51 additions and 0 deletions

View File

@@ -357,6 +357,7 @@ naming:
functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
excludeClassPattern: '$^'
ignoreOverridden: true
ignoreAnnotated: ['Composable']
FunctionParameterNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']

View File

@@ -1,5 +1,6 @@
package io.gitlab.arturbosch.detekt.rules.naming
import io.gitlab.arturbosch.detekt.api.AnnotationExcluder
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
@@ -11,6 +12,7 @@ import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.rules.identifierName
import io.gitlab.arturbosch.detekt.rules.isOverride
import io.gitlab.arturbosch.detekt.rules.naming.util.isContainingExcludedClassOrObject
import io.gitlab.arturbosch.detekt.rules.valueOrDefaultCommaSeparated
import org.jetbrains.kotlin.psi.KtNamedFunction
/**
@@ -21,6 +23,8 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
* @configuration functionPattern - naming pattern (default: `'([a-z][a-zA-Z0-9]*)|(`.*`)'`)
* @configuration excludeClassPattern - ignores functions in classes which match this regex (default: `'$^'`)
* @configuration ignoreOverridden - ignores functions that have the override modifier (default: `true`)
* @configuration ignoreAnnotated - ignore naming for functions in the context of these
* annotation class names (default: `['Composable']`)
*
* @active since v1.0.0
*/
@@ -36,14 +40,20 @@ class FunctionNaming(config: Config = Config.empty) : Rule(config) {
private val functionPattern by LazyRegex(FUNCTION_PATTERN, "([a-z][a-zA-Z0-9]*)|(`.*`)")
private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^")
private val ignoreOverridden = valueOrDefault(IGNORE_OVERRIDDEN, true)
private val ignoreAnnotated = valueOrDefaultCommaSeparated(IGNORE_ANNOTATED, listOf("Composable"))
override fun visitNamedFunction(function: KtNamedFunction) {
super.visitNamedFunction(function)
val annotationExcluder = AnnotationExcluder(function.containingKtFile, ignoreAnnotated)
if (ignoreOverridden && function.isOverride()) {
return
}
if (annotationExcluder.shouldExclude(function.annotationEntries)) {
return
}
if (!function.isContainingExcludedClassOrObject(excludeClassPattern) &&
!function.identifierName().matches(functionPattern) &&
function.identifierName() != function.typeReference?.name) {
@@ -60,5 +70,6 @@ class FunctionNaming(config: Config = Config.empty) : Rule(config) {
const val FUNCTION_PATTERN = "functionPattern"
const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern"
const val IGNORE_OVERRIDDEN = "ignoreOverridden"
const val IGNORE_ANNOTATED = "ignoreAnnotated"
}
}

View File

@@ -87,5 +87,39 @@ class FunctionNamingSpec : Spek({
SourceLocation(4, 19)
)
}
describe("annotated functions") {
val code = """
annotation class Composable
class D {
fun SHOULD_BE_FLAGGED() {}
}
class E {
@Suppress
fun FLAGGED_IF_NOT_IGNORED() {}
}
class F {
@Composable
fun NOT_FLAGGED_BY_DEFAULT() {}
}
"""
it("Ignores default annotated functions") {
assertThat(FunctionNaming().compileAndLint(code)).hasSourceLocations(
SourceLocation(4, 9),
SourceLocation(8, 9)
)
}
it("Ignores annotated functions if ignoreAnnotated includes the given annotation class") {
val config = TestConfig(mapOf(FunctionNaming.IGNORE_ANNOTATED to listOf("Suppress")))
assertThat(FunctionNaming(config).compileAndLint(code)).hasSourceLocations(
SourceLocation(4, 9),
SourceLocation(12, 9)
)
}
}
}
})

View File

@@ -132,6 +132,11 @@ These factory functions can have the same name as the class being created.
ignores functions that have the override modifier
* ``ignoreAnnotated`` (default: ``['Composable']``)
ignore naming for functions in the context of these
annotation class names
### FunctionParameterNaming
Reports function parameter names which do not follow the specified naming convention are used.