Skip to content

New rule proposal: Separate the class header and body when the class header is long #2788

@3flex

Description

@3flex

Expected Behavior

Class header & body are separated after a long class header. Compliant examples from Kotlin coding conventions:

class MyFavouriteVeryLongClassHolder :
    MyLongHolder<MyFavouriteVeryLongClass>(),
    SomeOtherInterface,
    AndAnotherOne {

    fun foo() { /*...*/ }
}

In the above example, there is a blank line between the opening brace and the class body.

class MyFavouriteVeryLongClassHolder :
    MyLongHolder<MyFavouriteVeryLongClass>(),
    SomeOtherInterface,
    AndAnotherOne
{
    fun foo() { /*...*/ }
}

In the above example, there is no blank line between the opening brace and the class body, but the opening brace is on its own line.

ktlint should enforce this rule.

Observed Behavior

As far as I can tell, ktlint does not support this. Some non-compliant examples from the docs (dev-snapshot) follow.

Class signature

class Foo7(
    val bar1: Bar,
    val bar2: Bar,
) : FooBar(
        bar1,
        bar2,
    ),
    BarFoo1,
    BarFoo2 {
    // body
}

In this example, the // body sits against the header. There are other examples in class signature code samples.

No blank lines in list

class FooBar :
    Foo,
    Bar {
    // body
}

In this example, body sits against the class header. I would call this a "long" class header as it's multi-line.

I note that this proposal conflicts with "No empty first line at start in class body" so would have to be disabled or enabled only in part when ktlint_official rule style is used.

Steps to Reproduce

Your Environment

  • Version of ktlint used:
  • Relevant parts of the .editorconfig settings
  • Name and version (or code for custom task) of integration used (Gradle plugin, Maven plugin, command line, custom Gradle task):
  • Version of Gradle used (if applicable):
  • Operating System and version:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions