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

Question: Custom computation expressions sometimes formatted incorrectly #315

Closed
zakaluka opened this issue Sep 30, 2018 · 5 comments
Closed

Comments

@zakaluka
Copy link
Contributor

zakaluka commented Sep 30, 2018

Hello,

I am trying the latest Fantomas on the default SAFE stack template, using Saturn. For the most part, it is formatting the code well. However, Saturn uses a number of custom computation expressions, and Fantomas is behaving very oddly.

I am seeing 2 issues.

First question has to do with how the following code block is reformatted. By default, Server.fs contains the following block of code:

let webApp = router {
    get "/api/init" (fun next ctx ->
        task {
            let! counter = getInitCounter()
            return! Successful.OK counter next ctx
        })
}

I ran the file through the Fantomas command-line utility (no options), and it changed to the following:

let webApp =
    router
        {
        get "/api/init"
            (fun next ctx -> task { let! counter = getInitCounter()
                                    return! Successful.OK counter next ctx }) }

While I understand some of the behavior, I don't understand why router and { are on separate lines. From looking at the computation expression tests https://github.com/fsprojects/fantomas/blob/master/src/Fantomas.Tests/ComputationExpressionTests.fs, it should have looked like router {.

On a positive note, it didn't indent the get call any further.

PLEASE SEE #339 FOR MORE INFORMATION ABOUT THE FOLLOWING ISSUE.
Second question is about when I format through the Fantomas library and FAKE. I am seeing the following error message when I try to run the Server.fs file through checkCode.

D:\projects\ZenCase\src\Client\Client.fs:
Unable to cast object of type 'YieldOrReturn' to type 'YieldOrReturnFrom'.

D:\projects\ZenCase\src\Server\Server.fs:
Unable to cast object of type 'YieldOrReturn' to type 'YieldOrReturnFrom'.

The following files aren't formatted properly:
- D:\projects\ZenCase\src\Client\AssemblyInfo.fs
- D:\projects\ZenCase\src\Client\Client.fs !
- D:\projects\ZenCase\src\Migration\AssemblyInfo.fs
- D:\projects\ZenCase\src\Migration\Constants.fs
- D:\projects\ZenCase\src\Migration\Migration.fs
- D:\projects\ZenCase\src\Server\AssemblyInfo.fs
- D:\projects\ZenCase\src\Server\Server.fs !
- D:\projects\ZenCase\src\Shared\Shared.fs
- D:\projects\ZenCase\src\Shared\Utility.fs)

If I comment out all the computation expressions in Server.fs, then that error goes away. However, any computation express in Server.fs causes the error to be printed out. Because of this, I'm concerned about running Server.fs through formatCode.

I even tried leaving only one computation expression Server.fs:

let getInitCounter() : Task<Counter> = task { return 42 }

Based on what I saw in Fantomas, this is a YieldOrReturn. I still get the same error message. Why is Fantomas trying to change this to YieldOrReturnFrom (aka return!)?

@jindraivanek
Copy link
Contributor

  1. I can confirm this, @zakaluka please create seperate issue with this snippet. It doesn't happen for each CE, my guess is it is connected to multiline expr as first thing in CE.

  2. Also confirmed. It can be reproduced wtih this FAKE5 script:

#r "paket: nuget Fantomas"
#load ".fake/test-FAKE5.fsx/intellisense.fsx"

let mkTempFile source =
    let fileName = System.IO.Path.GetTempFileName() + ".fs"
    System.IO.File.WriteAllText(fileName, source)
    fileName

let source = "let getInitCounter() : Task<Counter> = task { return 42 }"

let path = mkTempFile source

Fantomas.CodeFormatter.FormatDocument(path, System.IO.File.ReadAllText(path), Fantomas.FormatConfig.FormatConfig.Default)

System.IO.File.Delete path

It's weird because with CLI this code will be formatted without problem.

@jindraivanek
Copy link
Contributor

While working on http://ratatosk.dynu.net/fantomas/, I encounter second issue. Turns out it is caused by different versions of FSharp.Compiler.Service. Fantomas use 23.0.3, but when you use Fantomas as lib dependency, newer one is used (25.0.1) and it cause these issues.

Workaround is to use matching version of FSharp.Compiler.Service, this header of above script works:

#r "paket: nuget Fantomas
nuget FSharp.Compiler.Service 23.0.3"

Another option is to use

#r "paket: strategy: min 
nuget Fantomas"

I think we have two options how to fix this:

  1. upgrade FSharp.Compiler.Service to 25.0.1. That will force everyone who is using Fantomas as lib to also upgrade. Not sure if that is OK.
  2. change FSharp.Compiler.Service dependency in nuget to be exactly 23.0.3 (now is >=23.0.3). That would probably needs to change way of how we are creating nuget package, I wasn't able to find a way how to do it by dotnet pack parameter. It should be doable with paket pack.

I would prefer option 1.

@zakaluka
Copy link
Contributor Author

I have created a separate issue #339 to deal with the second issue presented above (YieldOrReturn to YieldOrReturnFrom).

@zakaluka zakaluka changed the title Question: Custom computation expressions? Testing on default SAFE stack template Question: Custom computation expressions sometimes formatted incorrectly Oct 24, 2018
@nojaf
Copy link
Contributor

nojaf commented Aug 14, 2020

I think this is no longer an issue (see example).
Please open a new issue if this is not the case.

@nojaf nojaf closed this as completed Aug 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants