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

Delegate with many parameters result in a compilation error. #1514

Closed
3 tasks done
MNie opened this issue Mar 9, 2021 · 3 comments · Fixed by #2715
Closed
3 tasks done

Delegate with many parameters result in a compilation error. #1514

MNie opened this issue Mar 9, 2021 · 3 comments · Fixed by #2715

Comments

@MNie
Copy link

MNie commented Mar 9, 2021

Issue created from fantomas-online

Code

type SomeWin32Callback = delegate of (NastyWinApi32Type * int * int * int * NastyWinApi32Type * int * int * int * int * NastyWinApi32Type * int * int) -> bool

Result

type SomeWin32Callback = delegate of
    (NastyWinApi32Type * int * int * int * NastyWinApi32Type * int * int * int * int * NastyWinApi32Type * int * int) ->
    bool

Problem description

I want to create a WinApi32 type in my application because this type is a delegate that accepts 8 nasty WinApi32 parameters after Fantomas autosave autoformats generate not compilable code.

I assume that in such a scenario it shouldn't format it at all(?) or use some indentation in new lines.

like:

type SomeWin32Callback = delegate of (NastyWinApi32Type * int * int * int * NastyWinApi32Type * int * int * int * int * NastyWinApi32Type * int * int) -> bool

or

type SomeWin32Callback = delegate of 
                               (NastyWinApi32Type * int * int * int * NastyWinApi32Type * int * int * int * int * NastyWinApi32Type * int * int) -> 
                               bool

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.

If this is indeed an issue I would be glad to help fix it : )

Options

Fantomas version: 4.5.0-alpha-001
Master at 03/08/2021 19:16:36 - a2fd887

Default Fantomas configuration

@nojaf
Copy link
Contributor

nojaf commented Mar 9, 2021

Hello Michal, thank you for reporting this issue.
I would expect the output to be:

type SomeWin32Callback = 
    delegate of 
         NastyWinApi32Type *
         int *
         int *
         int *
         NastyWinApi32Type *
         int *
         int *
         int *
         int *
         NastyWinApi32Type *
         int *
         int
        -> bool

in this case.

To solve this, there are two parts.
The first is moving the delegate of to the next line when it crossed the max_line_length.

| ObjectModel (TCDelegate (FunType ts), _, _) ->
typeName
+> sepEq
+> sepSpace
+> !- "delegate of "
+> genTypeList astContext ts

Change this to:

    | ObjectModel (TCDelegate (FunType ts), _, _) ->
        let short =
            typeName
            +> sepEq
            +> sepSpace
            +> !- "delegate of "
            +> genTypeList astContext ts
        let long =
            typeName
            +> sepEq
            +> indent
            +> sepNln
            +> !- "delegate of "
            +> genTypeList astContext ts
            +> unindent
        expressionFitsOnRestOfLine short long

The next part is trickier, because of the long tupled definition I would also be splitted on separate lines.
We already do this when there are no parenthesis in genTypeList (example)

and genTypeList astContext node =
let gt (t, args: SynArgInfo list) =
match t, args with
| TTuple ts', _ ->
let hasBracket = not node.IsEmpty
let gt sepBefore =
if args.Length = ts'.Length then
col
sepBefore
(Seq.zip args (Seq.map snd ts'))
(fun ((ArgInfo (ats, so, isOpt)), t) ->
genOnelinerAttributes astContext ats
+> opt
sepColon
so
(if isOpt then
(sprintf "?%s" >> (!-))
else
(!-))
+> genType astContext hasBracket t)
else
col sepBefore ts' (snd >> genType astContext hasBracket)
let shortExpr = gt sepStar
let longExpr = gt (sepNln +> sepStarFixed)
expressionFitsOnRestOfLine shortExpr longExpr
| _, [ ArgInfo (ats, so, isOpt) ] ->
match t with
| TTuple _ -> not node.IsEmpty
| TFun _ -> true // Fun is grouped by brackets inside 'genType astContext true t'
| _ -> false
|> fun hasBracket ->
genOnelinerAttributes astContext ats
+> opt
sepColon
so
(if isOpt then
(sprintf "?%s" >> (!-))
else
(!-))
+> genType astContext hasBracket t
| _ -> genType astContext false t
let shortExpr = col sepArrow node gt
let longExpr =
indent
+> sepNln
+> col (sepArrow +> sepNln) node gt
+> unindent
expressionFitsOnRestOfLine shortExpr longExpr

Add something like:

        | TParen (TTuple ts'), _ ->
            !- "TODO: something clever"

Are you interested in submitting a PR?
If so please check out our Contribution Guidelines (and add a test to TypeDeclarationTests).

@MNie
Copy link
Author

MNie commented Mar 10, 2021

@nojaf thanks! I will take a look if I could prepare something : )

@nojaf
Copy link
Contributor

nojaf commented Mar 10, 2021

Thank you, feel free to ask questions you might have along the way.

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