diff --git a/src/Fantomas.Tests/TypeProviderTests.fs b/src/Fantomas.Tests/TypeProviderTests.fs index f9153d21da..c189b1219c 100644 --- a/src/Fantomas.Tests/TypeProviderTests.fs +++ b/src/Fantomas.Tests/TypeProviderTests.fs @@ -19,7 +19,7 @@ let ``should add space before type provider params``() = type IntegerRegex = FSharpx.Regex< @"(?\d+)" >""" config |> prepend newline |> should equal """ -type IntegerRegex = FSharpx.Regex<@"(?\d+)"> +type IntegerRegex = FSharpx.Regex< @"(?\d+)" > """ [] diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 4ad98ff7b0..a58f9eae9f 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -2578,14 +2578,28 @@ and genType astContext outerBracket t = and genAnonRecordFieldType astContext (AnonRecordFieldType(s, t)) = !- s +> sepColon +> (genType astContext false t) -and genPrefixTypes astContext node = +and genPrefixTypes astContext node ctx = match node with - | [] -> sepNone + | [] -> ctx // Where < and ^ meet, we need an extra space. For example: seq< ^a > | (TVar(Typar(_, true)) as t)::ts -> - !- "< " +> col sepComma (t::ts) (genType astContext false) -- " >" - | ts -> - !- "<" +> col sepComma ts (genType astContext false) -- ">" + (!- "< " +> col sepComma (t::ts) (genType astContext false) -- " >") ctx + | t::_ -> + // for example: FSharpx.Regex< @"(?\d+)" > + let firstItemHasAtSignBeforeString = + match t with + | SourceParser.TStaticConstant(_,r) -> + TriviaHelpers.``has content itself that matches`` + (function | StringContent sc -> sc.StartsWith("@") | _ -> false) + r + ctx.Trivia + | _ -> false + + (!- "<" + +> onlyIf firstItemHasAtSignBeforeString sepSpace + +> col sepComma node (genType astContext false) + +> onlyIf firstItemHasAtSignBeforeString sepSpace + -- ">") ctx // |> genTrivia node and genTypeList astContext node = diff --git a/src/Fantomas/TriviaHelpers.fs b/src/Fantomas/TriviaHelpers.fs index 7ee35ed07d..4d827c2d87 100644 --- a/src/Fantomas/TriviaHelpers.fs +++ b/src/Fantomas/TriviaHelpers.fs @@ -65,6 +65,13 @@ module internal TriviaHelpers = | Some(CharContent c) -> Some c | _ -> None) + let ``has content itself that matches`` (predicate: TriviaContent -> bool) range (triviaNodes: TriviaNode list) = + triviaNodes + |> List.exists (fun tn -> + match tn.Range = range, tn.ContentItself with + | true, Some(t) -> predicate t + | _ -> false) + let ``has content itself is ident between ticks`` range (triviaNodes: TriviaNode list) = triviaNodes |> List.choose (fun tn ->