Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/Fantomas.Tests/CompilerDirectivesTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2659,3 +2659,58 @@ let ``indented #if directive inside another non-indented #if directive should fo
#endif
#endif
"""

[<Test>]
let ``double try-with, inner #if directive should not throw error, 1969`` () =
let correctlyFormatedSrc =
"""
try
try
()
#if FOO
()
#endif
with
| _ -> ()
with
| _ -> ()
"""

formatSourceString
false
correctlyFormatedSrc
config
|> prepend newline
|> should
equal
correctlyFormatedSrc

[<Test>]
let ``(copy) double try-with, inner #if directive should not throw error, 1969`` () =
// copied from TriviaTests.fs - here it works... No reason why...
formatSourceString
false
"""
try
try
()
// xxx
with
| _ -> ()
with
| _ -> ()
"""
config
|> prepend newline
|> should
equal
"""
try
try
()
// xxx
with
| _ -> ()
with
| _ -> ()
"""
31 changes: 31 additions & 0 deletions src/Fantomas.Tests/TriviaTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open NUnit.Framework
open Fantomas
open Fantomas.Tests.TestHelper
open Fantomas.TriviaTypes
open FsUnit

let private collectTrivia =
Trivia.collectTrivia
Expand Down Expand Up @@ -541,3 +542,33 @@ let x =
| [ { Type = TriviaNodeType.MainNode SynConst_Unit
ContentBefore = [ Directive "#if DEBUG\n\n#endif" ] } ] -> pass ()
| _ -> Assert.Fail(sprintf "Unexpected trivia: %A" trivia)

[<Test>]
let ``double try-with, comment before inner 'with' not duplicated, 1969`` () =
// This test fails because of [Expected: "\r\ntr" But was: "\ntry\n"] at start position of the string
formatSourceString
false
"""
try
try
()
// xxx
with
| _ -> ()
with
| _ -> ()
"""
config
|> prepend newline
|> should
equal
"""
try
try
()
// xxx
with
| _ -> ()
with
| _ -> ()
"""
8 changes: 7 additions & 1 deletion src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2030,7 +2030,13 @@ and genExpr astContext synExpr ctx =
+> sepNln
+> genExpr astContext e
+> unindent
+> kw WITH !+~ "with"
+> (fun ctx ->
let lookupRange =
ctx.MkRangeWith
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is a bit too vague I'm afraid.
It will fail if the with keyword is higher up:

[<Test>]
let ``comment is still lost`` () =
    formatSourceString
        false
        """
try
    a
// comment
with


| b -> c
"""
        config
    |> prepend newline
    |> should
        equal
        """
try
    a
// comment
with


| b -> c
"""

I would add mWithToLast to the active pattern:
(parser source)

let (|TryWith|_|) =
    function
    | SynExpr.TryWith (e, _, cs, mWithToLast, _, _, _) -> Some(e, mWithToLast, cs)
    | _ -> None

and extract the with range as:

| TryWith (e, mWithToLast, cs) ->
 ....
                    let lookupRange =
                        ctx.MkRangeWith
                            (mWithToLast.StartLine, mWithToLast.StartColumn)
                            (mWithToLast.StartLine, mWithToLast.StartColumn + 4)

Copy link
Contributor Author

@KarolBajkowski KarolBajkowski Nov 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the code with your suggestion. Thank you for your help :) I hope that will work now, even though it's probably my worst PR in my life :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to miss your suggested code :/ I'm wondering why this code works even with +3 like (mWithToLast.StartLine, mWithToLast.StartColumn + 3)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, well that might be an offset by 1 error on the token side.
The trivia node that has the comment is going from 3,0 - 3,3

image

mWithToLast shall in this case span from 3,0--6,8.
tokN will try and look within lookupRange whether the WITH token exists.
Inclusively, so that is why it is dangerous to look in a range that is too long.
I took + 4 because the with keyword is 4 characters long.

Once dotnet/fsharp#12400 is merged, we can look for that exact range (via ASTTransformer) and use range contains. Don't worry about this last bit, that is something for in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explanation! It really helps. But I must admit for me it was too much rush. I have to slowly finish fantomas youtube videos and look again at the source code and assembly all those puzzles together. I think I intuitively understand what's going on, but I need better understanding... TBH this is my first contact with compiler source code especially in F# (which I think basics I know very well but still I'm wrapping my head around some F# features/patterns which are not common in OOP)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it took me a lot of time to understand this project when I first started out.
That is why I made these videos, to speed up this process for newcomers.
But I'm well aware not everything immediately clicks. Especially all those custom operators.
At first you sorta conceptually understand what they do, and later you really start understanding the events they add to the context.
I'm in the same boot that before this project, I never saw a compiler up close.
That was also a very overwhelming brave new world, but with all things, eventually, you get the hang of it.

Thanks again for all your patience and for engaging in conversation.

(synExpr.Range.EndLine - 1, 0)
(synExpr.Range.EndLine, synExpr.Range.EndColumn)

tokN lookupRange WITH (!+~ "with") ctx)
+> indentOnWith
+> sepNln
+> col sepNln cs (genClause astContext true)
Expand Down