Skip to content

Commit

Permalink
Format x.Member with get() as regular member binding. Fixes #1913. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf authored Jan 8, 2022
1 parent 6edcf90 commit c496ae1
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 35 deletions.
39 changes: 39 additions & 0 deletions src/Fantomas.Tests/ClassTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,3 +1018,42 @@ type C() =
member _.Run() = 1
"""

[<Test>]
let ``static member with get unit should be formatted the same as without, 1913`` () =
formatSourceString
false
"""
type Subject<'a> private () =
/// Represents and object that is both an observable sequence as well as an observer.
/// Each notification is broadcasted to all subscribed observers.
static member broadcast
with get () = new System.Reactive.Subjects.Subject<'a> ()
type Subject<'a> private () =
/// Represents and object that is both an observable sequence as well as an observer.
/// Each notification is broadcasted to all subscribed observers.
static member broadcast = new System.Reactive.Subjects.Subject<'a>()
"""
config
|> prepend newline
|> should
equal
"""
type Subject<'a> private () =
/// Represents and object that is both an observable sequence as well as an observer.
/// Each notification is broadcasted to all subscribed observers.
static member broadcast =
new System.Reactive.Subjects.Subject<'a>()
type Subject<'a> private () =
/// Represents and object that is both an observable sequence as well as an observer.
/// Each notification is broadcasted to all subscribed observers.
static member broadcast =
new System.Reactive.Subjects.Subject<'a>()
"""
79 changes: 50 additions & 29 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,8 @@ and genProperty astContext prefix ao propertyKind ps e =

and genPropertyWithGetSet astContext (b1, b2) rangeOfMember =
match b1, b2 with
| PropertyBinding (ats, px, ao, isInline, mf1, PatLongIdent (ao1, s1, ps1, _), e1),
PropertyBinding (_, _, _, _, _, PatLongIdent (ao2, _, ps2, _), e2) ->
| PropertyBinding (ats, px, ao, isInline, mf1, PatLongIdent (ao1, s1, ps1, _), e1, _),
PropertyBinding (_, _, _, _, _, PatLongIdent (ao2, _, ps2, _), e2, _) ->
let prefix =
genPreXmlDoc px
+> genAttributes astContext ats
Expand Down Expand Up @@ -750,7 +750,7 @@ and genMemberBindingList astContext node =

and genMemberBinding astContext b =
match b with
| PropertyBinding (ats, px, ao, isInline, mf, p, e) ->
| PropertyBinding (ats, px, ao, isInline, mf, p, e, synValInfo) ->
let prefix =
genPreXmlDoc px
+> genAttributes astContext ats
Expand All @@ -771,8 +771,17 @@ and genMemberBinding astContext b =
match ao, propertyKind, ps with
| None, "get ", [ _, PatParen PatUnitConst ] ->
// Provide short-hand notation `x.Member = ...` for `x.Member with get()` getters
prefix -- s
+> genExprSepEqPrependType astContext e
let pat =
match p with
| SynPat.LongIdent (lid, extraId, typarDecls, _, accessibility, range) ->
SynPat.LongIdent(lid, extraId, typarDecls, SynArgPats.Pats([]), accessibility, range)
| _ -> p

let prefix =
(onlyIfNot mf.IsInstance (!- "static ")
+> !- "member ")

genMemberBindingImpl astContext prefix ats px ao isInline pat e synValInfo
| _ ->
let ps = List.map snd ps

Expand All @@ -787,30 +796,7 @@ and genMemberBinding astContext b =
let prefix =
genMemberFlagsForMemberBinding astContext mf b.RangeOfBindingAndRhs

match e, p with
| TypedExpr (Typed, e, t), PatLongIdent (ao, s, ps, tpso) when (List.isNotEmpty ps) ->
genSynBindingFunctionWithReturnType
astContext
true
false
px
ats
prefix
ao
isInline
false
s
p.Range
ps
tpso
t
synValInfo
e
| e, PatLongIdent (ao, s, ps, tpso) when (List.isNotEmpty ps) ->
genSynBindingFunction astContext true false px ats prefix ao isInline false s p.Range ps tpso e
| TypedExpr (Typed, e, t), pat ->
genSynBindingValue astContext false px ats prefix ao isInline false pat (Some t) e
| _, pat -> genSynBindingValue astContext false px ats prefix ao isInline false pat None e
genMemberBindingImpl astContext prefix ats px ao isInline p e synValInfo

| ExplicitCtor (ats, px, ao, p, e, so) ->
let prefix =
Expand Down Expand Up @@ -850,6 +836,41 @@ and genMemberBinding astContext b =
| b -> failwithf "%O isn't a member binding" b
|> genTriviaFor (synBindingToFsAstType b) b.RangeOfBindingAndRhs

and genMemberBindingImpl
(astContext: ASTContext)
(prefix: Context -> Context)
(ats: SynAttributes)
(px: FSharp.Compiler.XmlDoc.PreXmlDoc)
(ao: SynAccess option)
(isInline: bool)
(p: SynPat)
(e: SynExpr)
(synValInfo: SynValInfo)
=
match e, p with
| TypedExpr (Typed, e, t), PatLongIdent (ao, s, ps, tpso) when (List.isNotEmpty ps) ->
genSynBindingFunctionWithReturnType
astContext
true
false
px
ats
prefix
ao
isInline
false
s
p.Range
ps
tpso
t
synValInfo
e
| e, PatLongIdent (ao, s, ps, tpso) when (List.isNotEmpty ps) ->
genSynBindingFunction astContext true false px ats prefix ao isInline false s p.Range ps tpso e
| TypedExpr (Typed, e, t), pat -> genSynBindingValue astContext false px ats prefix ao isInline false pat (Some t) e
| _, pat -> genSynBindingValue astContext false px ats prefix ao isInline false pat None e

and genMemberFlags astContext (mf: MemberFlags) =
match mf with
| MFMember _ -> !- "member "
Expand Down
14 changes: 12 additions & 2 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,18 @@ let (|DoBinding|LetBinding|MemberBinding|PropertyBinding|ExplicitCtor|) =
function
| SynBinding.Binding (ao, _, _, _, ats, px, SynValData (Some MFConstructor, _, ido), pat, _, expr, _, _) ->
ExplicitCtor(ats, px, ao, pat, expr, Option.map (|Ident|) ido)
| SynBinding.Binding (ao, _, isInline, _, ats, px, SynValData (Some (MFProperty _ as mf), _, _), pat, _, expr, _, _) ->
PropertyBinding(ats, px, ao, isInline, mf, pat, expr)
| SynBinding.Binding (ao,
_,
isInline,
_,
ats,
px,
SynValData (Some (MFProperty _ as mf), synValInfo, _),
pat,
_,
expr,
_,
_) -> PropertyBinding(ats, px, ao, isInline, mf, pat, expr, synValInfo)
| SynBinding.Binding (ao, _, isInline, _, ats, px, SynValData (Some mf, synValInfo, _), pat, _, expr, _, _) ->
MemberBinding(ats, px, ao, isInline, mf, pat, expr, synValInfo)
| SynBinding.Binding (_, DoBinding, _, _, ats, px, _, _, _, expr, _, _) -> DoBinding(ats, px, expr)
Expand Down
12 changes: 8 additions & 4 deletions src/Fantomas/SourceTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,18 @@ let rec (|SigValL|_|) =
/// Assume that PropertySet comes right after PropertyGet.
let (|PropertyWithGetSet|_|) =
function
| PropertyBinding (_, _, _, _, MFProperty PropertyGet, PatLongIdent (_, s1, _, _), _) as b1 :: bs ->
| PropertyBinding (_, _, _, _, MFProperty PropertyGet, PatLongIdent (_, s1, _, _), _, _) as b1 :: bs ->
match bs with
| PropertyBinding (_, _, _, _, MFProperty PropertySet, PatLongIdent (_, s2, _, _), _) as b2 :: bs when s1 = s2 ->
| PropertyBinding (_, _, _, _, MFProperty PropertySet, PatLongIdent (_, s2, _, _), _, _) as b2 :: bs when
s1 = s2
->
Some((b1, b2), bs)
| _ -> None
| PropertyBinding (_, _, _, _, MFProperty PropertySet, PatLongIdent (_, s2, _, _), _) as b2 :: bs ->
| PropertyBinding (_, _, _, _, MFProperty PropertySet, PatLongIdent (_, s2, _, _), _, _) as b2 :: bs ->
match bs with
| PropertyBinding (_, _, _, _, MFProperty PropertyGet, PatLongIdent (_, s1, _, _), _) as b1 :: bs when s1 = s2 ->
| PropertyBinding (_, _, _, _, MFProperty PropertyGet, PatLongIdent (_, s1, _, _), _, _) as b1 :: bs when
s1 = s2
->
Some((b1, b2), bs)
| _ -> None
| _ -> None
Expand Down

0 comments on commit c496ae1

Please sign in to comment.