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

SemicolonAtEndOfLine causes syntax error #1342

Closed
2 of 3 tasks
lydell opened this issue Dec 28, 2020 · 6 comments
Closed
2 of 3 tasks

SemicolonAtEndOfLine causes syntax error #1342

lydell opened this issue Dec 28, 2020 · 6 comments

Comments

@lydell
Copy link

lydell commented Dec 28, 2020

Issue created from fantomas-online

Code

let f =
  a
  |> should equal bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  c |> should equal d

Error

Fantomas was able to format the code but the result appears to be invalid F# code.
Please open an issue.

Formatted result:

let f =
    a
    |> should equal bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    ;
    c |> should equal d

Problem description

Workaround: Add a blank line between the two statements – then Fantomas won’t add any semicolons at all.

I found this when upgrading from Fantomas 4.0 to 4.3 at work.

Extra information

  • The formatted result breaks by code.
  • The formatted result gives compiler warnings.
  • I or my company would be willing to help fix this.

The reason we use SemicolonAtEndOfLine = true is because we love it in lists and records, but we don’t care about semicolons at the end of statements.

Options

Fantomas Master at 12/26/2020 15:00:23 - 76fa31e

    { config with
                SemicolonAtEndOfLine = true }

Did you know that you can ignore files when formatting from fantomas-tool or the FAKE targets by using a .fantomasignore file?

@lydell
Copy link
Author

lydell commented Dec 29, 2020

Here’s another case. This time, the “blank line” workaround does not help :(

Issue created from fantomas-online

Code

module ViewBuilder =
    let rec private buildNode (isHtml : bool) (sb : StringBuilder) (node : XmlNode) : unit =
        let buildElement closingBracket (elemName, attributes : XmlAttribute array) =
            match attributes with
            | [||] -> do sb += "<" += elemName +! closingBracket
            | _ ->
                do sb += "<" +! elemName

                attributes
                |> Array.iter
                    (fun attr ->
                        match attr with
                        | KeyValue (k, v) -> do sb += " " += k += "=\"" += v +! "\""
                        | Boolean k -> do sb += " " +! k)

                do sb +! closingBracket

        let inline buildParentNode
            (elemName, attributes : XmlAttribute array)
            (nodes : XmlNode list)
            =
            do buildElement ">" (elemName, attributes)

            for node in nodes do
                buildNode isHtml sb node

            do sb += "</" += elemName +! ">"

        match node with
        | Text text -> do sb +! text
        | ParentNode (e, nodes) -> do buildParentNode e nodes
        | VoidElement e -> do buildElement (selfClosingBracket isHtml) e

Error

Fantomas was able to format the code but the result appears to be invalid F# code.
Please open an issue.

Formatted result:

module ViewBuilder =
    let rec private buildNode (isHtml: bool) (sb: StringBuilder) (node: XmlNode): unit =
        let buildElement closingBracket (elemName, attributes: XmlAttribute array) =
            match attributes with
            | [||] -> do sb += "<" += elemName +! closingBracket
            | _ ->
                do sb += "<" +! elemName

                attributes
                |> Array.iter
                    (fun attr ->
                        match attr with
                        | KeyValue (k, v) -> do sb += " " += k += "=\"" += v +! "\""
                        | Boolean k -> do sb += " " +! k)
                ;
                do sb +! closingBracket

        let inline buildParentNode (elemName, attributes: XmlAttribute array) (nodes: XmlNode list) =
            do buildElement ">" (elemName, attributes)

            for node in nodes do
                buildNode isHtml sb node
            ;
            do sb += "</" += elemName +! ">"

        match node with
        | Text text -> do sb +! text
        | ParentNode (e, nodes) -> do buildParentNode e nodes
        | VoidElement e -> do buildElement (selfClosingBracket isHtml) e

Options

Fantomas Master at 12/26/2020 15:00:23 - 76fa31e

    { config with
                SemicolonAtEndOfLine = true }

Workaround

I finally came up with this workaround:

        let buildElement closingBracket (elemName, attributes : XmlAttribute array) =
            match attributes with
            | [||] -> do sb += "<" += elemName +! closingBracket
            | _ ->
                do sb += "<" +! elemName

                let fantomasWorkaround =
                    function
                    | KeyValue (k, v) -> do sb += " " += k += "=\"" += v +! "\""
                    | Boolean k -> do sb += " " +! k

                Array.iter fantomasWorkaround attributes
                do sb +! closingBracket

        let inline buildParentNode
            (elemName, attributes : XmlAttribute array)
            (nodes : XmlNode list)
            =
            do buildElement ">" (elemName, attributes)

            let fantomasWorkaround () =
                for node in nodes do
                    buildNode isHtml sb node

            fantomasWorkaround ()
            do sb += "</" += elemName +! ">"

@nojaf
Copy link
Contributor

nojaf commented Jan 8, 2021

Hey @lydell, thank you for reporting this issue. I'm afraid I don't have a lot of incentive this look into this.
SemicolonAtEndOfLine has always been a strange setting as I have not encountered any F# codebase in the wild that does use this (regardless of using Fantomas).

Perhaps we should sunset this feature in the next major and replace it with something that better covers your need.

@lydell
Copy link
Author

lydell commented Jan 8, 2021

@nojaf There is an easier solution!

SemicolonAtEndOfLine is super helpful (our favorite option at work, actually!) in records and lists, but helps nothing when used between statements. And the bug only occurs between statements – in records and lists it’s perfect.

So I suggest making SemicolonAtEndOfLine only apply to records and lists – see also #1161

I could try making a PR that solves both issues at the same time in the upcoming months.

@nojaf
Copy link
Contributor

nojaf commented Jan 8, 2021

So I suggest making SemicolonAtEndOfLine only apply to records and lists

That would change the overall behavior of the current setting, this is something we cannot do at any given point in time.
A breaking change requires a major version.
Personally, I'd prefer the remove the old setting completely first and then consider #1161.

@lydell
Copy link
Author

lydell commented Feb 13, 2022

It’s been over a year, and I still haven’t made a PR. At work we are going away from using this option now. So I’m leaning more towards removing this now:

  1. Deprecating it and warning in the docs that it’s very buggy
  2. Delete it

@lydell
Copy link
Author

lydell commented May 21, 2022

This option was deprecated in #2250.

@lydell lydell closed this as completed May 21, 2022
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

2 participants