pinterest / ktlint

An anti-bikeshedding Kotlin linter with built-in formatter
https://pinterest.github.io/ktlint/
MIT License
6.06k stars 504 forks source link

[1.3.0] Running `-format` adds extra spaces to class & function definition #2688

Closed mateuszkwiecinski closed 5 days ago

mateuszkwiecinski commented 3 weeks ago

Expected Behavior

Running format with autoCorrect produces valid codestyle

Observed Behavior

Running check after successful format fails

Steps to Reproduce

Given the following snippet:

class KotlinClass{

    private fun hi(){
        println("OK")
    }
}

runing ktlint -F produces:

class KotlinClass  {

    private fun hi()  {
        println("OK")
    }
}

(notice the double spaces before {)

which then fails on regular ktlint run with

.../test/KotlinClass.kt:1:19: Unnecessary long whitespace (standard:no-multi-spaces)
.../test/KotlinClass.kt:1:20: Expected a single space before class body (standard:class-signature)
.../test/KotlinClass.kt:3:22: Unnecessary long whitespace (standard:no-multi-spaces)
.../test/KotlinClass.kt:3:23: Expected a single white space before start of function body (standard:function-start-of-body-spacing)
.../test/KotlinClass.kt:3:23: Expected a single space before body block (standard:function-signature)
22:35:13.777 [main] WARN com.pinterest.ktlint.cli.internal.KtlintCommandLine -- Lint has found errors than can be autocorrected using 'ktlint --format'

Summary error count (descending) by rule:
  standard:no-multi-spaces: 2
  standard:class-signature: 1
  standard:function-signature: 1
  standard:function-start-of-body-spacing: 1

Your Environment

[*] insert_final_newline = true

[*.{kt,kts}] max_line_length = 140 indent_size = 4 ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = true ktlint_code_style = intellij_idea


* Name and version (or code for custom task) of integration used (Gradle plugin, Maven plugin, command line, custom Gradle task): https://github.com/usefulness/ktlint-gradle-plugin/pull/227
* Version of Gradle used (if applicable): 8.8
* Operating System and version: ubuntu-latest, windows-latest
paul-dingemans commented 3 weeks ago

Tnx for reporting.

This problem is present since Ktlint version 1.0.x:

 $ ktlint-1.0.1 --stdin -F
07:59:48.997 [main] INFO com.pinterest.ktlint.cli.internal.KtlintCommandLine - Enable default patterns [**/*.kt, **/*.kts]
class KotlinClass{

    private fun hi(){
        println("OK")
    }
}
class KotlinClass  {

    private fun hi()  {
        println("OK")
    }
}

It works fine in version 0.50.0

 $ ktlint-0.50.0 --stdin -F
08:00:03.120 [main] INFO com.pinterest.ktlint.cli.internal.KtlintCommandLine - Enable default patterns [**/*.kt, **/*.kts]
class KotlinClass{

    private fun hi(){
        println("OK")
    }
}
08:00:20.335 [main] WARN com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine - Format was not able to resolve all violations which (theoretically) can be autocorrected in file <stdin> in 3 consecutive runs of format.
class KotlinClass {

    private fun hi() {
        println("OK")
    }
}
mateuszkwiecinski commented 3 weeks ago

This problem is present since Ktlint version 1.0.x:

Huh, interesting 😅 I started observing this only when upgrading to 1.3.0, I had an old smoke test which started failing just now - which suggests something recent made the issue more apparent/more easily reproducible? 👀

paul-dingemans commented 3 weeks ago

Maybe it is caused by promoting sone experimental rules to standard. If your smoke test runs with non-experimental only this could explain the issue.

paul-dingemans commented 3 weeks ago

Maybe it is caused by promoting sone experimental rules to standard. If your smoke test runs with non-experimental only this could explain the issue.

After some more investigation, it turns out that the problem is caused by moving the standard:curly-spacing rule.

Disabling that rule, results in the expected code:

root = true

[*.{kt,kts}]
ktlint_standard = enabled
ktlint_standard_curly-spacing = disabled

results in the expected code:

class KotlinClass {
    private fun hi() {
        println("OK")
    }
}

It is not clear to me why you smoketest did not fail with previous 1.0.x to 1.2.x versions. The class-signature was a experimental rule which is now promoted to non-experimental. The curly-spacing rule was already non-experimental since first release of ktlint.

Anyways, it is still a bug to be resolved.