Skip to content

Conversation

@KarolBajkowski
Copy link
Contributor

No description provided.

@nojaf nojaf linked an issue Nov 17, 2021 that may be closed by this pull request
Copy link
Contributor

@nojaf nojaf left a comment

Choose a reason for hiding this comment

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

Hello @KarolBajkowski, you are on the right track here.
Keep it up!

+> 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.

Copy link
Contributor

@nojaf nojaf left a comment

Choose a reason for hiding this comment

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

Hi Karol, don't be so hard on yourself.
This is a good first PR!
Fantomas is just one of those codebases where things can be delicate from time to time.

+> genExpr astContext e
+> unindent
+> kw WITH !+~ "with"
+> tokN mWithToLast WITH !+~ "with"
Copy link
Contributor

Choose a reason for hiding this comment

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

Close, but this still doesn't cover all cases:

[<Test>]
let ``nested try/with with comment on with`` () =
    formatSourceString
        false
        """
try
    a
with
| b ->
    try c
    // inner comment
    with
    | d -> ()
"""
        config
    |> prepend newline
    |> should
        equal
        """
try
    a
with
| b ->
    try
        c
    // inner comment
    with
    | d -> ()
"""

This will still fail, unfortunately. (online tool)

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 updated the code and test cases. Please take a look when you find some free time 🙏

@nojaf
Copy link
Contributor

nojaf commented Nov 18, 2021

@KarolBajkowski I think this is good to go.
I noticed one typo in a unit test name but I can change that myself.
Can we convert the draft to ready PR?

@KarolBajkowski
Copy link
Contributor Author

KarolBajkowski commented Nov 18, 2021

@KarolBajkowski I think this is good to go. I noticed one typo in a unit test name but I can change that myself. Can we convert the draft to ready PR?

Yes. I also thought about test naming convention, because I was not sure if the test names are readable. I'm use to Given When Then pattern so it's for me natural to first express all preconditions, then action (sometimes it's obvious so it can be omitted), and then expected outcome.

@KarolBajkowski KarolBajkowski marked this pull request as ready for review November 18, 2021 20:29
Copy link
Contributor

@nojaf nojaf left a comment

Choose a reason for hiding this comment

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

Many thanks, @KarolBajkowski for this first contribution!

@nojaf nojaf merged commit 38e1555 into fsprojects:master Nov 19, 2021
@KarolBajkowski KarolBajkowski deleted the fix/duplicated_trivia_-_nested_try_-_with_#1969 branch November 19, 2021 10:23
@KarolBajkowski
Copy link
Contributor Author

KarolBajkowski commented Nov 19, 2021

@nojaf I tried to give my best! I thank you for your patience and help :) That was remarkable experience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fantomas is unable to format valid F# (.net 6.0) program

2 participants