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

Indentation error on malformed formatter closing tag #2695

Closed paul-dingemans closed 5 days ago

paul-dingemans commented 2 weeks ago

From https://github.com/nbadal/ktlint-intellij-plugin/issues/535

Given .editorconfig:

root = true

[*.{kt,kts}]
ij_formatter_tags_enabled = true

This problem does not seem to be caused by the ktlint-intellij-plugin but in ktlint itself. I can reproduce the exact same stacktrace, by malforming the "@formatter:on" tag:

$ ktlint-1.3.0 --stdin
08:03:08.208 [main] INFO com.pinterest.ktlint.cli.internal.KtlintCommandLine -- Enable default patterns [**/*.kt, **/*.kts]
fun foo123() {
    // @formatter:off
    listOf(
        "x" to 1, "x" to 2, "x" to 3,
        "x" to 1, "x" to 2, "x" to 3,
        "y" to 1, "y" to 2, "y" to 3,
        "z" to 1, "z" to 2, "z" to 3,
    )
    // The "@formatted:on" tag below is malformed on purpose.
    // It will cause an exception when indenting
    // @formstter:on
}

Exception in thread "main" java.lang.IllegalArgumentException: Stack should be empty:
        IndentContext(fromASTNode=Element(kotlin.FILE), toASTNode=PsiWhiteSpace, nodeIndent=, firstChildIndent=, childIndent=, lastChildIndent=, activated=true)
        IndentContext(fromASTNode=BLOCK, toASTNode=PsiElement(RBRACE), nodeIndent=, firstChildIndent=    , childIndent=    , lastChildIndent=    , activated=false)
        IndentContext(fromASTNode=PsiElement(LBRACE), toASTNode=PsiElement(RBRACE), nodeIndent=, firstChildIndent=, childIndent=    , lastChildIndent=, activated=true)
        at com.pinterest.ktlint.ruleset.standard.rules.IndentationRule.afterLastNode(IndentationRule.kt:1066)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:65)
        at com.pinterest.ktlint.rule.engine.internal.CodeFormatter.executeRule(CodeFormatter.kt:116)
        at com.pinterest.ktlint.rule.engine.internal.CodeFormatter.format(CodeFormatter.kt:87)
        at com.pinterest.ktlint.rule.engine.internal.CodeFormatter.format(CodeFormatter.kt:56)
        at com.pinterest.ktlint.rule.engine.internal.CodeFormatter.format(CodeFormatter.kt:27)
        at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine.lint(KtLintRuleEngine.kt:91)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.lint(KtlintCommandLine.kt:558)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.process(KtlintCommandLine.kt:466)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.lintStdin(KtlintCommandLine.kt:425)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.lintOrFormat(KtlintCommandLine.kt:296)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.run(KtlintCommandLine.kt:246)
        at com.github.ajalt.clikt.parsers.Parser.finalizeAndRun(Parser.kt:348)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:218)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:42)
        at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:457)
        at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:454)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:474)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:481)
        at com.pinterest.ktlint.Main.main(Main.kt:20)