fsprojects / fantomas

FSharp source code formatter
https://fsprojects.github.io/fantomas
Other
772 stars 194 forks source link

`in` is removed from binding when PreserveEndOfLine is true #340

Closed auduchinok closed 3 years ago

auduchinok commented 5 years ago
let x = 123 in ()

is being formatted to

let x = 123()
nojaf commented 5 years ago

Related:

let f () = 
  let x = 1 in   // the "in" keyword is available in F#
    let y = 2 in 
      x + y

gets formatted to

let f() =
    let x = 1
     // the "in" keyword is available in F#
     let y = 2
    x + y

Code is still valid, but the in keyword is lost.

jindraivanek commented 5 years ago

@nojaf I think removing in on EOL is fine because it is just unnecessary.

However this snippet shows other bug(s) related to comment

with comment

without comment

nojaf commented 5 years ago

Ok, good to know that the comment caused the bad indent. Something is going wrong in TokenMatcher.

When PreserveEndOfLine is true the comment is on the correct line.

let f() =
  let x = 1  // the "in" keyword is available in F#
    let y = 2
      x + y

Indentation is not correct though.

yuriyostapenko commented 5 years ago

This doesn't seem to be fixed. At least for me in is being removed by 2.9.2.0. Sometimes that in can indeed be omitted, other times it is actually required. For example, given original

let x = List.singleton <|
        let item = "text" in
        item

if it is processed with --preserveEOL, it will strip in, but the code is at least still valid:

let x = List.singleton <|
        let item = "text"
        item

however, without preserve the output is invalid F# (and subsequent fantomas runs will throw when parsing):

let x =
    List.singleton <| let item = "text"
                      item

The compiler error is FS0010 Unexpected identifier in expression. Expected 'in' or other token.