From 52d3d16ebcd78039c8b05b9a5dc4ed16b7846f7c Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Sat, 23 Sep 2023 14:24:49 +0200 Subject: [PATCH] Ignore override of function in rule `function-naming` A function override should not be reported as the interface of class that defines the function might be out of scope of the project in which case the function name can not be changed. Note that the function will still be reported at the interface or class itself whenever that interface or class is defined inside the scope of the project. Closes #2271 --- CHANGELOG.md | 1 + .../standard/rules/FunctionNamingRule.kt | 17 ++++++++++++++++- .../standard/rules/FunctionNamingRuleTest.kt | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23fd898cf5..c8db6c742c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). * Fix indent of multiline object declaration inside class `indent` [#2257](https://github.com/pinterest/ktlint/issue/2257) * Ignore anonymous function in rule `function-naming` [#2260](https://github.com/pinterest/ktlint/issue/2260) * Do not force blank line before function in right hand side of assignment `blank-line-before-declaration` [#2260](https://github.com/pinterest/ktlint/issue/2260) +* Ignore override of function in rule `function-naming` [#2271](https://github.com/pinterest/ktlint/issue/2271) ### Changed diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRule.kt index a1ad1baab4..16f78800c2 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRule.kt @@ -4,11 +4,14 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN_KEYWORD import com.pinterest.ktlint.rule.engine.core.api.ElementType.IDENTIFIER import com.pinterest.ktlint.rule.engine.core.api.ElementType.IMPORT_DIRECTIVE +import com.pinterest.ktlint.rule.engine.core.api.ElementType.MODIFIER_LIST +import com.pinterest.ktlint.rule.engine.core.api.ElementType.OVERRIDE_KEYWORD import com.pinterest.ktlint.rule.engine.core.api.ElementType.VALUE_PARAMETER_LIST import com.pinterest.ktlint.rule.engine.core.api.RuleId import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.EXPERIMENTAL import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.STABLE +import com.pinterest.ktlint.rule.engine.core.api.children import com.pinterest.ktlint.rule.engine.core.api.nextCodeSibling import com.pinterest.ktlint.ruleset.standard.StandardRule import com.pinterest.ktlint.ruleset.standard.rules.internal.regExIgnoringDiacriticsAndStrokesOnLetters @@ -47,7 +50,8 @@ public class FunctionNamingRule : StandardRule("function-naming") { node.isFactoryMethod() || node.isTestMethod() || node.hasValidFunctionName() || - node.isAnonymousFunction() + node.isAnonymousFunction() || + node.isOverrideFunction() }?.let { val identifierOffset = node @@ -86,6 +90,17 @@ public class FunctionNamingRule : StandardRule("function-naming") { ?.nextCodeSibling() ?.elementType + /* + * A function override should not be reported as the interface of class that defines the function might be out of scope of the project + * in which case the function name can not be changed. Note that the function will still be reported at the interface or class itself + * whenever that interface or class is defined inside the scope of the project. + */ + private fun ASTNode.isOverrideFunction() = + findChildByType(MODIFIER_LIST) + ?.children() + .orEmpty() + .any { it.elementType == OVERRIDE_KEYWORD } + private companion object { val VALID_FUNCTION_NAME_REGEXP = "[a-z][A-Za-z\\d]*".regExIgnoringDiacriticsAndStrokesOnLetters() val VALID_TEST_FUNCTION_NAME_REGEXP = "(`.*`)|([a-z][A-Za-z\\d_]*)".regExIgnoringDiacriticsAndStrokesOnLetters() diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRuleTest.kt index 34ab7fb691..6231c28077 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/FunctionNamingRuleTest.kt @@ -182,4 +182,18 @@ class FunctionNamingRuleTest { """.trimIndent() functionNamingRuleAssertThat(code).hasNoLintViolations() } + + @Test + fun `Issue 2271 - Given an override fun then do not report a violation of the rule as it might not be possible to change the signature of the rule when defined outside scope of project`() { + val code = + """ + // Assume that Bar is defined outside the scope of the project. As of that the function signature can not be changed to comply + // to the function-naming rule. In case that Bar is defined inside the scope of the project, the violation will still be + // reported in the Bar class/interface itself. + class Foo : Bar { + override fun Something() + } + """.trimIndent() + functionNamingRuleAssertThat(code).hasNoLintViolations() + } }