Skip to content

Commit

Permalink
Support anon record expressions
Browse files Browse the repository at this point in the history
auduchinok committed Mar 23, 2019
1 parent a46b21b commit 7b52594
Showing 4 changed files with 60 additions and 3 deletions.
30 changes: 29 additions & 1 deletion src/Fantomas.Tests/RecordTests.fs
Original file line number Diff line number Diff line change
@@ -259,4 +259,32 @@ type MyExc =
{ inherit Exception(msg)
X = 1
Y = 2 }
"""
"""

[<Test>]
let ``anon record expression``() =
formatSourceString false """
let r =
{| Foo = 123
Bar = "" |}
""" config
|> prepend newline
|> should equal """
let r =
{| Foo = 123
Bar = "" |}
"""

[<Test>]
let `` anon record struct expression``() =
formatSourceString false """
let r =
struct {| Foo = 123
Bar = "" |}
""" config
|> prepend newline
|> should equal """
let r =
struct {| Foo = 123
Bar = "" |}
"""
14 changes: 14 additions & 0 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
@@ -473,6 +473,9 @@ and genVal astContext (Val(ats, px, ao, s, t, vi, _)) =
and genRecordFieldName astContext (RecordFieldName(s, eo)) =
opt sepNone eo (fun e -> !- s +> sepEq +> preserveBreakNlnOrAddSpace astContext e)

and genAnonRecordFieldName astContext (AnonRecordFieldName(s, e)) =
!- s +> sepEq +> preserveBreakNlnOrAddSpace astContext e

and genTuple astContext es =
atCurrentColumn (coli sepComma es (fun i ->
if i = 0 then genExpr astContext else noIndentBreakNln astContext
@@ -539,6 +542,17 @@ and genExpr astContext synExpr =
(fun (typ, expr) -> !- "inherit " +> genType astContext false typ +> genExpr astContext expr) +> recordExpr)
+> sepCloseS

| AnonRecord(isStruct, fields, copyInfo) ->
let recordExpr =
let fieldsExpr = col sepSemiNln fields (genAnonRecordFieldName astContext)
copyInfo |> Option.map (fun e ->
genExpr astContext e +> ifElseCtx (futureNlnCheck fieldsExpr) (!- " with" +> indent +> sepNln +> fieldsExpr +> unindent) (!- " with " +> fieldsExpr))
|> Option.defaultValue fieldsExpr
ifElse isStruct !- "struct " sepNone
+> sepOpenAnonRecd
+> atCurrentColumnIndent recordExpr
+> sepCloseAnonRecd

| ObjExpr(t, eio, bd, ims, range) ->
// Check the role of the second part of eio
let param = opt sepNone (Option.map fst eio) (genExpr astContext)
12 changes: 10 additions & 2 deletions src/Fantomas/Context.fs
Original file line number Diff line number Diff line change
@@ -295,14 +295,22 @@ let internal sepOpenAFixed = !- "[|"
/// closing token of list
let internal sepCloseAFixed = !- "|]"

/// opening token of sequence
/// opening token of sequence or record
let internal sepOpenS (ctx : Context) =
if ctx.Config.SpaceAroundDelimiter then str "{ " ctx else str "{" ctx

/// closing token of sequence
/// closing token of sequence or record
let internal sepCloseS (ctx : Context) =
if ctx.Config.SpaceAroundDelimiter then str " }" ctx else str "}" ctx

/// opening token of anon record
let internal sepOpenAnonRecd (ctx : Context) =
if ctx.Config.SpaceAroundDelimiter then str "{| " ctx else str "{|" ctx

/// closing token of anon record
let internal sepCloseAnonRecd (ctx : Context) =
if ctx.Config.SpaceAroundDelimiter then str " |}" ctx else str "|}" ctx

/// opening token of sequence
let internal sepOpenSFixed = !- "{"

7 changes: 7 additions & 0 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
@@ -808,6 +808,11 @@ let (|Record|_|) = function
Some(inheritOpt, xs, Option.map fst eo)
| _ -> None

let (|AnonRecord|_|) = function
| SynExpr.AnonRecd(isStruct, copyInfo, fields, _) ->
Some(isStruct, fields, Option.map fst copyInfo)
| _ -> None

let (|ObjExpr|_|) = function
| SynExpr.ObjExpr(t, eio, bd, ims, _, range) ->
Some (t, eio, bd, ims, range)
@@ -1207,6 +1212,8 @@ let (|Val|) (ValSpfn(ats, IdentOrKeyword(OpNameFull s), tds, t, vi, _, _, px, ao

let (|RecordFieldName|) ((LongIdentWithDots s, _) : RecordFieldName, eo : SynExpr option, _) = (s, eo)

let (|AnonRecordFieldName|) ((Ident s): Ident, e: SynExpr) = (s, e)

let (|PatRecordFieldName|) ((LongIdent s1, Ident s2), p) = (s1, s2, p)

let (|ValInfo|) (SynValInfo(aiss, ai)) = (aiss, ai)

0 comments on commit 7b52594

Please sign in to comment.