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

Multiline type parameter arguments inside indentation #1611

Closed
2 of 3 tasks
piaste opened this issue Apr 6, 2021 · 2 comments · Fixed by #1636
Closed
2 of 3 tasks

Multiline type parameter arguments inside indentation #1611

piaste opened this issue Apr 6, 2021 · 2 comments · Fixed by #1636

Comments

@piaste
Copy link
Contributor

piaste commented Apr 6, 2021

Issue created from fantomas-online

Code

module PoorlyIndented = 

 let findThing dependency thingId = 
  use cmd = 
   query SomeDatabase.CreateCommand<"
                    select name
                    from things
                    where id = :id
   "> dependency

  cmd.AsyncExecute(id = thingId)

Result

module PoorlyIndented =

    let findThing dependency thingId =
        use cmd =
            query
                SomeDatabase.CreateCommand<"
                    select name
                    from things
                    where id = :id
   ">
                dependency

        cmd.AsyncExecute(id = thingId)

Problem description

This one is tricky and very, very niche. The sample code above is how we often write one-off queries in our functions. The query function is a helper that lets us pass type-safe database connection and/or transactions instead of raw strings, and the first argument is the type-provider-generated command.

Because the argument has a multi-line string literal as a type parameter, the angle brackets need to end within the indentation rules for the containing declaration, or the F# compiler gets confused and doesn't compile anymore.

So now let's say the whole code tree is insufficiently indented (this actually happened). After Fantomas applies the wider indentation, the indentation requirement for the parameter increases, and the code breaks.

When we edit this code manually, we add the right amount of whitespace at the end of the query string, since placing the entire "> in the right place looks better. Fantomas, of course, should never change the content of a string literal, so what it should do is add space between the " and the >, like this:

module PoorlyIndented =

    let findThing dependency thingId =
        use cmd =
            query
                SomeDatabase.CreateCommand<"
                    select name
                    from things
                    where id = :id
   "            >
                dependency

        cmd.AsyncExecute(id = thingId)

which is ugly but will satisfy the compiler and won't change the code semantics.

Extra information

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

Options

Fantomas Master at 04/05/2021 16:09:34 - 31922c0

Default Fantomas configuration

@nojaf
Copy link
Contributor

nojaf commented Apr 6, 2021

Hello @piaste, thanks for reporting this issue!
This is quite the challenge at first glance.
I believe the function indentIfNeeded can be used to get around this problem.

let internal indentIfNeeded f (ctx: Context) =

Add it to genGenericTypeParameters

and genGenericTypeParameters astContext ts =
match ts with
| [] -> sepNone
| ts ->
!- "<"
+> coli
sepComma
ts
(fun idx ->
genType
{ astContext with
IsFirstTypeParam = idx = 0 }
false)
-- ">"

so it becomes something like:

        !- "<"
        +> coli
            sepComma
            ts
            (fun idx ->
                genType
                    { astContext with
                          IsFirstTypeParam = idx = 0 }
                    false)
        +> indentIfNeeded sepNone
        -- ">"

the closing > won't really align with anything, but it will be indented far enough to make it compile.

Are you interested in submitting a PR for this?

@piaste
Copy link
Contributor Author

piaste commented Apr 6, 2021

Are you interested in submitting a PR for this?

Yes, that should be enough guidance to get me started, thank you 🙂 I'll take a crack at it this weekend.

nojaf added a commit that referenced this issue Apr 13, 2021
* added failing test

* All tests pass

* Indent by one level instead of by 1 space

* Formatted code

* Trim added trailing whitespace

* Format

* Remove usage of indentIfNeeded in genApp.

Co-authored-by: Stefano Pian <stefano.pian@piaste.com>
Co-authored-by: nojaf <florian.verdonck@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants