From 6ff4edb6c23d54c1fea5b8c2b444fa600b255cf5 Mon Sep 17 00:00:00 2001 From: soWhoAmI Date: Tue, 29 Dec 2020 16:44:46 +0300 Subject: [PATCH] feature/more-prefixes-boolean-methods(#417) ### What's done: * Added more prefixes --- diktat-analysis.yml | 2 ++ .../diktat/ruleset/rules/IdentifierNaming.kt | 13 +++++++- .../main/resources/diktat-analysis-huawei.yml | 2 ++ .../src/main/resources/diktat-analysis.yml | 2 ++ .../chapter1/IdentifierNamingWarnTest.kt | 31 +++++++++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 38a03d1f58..a574b62889 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -18,6 +18,8 @@ enabled: true - name: FUNCTION_BOOLEAN_PREFIX enabled: true + configuration: + allowedFunctions: "" # A list of functions that return boolean and are allowed to use. Input is in a form "foo, bar". - name: FUNCTION_NAME_INCORRECT_CASE enabled: true - name: GENERIC_NAME diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt index 145ee19869..e1ea3a2091 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/IdentifierNaming.kt @@ -57,6 +57,7 @@ import com.pinterest.ktlint.core.ast.ElementType.TYPE_REFERENCE import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER_LIST import com.pinterest.ktlint.core.ast.parent import com.pinterest.ktlint.core.ast.prevCodeSibling +import org.cqfn.diktat.ruleset.constants.Warnings import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement @@ -358,7 +359,10 @@ class IdentifierNaming(private val configRules: List) : Rule("ident if (!node.isOverridden()) { // if function has Boolean return type in 99% of cases it is much better to name it with isXXX or hasXXX prefix if (functionReturnType != null && functionReturnType == PrimitiveType.BOOLEAN.typeName.asString()) { - if (booleanMethodPrefixes.none { functionName.text.startsWith(it) }) { + val configuration = BooleanFunctionsConfiguration( + this.configRules.getRuleConfig(FUNCTION_BOOLEAN_PREFIX)?.configuration ?: emptyMap() + ) + if (booleanMethodPrefixes.none { functionName.text.startsWith(it) } && functionName.text !in configuration.allowedBooleanFunctions) { FUNCTION_BOOLEAN_PREFIX.warnAndFix(configRules, emitWarn, isFixMode, functionName.text, functionName.startOffset, functionName) { // FixMe: add agressive autofix for this } @@ -426,6 +430,13 @@ class IdentifierNaming(private val configRules: List) : Rule("ident } ?: Style.SNAKE_CASE } + 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". + */ + val allowedBooleanFunctions = config["allowedFunctions"]?.split(",")?.map { it.trim() } ?: emptyList() + } + companion object { const val MAX_IDENTIFIER_LENGTH = 64 const val MIN_IDENTIFIER_LENGTH = 2 diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index 3d8614fc42..99b7231f27 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -16,6 +16,8 @@ enabled: true - name: FUNCTION_BOOLEAN_PREFIX enabled: true + configuration: + allowedFunctions: "" # A list of functions that return boolean and are allowed to use. Input is in a form "foo, bar". - name: FUNCTION_NAME_INCORRECT_CASE enabled: true - name: GENERIC_NAME diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index a043d1d4d5..c28df4abae 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -17,6 +17,8 @@ enabled: true - name: FUNCTION_BOOLEAN_PREFIX enabled: true + configuration: + allowedFunctions: "" # A list of functions that return boolean and are allowed to use. Input is in a form "foo, bar". - name: FUNCTION_NAME_INCORRECT_CASE enabled: true - name: GENERIC_NAME diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt index d765473f31..a6156fdfc3 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter1/IdentifierNamingWarnTest.kt @@ -27,6 +27,10 @@ import org.junit.jupiter.api.Test class IdentifierNamingWarnTest : LintTestBase(::IdentifierNaming) { private val ruleId: String = "$DIKTAT_RULE_SET_ID:identifier-naming" + private val rulesConfigBooleanFunctions: List = listOf( + RulesConfig(FUNCTION_BOOLEAN_PREFIX.name, true, + mapOf("allowedFunctions" to "equals, equivalent, foo")) + ) // ======== checks for generics ======== @Test @Tag(WarningNames.GENERIC_NAME) @@ -392,6 +396,33 @@ class IdentifierNamingWarnTest : LintTestBase(::IdentifierNaming) { ) } + @Test + @Tag(WarningNames.FUNCTION_BOOLEAN_PREFIX) + fun `all prefixes for boolean methods`() { + lintMethod( + """ + fun hasEmptyLineAfter(): Boolean { } + fun haveEmptyLineAfter(): Boolean { } + fun isEmpty(): Boolean { } + fun shouldBeEmpty(): Boolean { } + fun areEmpty(): Boolean { } + """.trimIndent() + ) + } + + @Test + @Tag(WarningNames.FUNCTION_BOOLEAN_PREFIX) + fun `test allowed boolean functions in configuration`() { + lintMethod( + """ + fun equals(): Boolean { } + fun foo(): Boolean { } + fun equivalent(): Boolean { } + """.trimIndent(), + rulesConfigList = rulesConfigBooleanFunctions + ) + } + @Test @Tag(WarningNames.IDENTIFIER_LENGTH) fun `regression - function argument type`() {