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

Problem Merging multiple compiler directives code #2068

Closed
Rajivhost opened this issue Feb 7, 2022 · 1 comment · Fixed by #2083
Closed

Problem Merging multiple compiler directives code #2068

Rajivhost opened this issue Feb 7, 2022 · 1 comment · Fixed by #2083
Labels
area-trivia bug (soundness) good first issue Long hanging fruit: easy issue to get your feet wet!

Comments

@Rajivhost
Copy link

Issue created from fantomas-online

Code

let Ok (content: string) =
#if API_GATEWAY || MADAPI
    APIGatewayHttpApiV2ProxyResponse(
        StatusCode = int HttpStatusCode.OK,
        Body = content,
    #if API_GATEWAY
        Headers = Map.empty.Add("Content-Type", "text/plain")
    #else
        Headers = Map.empty.Add("Content-Type", "application/json")
#endif
    )
#else
    ApplicationLoadBalancerResponse(
        StatusCode = int HttpStatusCode.OK,
        Body = content,
        Headers = Map.empty.Add("Content-Type", "text/plain")
    )
#endif

Problem description

We got this error:

System.Exception: Fantomas is trying to format the input multiple times due to the detect of multiple defines.
There is a problem with merging all the code back together.
[API_GATEWAY, MADAPI] has 21 fragments
[] has 22 fragments
[API_GATEWAY] has 21 fragments
[MADAPI] has 20 fragments
Please raise an issue at https://fsprojects.github.io/fantomas-tools/#/fantomas/preview.
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1439.Invoke(String message) in D:\a_work\1\s\src\fsharp\FSharp.Core\printf.fs:line 1439
at Fantomas.CodeFormatterImpl.format@410-3.Invoke(FSharpList1 _arg2) in /home/runner/work/fantomas-tools/fantomas-tools/.deps/fantomas/src/Fantomas/CodeFormatterImpl.fs:line 436 at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvokeNoHijackCheck[a,b](AsyncActivation1 ctxt, b result1, FSharpFunc2 userCode) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 465 at Fantomas.Async.map@167-2.Invoke(AsyncActivation1 ctxt) in /home/runner/work/fantomas-tools/fantomas-tools/.deps/fantomas/src/Fantomas/Utils.fs:line 167
at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in D:\a_work\1\s\src\fsharp\FSharp.Core\async.fs:line 105

@nojaf
Copy link
Contributor

nojaf commented Feb 7, 2022

Hello @Rajivhost, thank you for reporting this issue.

I was able to reproduce the problem using code comments.

This is a trivia issue, we don't print the comment (or in your case the #if) in

let genExpr astContext e =
match e with
| InfixApp (equal, operatorExpr, e1, e2) when (equal = "=") ->
genNamedArgumentExpr astContext operatorExpr e1 e2
| _ -> genExpr astContext e

To do this, we would need to extend the InfixApp active pattern with the range of the outer SynExpr.App in

let (|InfixApp|_|) synExpr =
match synExpr with
| SynExpr.App (_, true, (Var "::" as e), Tuple ([ e1; e2 ], _), _) -> Some("::", e, e1, e2)
| SynExpr.App (_, _, SynExpr.App (_, true, (Var s as e), e1, _), e2, _) -> Some(s, e, e1, e2)
| _ -> None

Once this has been added, in CodePrinter you can to do something like:

     | InfixApp (equal, operatorExpr, e1, e2, range) when (equal = "=") -> 
         genNamedArgumentExpr astContext operatorExpr e1 e2 
         |> genTriviaFor SynExpr_App range

Are you interested in submitting a PR for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-trivia bug (soundness) good first issue Long hanging fruit: easy issue to get your feet wet!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants