From 715b8c6a08a8cee05b034adc83a4b046e0ce33fe Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Sat, 30 Sep 2023 16:02:58 +0200 Subject: [PATCH 1/2] Force blank line before object declaration if preceded by another declaration Closes #2284 --- CHANGELOG.md | 1 + .../rules/BlankLineBeforeDeclarationRule.kt | 2 ++ .../BlankLineBeforeDeclarationRuleTest.kt | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1460ff7a9..3186173098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). * 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) * Do not replace function body having a return statement only in case the return statement contains an intermediate exit point 'function-expression-body' [#2269](https://github.com/pinterest/ktlint/issue/2269) +* Force blank line before object declaration if preceded by another declaration `blank-line-before-declaration` [#2284](https://github.com/pinterest/ktlint/issues/2284) ### Changed diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt index b75c306864..1c77388078 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt @@ -8,6 +8,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.EQ import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUNCTION_LITERAL import com.pinterest.ktlint.rule.engine.core.api.ElementType.LBRACE +import com.pinterest.ktlint.rule.engine.core.api.ElementType.OBJECT_DECLARATION import com.pinterest.ktlint.rule.engine.core.api.ElementType.PROPERTY import com.pinterest.ktlint.rule.engine.core.api.ElementType.PROPERTY_ACCESSOR import com.pinterest.ktlint.rule.engine.core.api.ElementType.WHEN @@ -48,6 +49,7 @@ public class BlankLineBeforeDeclarationRule : CLASS, CLASS_INITIALIZER, FUN, + OBJECT_DECLARATION, PROPERTY, PROPERTY_ACCESSOR, -> diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt index cee323deb7..b18c7c798f 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt @@ -3,6 +3,7 @@ package com.pinterest.ktlint.ruleset.standard.rules import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CODE_STYLE_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CodeStyleValue import com.pinterest.ktlint.test.KtLintAssertThat +import com.pinterest.ktlint.test.KtlintDocumentationTest import com.pinterest.ktlint.test.LintViolation import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test @@ -459,4 +460,31 @@ class BlankLineBeforeDeclarationRuleTest { """.trimIndent() blankLineBeforeDeclarationRuleAssertThat(code).hasNoLintViolations() } + + @KtlintDocumentationTest + fun `Issue 2284 - Given an object declaration preceded by another declaration`() { + val code = + """ + class C + data class DC(val v: Any) + interface I + object O + """.trimIndent() + val formattedCode = + """ + class C + + data class DC(val v: Any) + + interface I + + object O + """.trimIndent() + blankLineBeforeDeclarationRuleAssertThat(code) + .hasLintViolations( + LintViolation(2, 1, "Expected a blank line for this declaration"), + LintViolation(3, 1, "Expected a blank line for this declaration"), + LintViolation(4, 1, "Expected a blank line for this declaration"), + ).isFormattedAs(formattedCode) + } } From a45e51ba4cf0c93ff98c43f0ec99a1a2da8769e2 Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Sat, 30 Sep 2023 16:12:48 +0200 Subject: [PATCH 2/2] Do not force blank line in object literal --- .../standard/rules/BlankLineBeforeDeclarationRule.kt | 10 ++++++++++ .../rules/BlankLineBeforeDeclarationRuleTest.kt | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt index 1c77388078..e7a5475a60 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt @@ -9,6 +9,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUN import com.pinterest.ktlint.rule.engine.core.api.ElementType.FUNCTION_LITERAL import com.pinterest.ktlint.rule.engine.core.api.ElementType.LBRACE import com.pinterest.ktlint.rule.engine.core.api.ElementType.OBJECT_DECLARATION +import com.pinterest.ktlint.rule.engine.core.api.ElementType.OBJECT_LITERAL import com.pinterest.ktlint.rule.engine.core.api.ElementType.PROPERTY import com.pinterest.ktlint.rule.engine.core.api.ElementType.PROPERTY_ACCESSOR import com.pinterest.ktlint.rule.engine.core.api.ElementType.WHEN @@ -128,6 +129,15 @@ public class BlankLineBeforeDeclarationRule : return } + if (node.elementType == OBJECT_DECLARATION && node.treeParent.elementType == OBJECT_LITERAL) { + // Allow: + // fun foo() = + // object : Foo() { + // // some declarations + // } + return + } + node .takeIf { it.psi is KtDeclaration } ?.takeIf { diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt index b18c7c798f..bcfb78a219 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRuleTest.kt @@ -487,4 +487,16 @@ class BlankLineBeforeDeclarationRuleTest { LintViolation(4, 1, "Expected a blank line for this declaration"), ).isFormattedAs(formattedCode) } + + @Test + fun `Issue 2284 - Given an object declaration wrapped in object literal`() { + val code = + """ + fun foo() = + object : Foo() { + // some declarations + } + """.trimIndent() + blankLineBeforeDeclarationRuleAssertThat(code).hasNoLintViolations() + } }