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

Member with indexer that has a getter and setter doesn't use and correctly #2129

Closed
2 of 3 tasks
baronfel opened this issue Mar 6, 2022 · 2 comments · Fixed by #2140
Closed
2 of 3 tasks

Member with indexer that has a getter and setter doesn't use and correctly #2129

baronfel opened this issue Mar 6, 2022 · 2 comments · Fixed by #2140

Comments

@baronfel
Copy link
Contributor

baronfel commented Mar 6, 2022

Issue created from fantomas-online

Code

type TaskDefinition =
    abstract Item: name: string -> obj option with get, set

{ new TaskDefinition with
    member this.Item
        with get (name: string): obj option = None

    member this.Item
        with set (name: string) (v: obj option): unit =
            () }

Result

type TaskDefinition =
    abstract Item: name: string -> obj option with get, set

{ new TaskDefinition with
    member this.Item
        with set (name: string) (v: obj option): unit = ()
        with get (name: string): obj option = None }

Problem description

The problem here is that the with on the second property member (either getter or setter) needs to be an and if both getter and setter are provided.

type TaskDefinition =
    abstract Item: name: string -> obj option with get, set

{ new TaskDefinition with
    member this.Item
        with set (name: string) (v: obj option): unit = ()
        and get (name: string): obj option = None }

Note that if the source code isn't written in the separate-property-member syntax (see below) the format works.

{ new TaskDefinition with
    member this.Item
        with get (name: string): obj option = data.TryGet name

        and set (name: string) (v: obj option): unit =
            match v with
            | None -> data.Remove(name) |> ignore
            | Some v -> data.[name] <- v

    override this.``type``: string = "fakerun" }

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.

Options

Fantomas master branch at 2022-03-05T20:07:44Z - d7fb5cb

Default Fantomas configuration

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

@nojaf
Copy link
Contributor

nojaf commented Mar 7, 2022

Hi, this rings a bell. SynPat.LongIdent can have an propertyKeyword which tells you if get or set was used.

We combine both members into:

let (|PropertyWithGetSetMemberDefn|_|) =
function
| MDMember x1 :: MDMember x2 :: xs ->
match [ x1; x2 ] with
| PropertyWithGetSet ((x1, x2), []) -> Some((x1, x2), xs)
| _ -> None
| _ -> None

and then we probably don't do the right thing in

and genPropertyWithGetSet astContext (b1, b2) =
match b1, b2 with
| PropertyBinding (ats, px, ao, isInline, mf1, PatLongIdent (ao1, s1, pk1, ps1, _), eqR1, e1, _),
PropertyBinding (_, _, _, _, _, PatLongIdent (ao2, _, pk2, ps2, _), eqR2, e2, _) ->
let prefix =
genPreXmlDoc px
+> genAttributes astContext ats
+> genMemberFlags mf1
+> ifElse isInline (!- "inline ") sepNone
+> opt sepSpace ao genAccess
assert (ps1 |> Seq.map fst |> Seq.forall Option.isNone)
assert (ps2 |> Seq.map fst |> Seq.forall Option.isNone)
let ps1 = List.map snd ps1
let ps2 = List.map snd ps2
let genGet =
genProperty astContext (genPropertyKeyword pk1) ao1 "get " ps1 SynBinding_Equals eqR1 e1
let genSet =
genProperty astContext (genPropertyKeyword pk2) ao2 "set " ps2 SynBinding_Equals eqR2 e2
let genGetSet =
match pk2 with
| Some (PropertyKeyword.With _) -> genSet +> sepNln +> genGet
| _ -> genGet +> sepNln +> genSet
prefix
+> !-s1
+> indent
+> sepNln
+> genGetSet
+> unindent
| _ -> sepNone

anymore.

Are you interested in submitting a PR for this one?

@baronfel
Copy link
Contributor Author

baronfel commented Mar 8, 2022

Of course! I'll probably take a look this weekend.

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