fantomas icon indicating copy to clipboard operation
fantomas copied to clipboard

`fsharp_newline_before_multiline_computation_expression = false` may cause parse error if CE is called from an expression

Open Shuenhoy opened this issue 10 months ago • 4 comments

Issue created from fantomas-online

Code


let a = Builder.build ("a long enough str") {
    let a = 1
    return a
}

Result

let a = Builder.build (
    "a long enough str"
) {
    let a = 1
    return a
}

Problem description

Please describe here the Fantomas problem you encountered. Check out our Contribution Guidelines.

A more complete code that can compile:

module Test.Program

type Builder() =
    member __.Return x = x

    static member build(str) =
        Builder()

let a =
    Builder.build (
        "a long enough str"
    ) {
        let a = 1
        return a
    }

The result formatted will fail to parse.

Extra information

  • [x] The formatted result breaks my code.
  • [ ] The formatted result gives compiler warnings.
  • [ ] I or my company would be willing to help fix this.
  • [ ] I would like a release if this problem is solved.

Options

Fantomas main branch at 2025-02-28T11:18:04Z - 6108fc41cf9ff49c9bd0f0059fc6b5fd2bc7974d

    { config with
                MaxLineLength = 30
                NewlineBeforeMultilineComputationExpression = false }

Did you know that you can ignore files when formatting by using a .fantomasignore file? PS: It's unlikely that someone else will solve your specific issue, as it's something that you have a personal stake in.

Shuenhoy avatar Mar 03 '25 07:03 Shuenhoy

Hello, thanks for opening this issue. What are you expectations here? Would you like valid code but potentially not consistent in style?

nojaf avatar Mar 03 '25 08:03 nojaf

I think valid code is better than style consistency. In fact, I am not aware of an easy way to conform the style here.

// fallback to `fsharp_newline_before_multiline_computation_expression = true`. It looks OK and at least compiles.
let a = 
    Builder.build ( 
            "a long enough str" 
    ) {
        let a = 1
        return a
    }

// a possible form without newline before CE, but it looks also not consistent in style and seems worse than the first form.
let a = Builder.build ( 
                "a long enough str" 
        ) {
            let a = 1
            return a
        }

Shuenhoy avatar Mar 03 '25 08:03 Shuenhoy

Perhaps we should change this rule a bit and only never leave the computation expression on the same line if it has a large identifier expression. Thoughts @josh-degraw @dawedawe?

nojaf avatar Mar 03 '25 09:03 nojaf

Will look into this next week.

dawedawe avatar Mar 07 '25 08:03 dawedawe