From 0bab9b8bb41c21181749d55444e3bf99484b47b0 Mon Sep 17 00:00:00 2001 From: Paul Dingemans Date: Mon, 4 Sep 2023 19:54:03 +0200 Subject: [PATCH] Do not remove parenthesis after explicit class constructor without arguments (#2226) --- CHANGELOG.md | 1 + .../ruleset/standard/rules/ClassSignatureRule.kt | 8 +++++++- .../ruleset/standard/rules/ClassSignatureRuleTest.kt | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46e5b91863..f239ee5e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ If an `EditorConfigProperty` is defined in a `Rule` that is only provided via a * Fix wrapping of multiline postfix expression `multiline-expression-wrapping` [#2183](https://github.com/pinterest/ktlint/issues/2183) * Remove registration of class "org.jetbrains.kotlin.com.intellij.treeCopyHandler" as extension point for the compiler as this is not supported in the embedded Kotlin compiler version 1.9. Also remove Ktlint CLI command line flag `disable-kotlin-extension-point`, and parameter `enableKotlinCompilerExtensionPoint` from `KtLintRuleEngine` to disable the kotlin extension point [#2061](https://github.com/pinterest/ktlint/issues/2061) * Do not wrap expression after a spread operator `multiline-expression-wrapping` [#2188](https://github.com/pinterest/ktlint/issues/2188) +* Do not remove parenthesis after explicit constructor keyword when it has no parameters ([#2226](https://github.com/pinterest/ktlint/pull/2226)) ### Changed diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRule.kt index aee1bb71e1..153489a50d 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRule.kt @@ -6,6 +6,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.CLASS import com.pinterest.ktlint.rule.engine.core.api.ElementType.CLASS_BODY import com.pinterest.ktlint.rule.engine.core.api.ElementType.COLON import com.pinterest.ktlint.rule.engine.core.api.ElementType.COMMA +import com.pinterest.ktlint.rule.engine.core.api.ElementType.CONSTRUCTOR_KEYWORD import com.pinterest.ktlint.rule.engine.core.api.ElementType.MODIFIER_LIST import com.pinterest.ktlint.rule.engine.core.api.ElementType.PRIMARY_CONSTRUCTOR import com.pinterest.ktlint.rule.engine.core.api.ElementType.RPAR @@ -39,6 +40,7 @@ import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpaceWithNewline import com.pinterest.ktlint.rule.engine.core.api.nextCodeLeaf import com.pinterest.ktlint.rule.engine.core.api.nextCodeSibling import com.pinterest.ktlint.rule.engine.core.api.nextLeaf +import com.pinterest.ktlint.rule.engine.core.api.prevCodeSibling import com.pinterest.ktlint.rule.engine.core.api.prevLeaf import com.pinterest.ktlint.rule.engine.core.api.prevSibling import com.pinterest.ktlint.rule.engine.core.api.upsertWhitespaceAfterMe @@ -251,7 +253,11 @@ public class ClassSignatureRule : node .getPrimaryConstructorParameterListOrNull() ?.takeUnless { it.containsComment() } - ?.let { parameterList -> + ?.takeUnless { + // Allow: + // class Foo constructor() { ... } + it.prevCodeSibling()?.elementType == CONSTRUCTOR_KEYWORD + }?.let { parameterList -> if (!dryRun) { emit(parameterList.startOffset, "No parenthesis expected", true) } diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRuleTest.kt index cc054f425d..85def18e48 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/ClassSignatureRuleTest.kt @@ -1684,6 +1684,17 @@ class ClassSignatureRuleTest { ).isFormattedAs(formattedCode) } + @Test + fun `Given a class with an explicit constructor not having arguments`() { + val code = + """ + class Foo constructor() { + fun bar() + } + """.trimIndent() + classSignatureWrappingRuleAssertThat(code).hasNoLintViolations() + } + private companion object { const val UNEXPECTED_SPACES = " " const val NO_SPACE = ""