From 503a4711761d3e2b2cac976eda9bb38decc33ea7 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Tue, 1 Feb 2022 08:26:28 +0100 Subject: [PATCH] Visit SynTypar indent in AstTransformer.fs. Fixes #2052. (#2053) --- src/Fantomas.Tests/CommentTests.fs | 15 +++++++++++++++ src/Fantomas.Tests/InterfaceTests.fs | 6 +++--- src/Fantomas/AstTransformer.fs | 6 +++++- src/Fantomas/CodePrinter.fs | 11 ++++++----- src/Fantomas/SourceParser.fs | 12 ++++++------ 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/Fantomas.Tests/CommentTests.fs b/src/Fantomas.Tests/CommentTests.fs index 8ed6582a8a..4e1225dee7 100644 --- a/src/Fantomas.Tests/CommentTests.fs +++ b/src/Fantomas.Tests/CommentTests.fs @@ -1744,3 +1744,18 @@ let a = 9 // bar let a = 9 """ + +[] +let ``comment after SynTypar, 2052`` () = + formatSourceString + false + """ +let Foo<'T (* TODO *)> () = () +""" + config + |> prepend newline + |> should + equal + """ +let Foo<'T (* TODO *) > () = () +""" diff --git a/src/Fantomas.Tests/InterfaceTests.fs b/src/Fantomas.Tests/InterfaceTests.fs index 8ef954e4a5..82e7fb66ac 100644 --- a/src/Fantomas.Tests/InterfaceTests.fs +++ b/src/Fantomas.Tests/InterfaceTests.fs @@ -236,13 +236,13 @@ type IArgParserTemplate = [] let ``generic interface member should have space after name`` () = - let source = + formatSourceString + false """ type IFunc<'R> = abstract Invoke<'T> : unit -> 'R // without this space the code is invalid """ - - formatSourceString false source config + config |> fun formatted -> formatSourceString false formatted config |> should equal diff --git a/src/Fantomas/AstTransformer.fs b/src/Fantomas/AstTransformer.fs index 28ab282f62..19a2cafba7 100644 --- a/src/Fantomas/AstTransformer.fs +++ b/src/Fantomas/AstTransformer.fs @@ -853,7 +853,11 @@ module private Ast = and visitSynTyparDecl (std: SynTyparDecl) : TriviaNodeAssigner list = match std with - | SynTyparDecl (attrs, _) -> [ yield! (visitSynAttributeLists attrs) ] + | SynTyparDecl (attrs, synTypar) -> + [ yield! (visitSynAttributeLists attrs) + yield visitSynTypar synTypar ] + + and visitSynTypar (SynTypar (ident, _typarStaticReq, _isCompGen)) = mkNode Ident_ ident.idRange and visitSynBindingReturnInfo (returnInfo: SynBindingReturnInfo) : TriviaNodeAssigner list = match returnInfo with diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index c120245091..2a89800e52 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -4260,7 +4260,9 @@ and genType astContext outerBracket t = +> loop t2 | TArray (t, n) -> loop t -- " [" +> rep (n - 1) (!- ",") -- "]" | TAnon -> sepWild - | TVar tp -> genTypar astContext tp + | TVar (tp, r) -> + genTypar astContext tp + |> genTriviaFor SynType_Var r // Drop bracket around tuples before an arrow | TFun (TTuple ts, t) -> loopTTupleList ts +> sepArrow +> loop t // Do similar for tuples after an arrow @@ -4399,7 +4401,7 @@ and genPrefixTypes astContext node (range: Range) ctx = match node with | [] -> ctx // Where < and ^ meet, we need an extra space. For example: seq< ^a > - | TVar (Typar (_, true)) as t :: ts -> + | TVar (Typar (_, _, true), _r) as t :: ts -> (!- "< " +> col sepComma (t :: ts) (genType astContext false) -- " >") @@ -4491,10 +4493,9 @@ and genTypeList astContext node = expressionFitsOnRestOfLine shortExpr longExpr -and genTypar astContext (Typar (s, isHead) as node) = +and genTypar astContext (Typar (s, idRange, isHead)) = ifElse isHead (ifElse astContext.IsFirstTypeParam (!- " ^") (!- "^")) (!- "'") - -- s - |> genTriviaFor SynType_Var node.Range + +> genTriviaFor Ident_ idRange !-s and genTypeConstraint astContext node = match node with diff --git a/src/Fantomas/SourceParser.fs b/src/Fantomas/SourceParser.fs index 9bcdb87175..5a649414f0 100644 --- a/src/Fantomas/SourceParser.fs +++ b/src/Fantomas/SourceParser.fs @@ -181,10 +181,10 @@ let (|OpNameFull|) (x: Identifier) = // Type params -let inline (|Typar|) (SynTypar.SynTypar (Ident s, req, _)) = +let inline (|Typar|) (SynTypar.SynTypar (Ident s as ident, req, _)) = match req with - | TyparStaticReq.None -> (s, false) - | TyparStaticReq.HeadType -> (s, true) + | TyparStaticReq.None -> (s, ident.idRange, false) + | TyparStaticReq.HeadType -> (s, ident.idRange, true) let inline (|ValTyparDecls|) (SynValTyparDecls (tds, b)) = (tds, b) @@ -199,7 +199,7 @@ let rec (|RationalConst|) = let (|Measure|) x = let rec loop = function - | SynMeasure.Var (Typar (s, _), _) -> s + | SynMeasure.Var (Typar (s, _, _), _) -> s | SynMeasure.Anon _ -> "_" | SynMeasure.One -> "1" | SynMeasure.Product (m1, m2, _) -> @@ -1446,7 +1446,7 @@ let (|TAnon|_|) = let (|TVar|_|) = function - | SynType.Var (tp, _) -> Some tp + | SynType.Var (tp, r) -> Some(tp, r) | _ -> None let (|TFun|_|) = @@ -1648,7 +1648,7 @@ let rec (|UppercaseSynType|LowercaseSynType|) (synType: SynType) = match synType with | SynType.LongIdent (LongIdentWithDots lid) -> lid.Split('.') |> Seq.last |> upperOrLower - | SynType.Var (Typar (s, _), _) -> upperOrLower s + | SynType.Var (Typar (s, _, _), _) -> upperOrLower s | SynType.App (st, _, _, _, _, _, _) -> (|UppercaseSynType|LowercaseSynType|) st | _ -> failwithf "cannot determine if synType %A is uppercase or lowercase" synType