diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 329daf2895..10586be2ed 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -18,6 +18,8 @@ # Checks that CONSTANT (treated as const val from companion object or class level) is in non UPPER_SNAKE_CASE - name: CONSTANT_UPPERCASE enabled: true + configuration: + exceptionConstNames: "serialVersionUID" # Checks that enum value is in upper SNAKE_CASE or in PascalCase depending on the config. UPPER_SNAKE_CASE is the default, but can be changed by 'enumStyle' config - name: ENUM_VALUE enabled: true diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 24fe0cfcba..014254698e 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -152,6 +152,12 @@ class IdentifierNaming(configRules: List) : DiktatRule( ) private fun checkVariableName(node: ASTNode): List { + val configuration = ConstantUpperCaseConfiguration( + configRules.getRuleConfig(CONSTANT_UPPERCASE)?.configuration + ?: emptyMap()) + + val exceptionNames = configuration.exceptionConstNames + // special case for Destructuring declarations that can be treated as parameters in lambda: var namesOfVariables = extractVariableIdentifiers(node) @@ -178,7 +184,7 @@ class IdentifierNaming(configRules: List) : DiktatRule( // check for constant variables - check for val from companion object or on global file level // it should be in UPPER_CASE, no need to raise this warning if it is one-letter variable if (node.isConstant()) { - if (!variableName.text.isUpperSnakeCase() && variableName.text.length > 1) { + if (!exceptionNames.contains(variableName.text) && !variableName.text.isUpperSnakeCase() && variableName.text.length > 1) { CONSTANT_UPPERCASE.warnOnlyOrWarnAndFix( configRules = configRules, emit = emitWarn, @@ -493,6 +499,10 @@ class IdentifierNaming(configRules: List) : DiktatRule( } ?: Style.SNAKE_CASE } + class ConstantUpperCaseConfiguration(config: Map) : RuleConfiguration(config) { + val exceptionConstNames = config["exceptionConstNames"]?.split(',') ?: emptyList() + } + class BooleanFunctionsConfiguration(config: Map) : RuleConfiguration(config) { /** * A list of functions that return boolean and are allowed to use. Input is in a form "foo, bar". diff --git a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt index 180f0e64e8..f41a6e3cd0 100644 --- a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt @@ -41,6 +41,11 @@ class IdentifierNamingWarnTest : LintTestBase(::IdentifierNaming) { RulesConfig(FUNCTION_BOOLEAN_PREFIX.name, true, mapOf("allowedPrefixes" to "equals, equivalent, foo")) ) + private val rulesConfigConstantUpperCase = listOf( + RulesConfig(CONSTANT_UPPERCASE.name, true, mapOf( + "exceptionConstNames" to "serialVersionUID" + )) + ) // ======== checks for generics ======== @Test @@ -195,6 +200,37 @@ class IdentifierNamingWarnTest : LintTestBase(::IdentifierNaming) { ) } + @Test + @Tag(WarningNames.CONSTANT_UPPERCASE) + fun `serialVersionUID should be ignored`() { + lintMethod( + """ + class TestSerializableClass() : Serializable { + companion object { + private const val serialVersionUID: Long = -1 + } + } + """.trimIndent(), + rulesConfigList = rulesConfigConstantUpperCase + ) + } + + @Test + @Tag(WarningNames.CONSTANT_UPPERCASE) + fun `should trigger when the name is not exception`() { + val code = + """ + class TestSerializableClass() : Serializable { + companion object { + private const val serialVersion: Long = -1 + } + } + """.trimIndent() + lintMethod(code, + DiktatError(3, 27, ruleId, "${CONSTANT_UPPERCASE.warnText()} serialVersion", true) + ) + } + @Test @Tags(Tag(WarningNames.IDENTIFIER_LENGTH), Tag(WarningNames.VARIABLE_NAME_INCORRECT)) fun `check variable length (check - negative)`() {