Skip to content

Commit

Permalink
Print trivia of TypeDefnSig using FullRange extension. Fixes fsprojec…
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed Apr 1, 2021
1 parent 82615ce commit 61ef1ed
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 15 deletions.
57 changes: 57 additions & 0 deletions src/Fantomas.Tests/SignatureTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1325,3 +1325,60 @@ type 'a Bar =
///
| Quux
"""

[<Test>]
let ``comment between recursive type, 1562`` () =
formatSourceString
true
"""
namespace Baz
type Foo = | Foo of int
///
and [<RequireQualifiedAccess>] Bar<'a> =
| Bar of int
"""
config
|> prepend newline
|> should
equal
"""
namespace Baz
type Foo = Foo of int
///
and [<RequireQualifiedAccess>] Bar<'a> = Bar of int
"""

[<Test>]
let ``comments between multiple recursive types`` () =
formatSourceString
true
"""
namespace Baz
type Foo = | Foo of int
/// barry
and Bar = | Bar of string
/// mehhy
and Meh = | Meh of DateTime
"""
config
|> prepend newline
|> should
equal
"""
namespace Baz
type Foo = Foo of int
/// barry
and Bar = Bar of string
/// mehhy
and Meh = Meh of DateTime
"""
11 changes: 11 additions & 0 deletions src/Fantomas/AstExtensions.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Fantomas.AstExtensions

open FSharp.Compiler.SyntaxTree
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Range

type SynTypeDefnSig with
/// Combines the range of type name and the body.
member this.FullRange : Range =
match this with
| SynTypeDefnSig.TypeDefnSig (comp, _, _, r) -> mkRange r.FileName comp.Range.Start r.End
4 changes: 3 additions & 1 deletion src/Fantomas/AstTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Fantomas.AstTransformer
open FSharp.Compiler.Text
open FSharp.Compiler.SyntaxTree
open Fantomas.TriviaTypes
open Fantomas.AstExtensions
open Fantomas

type Id = { Ident: string; Range: Range }
Expand Down Expand Up @@ -645,7 +646,8 @@ module private Ast =
and visitSynTypeDefnSig (typeDefSig: SynTypeDefnSig) : TriviaNodeAssigner list =
match typeDefSig with
| TypeDefnSig (sci, synTypeDefnSigReprs, memberSig, _) ->
[ yield! visitSynComponentInfo sci
[ yield mkNode TypeDefnSig_ typeDefSig.FullRange
yield! visitSynComponentInfo sci
yield! visitSynTypeDefnSigRepr synTypeDefnSigReprs
yield! (memberSig |> List.collect visitSynMemberSig) ]

Expand Down
34 changes: 31 additions & 3 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ open Fantomas.SourceTransformer
open Fantomas.Context
open Fantomas.TriviaTypes
open Fantomas.TriviaContext
open Fantomas.AstExtensions

/// This type consists of contextual information which is important for formatting
type ASTContext =
Expand Down Expand Up @@ -454,8 +455,24 @@ and genSigModuleDecl astContext node =
| SigOpen (s) -> !-(sprintf "open %s" s)
| SigOpenType (s) -> !-(sprintf "open type %s" s)
| SigTypes (t :: ts) ->
let sepTs =
match List.tryHead ts with
| Some t ->
let attributeRanges =
getRangesFromAttributesFromSynTypeDefnSig t

sepNln
+> sepNlnConsideringTriviaContentBeforeWithAttributesFor TypeDefnSig_ t.FullRange attributeRanges
| None -> rep 2 sepNln

genSigTypeDefn { astContext with IsFirstChild = true } t
+> colPre (rep 2 sepNln) (rep 2 sepNln) ts (genSigTypeDefn { astContext with IsFirstChild = false })
+> colPreEx
sepTs
(fun (ty: SynTypeDefnSig) ->
sepNln
+> sepNlnConsideringTriviaContentBeforeForMainNode TypeDefnSig_ ty.FullRange)
ts
(genSigTypeDefn { astContext with IsFirstChild = false })
| md -> failwithf "Unexpected module signature declaration: %O" md
|> (match node with
| SynModuleSigDecl.Types _ -> genTriviaFor SynModuleSigDecl_Types node.Range
Expand Down Expand Up @@ -3691,13 +3708,23 @@ and sepNlnBetweenSigTypeAndMembers (synTypeDefnRepr: SynTypeDefnSigRepr) (ms: Sy
sepNlnTypeAndMembers synTypeDefnRepr.Range.End range mainNodeType
| None -> sepNone

and genSigTypeDefn astContext (SigTypeDef (ats, px, ao, tds, tcs, tdr, ms, s, preferPostfix)) =
and genSigTypeDefn astContext (SigTypeDef (ats, px, ao, tds, tcs, tdr, ms, s, preferPostfix, fullRange)) =
let genTriviaForOnelinerAttributes f (ctx: Context) =
match ats with
| [] -> f ctx
| h :: _ ->
(enterNodeFor SynAttributeList_ h.Range
+> f
+> leaveNodeFor SynAttributeList_ h.Range)
ctx

let typeName =
genPreXmlDoc px
+> ifElse
astContext.IsFirstChild
(genAttributes astContext ats -- "type ")
(!- "and " +> genOnelinerAttributes astContext ats)
((!- "and " +> genOnelinerAttributes astContext ats)
|> genTriviaForOnelinerAttributes)
+> opt sepSpace ao genAccess
+> genTypeAndParam astContext s tds tcs preferPostfix

Expand Down Expand Up @@ -3855,6 +3882,7 @@ and genSigTypeDefn astContext (SigTypeDef (ats, px, ao, tds, tcs, tdr, ms, s, pr
+> unindent

| SigExceptionRepr (SigExceptionDefRepr (ats, px, ao, uc)) -> genExceptionBody astContext ats px ao uc
|> genTriviaFor TypeDefnSig_ fullRange

and genSigSimpleRecord tdr ms ao' fs astContext =
// the typeName is already printed
Expand Down
15 changes: 7 additions & 8 deletions src/Fantomas/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,28 +1344,27 @@ let internal sepNlnConsideringTriviaContentBeforeWithAttributesFor
(attributeRanges: Range seq)
(ctx: Context)
=
let triviaNode =
let triviaNodeBeforeMain =
match Map.tryFind mainNode ctx.TriviaMainNodes with
| Some triviaNodes ->
List.tryFind
List.exists
(fun { Range = r; ContentBefore = cb } ->
hasPrintableContent cb
&& RangeHelpers.rangeEq r ownRange)
triviaNodes
| None -> None
| None -> false

let attributeNode =
let triviaNodeBeforeAttribute =
match Map.tryFind SynAttributeList_ ctx.TriviaMainNodes with
| Some attributeNodes ->
List.tryFind
List.exists
(fun { Range = r; ContentBefore = cb } ->
hasPrintableContent cb
&& Seq.exists (RangeHelpers.rangeEq r) attributeRanges)
attributeNodes
| None -> None
| None -> false

if Option.isSome triviaNode
|| Option.isSome attributeNode then
if triviaNodeBeforeMain || triviaNodeBeforeAttribute then
ctx
else
sepNln ctx
Expand Down
1 change: 1 addition & 0 deletions src/Fantomas/Fantomas.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Compile Include="TriviaTypes.fs" />
<Compile Include="Dbg.fs" />
<Compile Include="Utils.fs" />
<Compile Include="AstExtensions.fs" />
<Compile Include="AstTransformer.fs" />
<Compile Include="SourceOrigin.fs" />
<Compile Include="Version.fs" />
Expand Down
9 changes: 7 additions & 2 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open FSharp.Compiler.SyntaxTree
open FSharp.Compiler.XmlDoc
open Fantomas
open Fantomas.Context
open Fantomas.AstExtensions

type Composite<'a, 'b> =
| Pair of 'b * 'b
Expand Down Expand Up @@ -1353,9 +1354,9 @@ let (|SigTypeDef|)
(SynTypeDefnSig.TypeDefnSig (SynComponentInfo.ComponentInfo (ats, tds, tcs, LongIdent s, px, preferPostfix, ao, _),
tdr,
ms,
_))
_) as node)
=
(ats, px, ao, tds, tcs, tdr, ms, s, preferPostfix)
(ats, px, ao, tds, tcs, tdr, ms, s, preferPostfix, node.FullRange)

let (|TyparDecl|) (SynTyparDecl.TyparDecl (ats, tp)) = (ats, tp)

Expand Down Expand Up @@ -1586,6 +1587,10 @@ let getRangesFromAttributesFromSynModuleSigDeclaration (sdl: SynModuleSigDecl) =
| _ -> Seq.empty
|> Seq.toList

let getRangesFromAttributesFromSynTypeDefnSig (TypeDefnSig (comp, _, _, _)) =
match comp with
| SynComponentInfo.ComponentInfo (attrs, _, _, _, _, _, _, _) -> collectAttributesRanges attrs

let getRangesFromAttributesFromSynBinding (sb: SynBinding) =
match sb with
| SynBinding.Binding (_, _, _, _, attrs, _, _, _, _, _, _, _) -> attrs |> List.map (fun a -> a.Range)
Expand Down
2 changes: 1 addition & 1 deletion src/Fantomas/TriviaTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ type FsAstType =
| ArgOptions_
| InterfaceImpl_
| TypeDefn_
// | TypeDefnSig_ use first nested type
| TypeDefnSig_
// | SynTypeDefnSigRepr_ObjectModel use first nested node
| SynTypeDefnSigRepr_Exception
| SynMemberDefn_Open
Expand Down

0 comments on commit 61ef1ed

Please sign in to comment.