fsprojects / fantomas

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

FormatASTAsync loses single quotes for characters #3076

Closed ErikSchierboom closed 2 months ago

ErikSchierboom commented 2 months ago

I've been using FormatASTAsync to format my code, but I found out that it is removed the single quotes from characters.

let code = "let x = 'A'"
let tree, _ = parseFile false (SourceText.ofString code) []    
let formattedCode = CodeFormatter.FormatASTAsync(tree) |> Async.RunSynchronously

I've also tried:

let code = "let x = 'A'"
let [|(tree,_)|] = CodeFormatter.ParseAsync(false, code) |> Async.RunSynchronously
let formattedCode = CodeFormatter.FormatASTAsync(tree) |> Async.RunSynchronously

But that has the same issue.

I'm using:

ErikSchierboom commented 2 months ago

I've just tried reproducing it from within a test in Fantomas, but that does work 🤔 I'll do some more digging.

nojaf commented 2 months ago

Yeah, this is more or less to be expected. We don't seem to add the single quotes in https://github.com/fsprojects/fantomas/blob/4d5e5e26fbf4e0d3059bdc20453c01432c679070/src/Fantomas.Core/ASTTransformer.fs#L142

In practice, the value of SynConst.Char is quite unreliable, so Fantomas will normally reuse the char content based on the original source code. This is why this works in the test.

let formattedCode = CodeFormatter.FormatASTAsync(tree, code) |> Async.RunSynchronously probably would be another workaround.

I would accept a PR fix for this.

ErikSchierboom commented 2 months ago

Thanks!

formatSourceString "let s = 'A'" config
|> should equal "let s = 'A'\n"

works, but

formatAST false "let s = 'A'" config
|> should equal "let s = 'A'\n"

doesn't.

I'll see if I can figure it out :)

ErikSchierboom commented 2 months ago

I've opened a PR: #3077