Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ktlint 1.0 crashes with LetsPlot Kotlin syntax #2286

Closed
ccjernigan opened this issue Sep 30, 2023 · 1 comment · Fixed by #2290
Closed

Ktlint 1.0 crashes with LetsPlot Kotlin syntax #2286

ccjernigan opened this issue Sep 30, 2023 · 1 comment · Fixed by #2290
Milestone

Comments

@ccjernigan
Copy link

Expected Behavior

Ktlint successfully formats typical usages of LetsPlot Kotlin API (which is admittedly less idiomatic for Kotlin but that's how the API works).

Observed Behavior

com.pinterest.ktlint.rule.engine.api.KtLintRuleException: Rule 'standard:multiline-expression-wrapping' throws exception in file 'LetsPlotTimeSeriesGradientPlot.kt' at position (0:0)
   Rule maintainer: KtLint
   Issue tracker  : https://github.com/pinterest/ktlint/issues
   Repository     : https://github.com/pinterest/ktlint
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:65)
	at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:146)
	at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:145)
	at com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:46)
	at com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:44)
	at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine.format(KtLintRuleEngine.kt:145)
	at com.pinterest.ktlint.cli.internal.KtlintCommandLine.format(KtlintCommandLine.kt:485)
	at com.pinterest.ktlint.cli.internal.KtlintCommandLine.process(KtlintCommandLine.kt:471)
	at com.pinterest.ktlint.cli.internal.KtlintCommandLine.access$process(KtlintCommandLine.kt:59)
	at com.pinterest.ktlint.cli.internal.KtlintCommandLine$lintFiles$3.invoke$lambda$0(KtlintCommandLine.kt:411)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Cannot invoke "org.jetbrains.kotlin.com.intellij.lang.ASTNode.getElementType()" because the return value of "org.jetbrains.kotlin.com.intellij.lang.ASTNode.getFirstChildNode()" is null
	at com.pinterest.ktlint.ruleset.standard.rules.MultilineExpressionWrappingRule.isElvisOperator(MultilineExpressionWrappingRule.kt:155)
	at com.pinterest.ktlint.ruleset.standard.rules.MultilineExpressionWrappingRule.isValueInAnAssignment(MultilineExpressionWrappingRule.kt:144)
	at com.pinterest.ktlint.ruleset.standard.rules.MultilineExpressionWrappingRule.needToWrapMultilineExpression(MultilineExpressionWrappingRule.kt:135)
	at com.pinterest.ktlint.ruleset.standard.rules.MultilineExpressionWrappingRule.visitExpression(MultilineExpressionWrappingRule.kt:103)
	at com.pinterest.ktlint.ruleset.standard.rules.MultilineExpressionWrappingRule.beforeVisitChildNodes(MultilineExpressionWrappingRule.kt:85)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:125)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:124)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:124)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
	at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:62)
	... 13 more
 ()

Steps to Reproduce

This code will reproduce the failure

        val firstPlot = letsPlot() + geomLine(rawDataframe, color = "blue", sampling = samplingNone) {
            x = X
            y = Y
            group = GROUP
        } + geomPoint(detectionDataframe, color = "red") {
            x = X
            y = Y
            group = GROUP
        } + ggtitle(
            title
        ) + scaleXDateTime(format = "%H:%M:%S") + ggsize(
            IMAGE_PIXELS_WIDTH,
            IMAGE_PIXELS_HEIGHT
        ) + facetGrid(y = GROUP, scales = "free_y")

Workaround

Changing to a var and reassigning it is a workaround for this Ktlint crash.

        var firstPlot = letsPlot()
        firstPlot +=
            geomLine(rawDataframe, color = "blue", sampling = samplingNone) {
                x = X
                y = Y
                group = GROUP
            }
        firstPlot +=
            geomPoint(detectionDataframe, color = "red") {
                x = X
                y = Y
                group = GROUP
            }
        firstPlot +=
            ggtitle(
                title
            )
        firstPlot += scaleXDateTime(format = "%H:%M:%S") +
            ggsize(
                IMAGE_PIXELS_WIDTH,
                IMAGE_PIXELS_HEIGHT
            )
        firstPlot += facetGrid(y = GROUP, scales = "free_y")

Your Environment

  • Version of ktlint used: 1.0
  • 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): Custom gradle task
  • Version of Gradle used (if applicable): 8.3
  • Operating System and version: macOS Sonoma
@paul-dingemans
Copy link
Collaborator

Interestingly. I can reproduce the problem with simplified example below:

val foo = foo() + bar {
    "bar"
} + bar {
    "bar"
}

which does not throw the error if the code was (already manually) formatted as:

val foo =
    foo() +
        bar {
            "bar"
        } +
        bar {
            "bar"
        }

Your code is also accepted when it is formatted as:

val firstPlot =
    letsPlot() +
        geomLine(rawDataframe, color = "blue", sampling = samplingNone) {
            x = X
            y = Y
            group = GROUP
        } +
        geomPoint(detectionDataframe, color = "red") {
            x = X
            y = Y
            group = GROUP
        } +
        ggtitle(title) +
        scaleXDateTime(format = "%H:%M:%S") +
        ggsize(
            IMAGE_PIXELS_WIDTH,
            IMAGE_PIXELS_HEIGHT,
        ) +
        facetGrid(y = GROUP, scales = "free_y")

I will investigate and fix the problem so that no exception will be thrown on similar code.

@paul-dingemans paul-dingemans added this to the 1.0.1 milestone Sep 30, 2023
paul-dingemans added a commit that referenced this issue Oct 2, 2023
…on reference as it results in a compilation error

Closes #2286
paul-dingemans added a commit that referenced this issue Oct 3, 2023
Prevent wrapping of nested multiline binary expression before operation reference as it results in a compilation error

Closes #2286
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants