From d2c677642b6e48ae0fb4dd51dcbea59a79526d45 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Tue, 2 May 2023 09:33:47 +0200 Subject: [PATCH 01/17] Expose TransformAST api. (#2868) * Expose TransformAST api. * Add additional unit test. * Revert changelog entry --- src/Fantomas.Core.Tests/CodeFormatterTests.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Fantomas.Core.Tests/CodeFormatterTests.fs b/src/Fantomas.Core.Tests/CodeFormatterTests.fs index b396a37a48..f44801cc39 100644 --- a/src/Fantomas.Core.Tests/CodeFormatterTests.fs +++ b/src/Fantomas.Core.Tests/CodeFormatterTests.fs @@ -1,5 +1,6 @@ module Fantomas.Core.Tests.CodeFormatterTests +open Fantomas.Core.SyntaxOak open NUnit.Framework open Fantomas.FCS.Text open Fantomas.Core From ee664f5ceb9fb2d95e6590f71f892ce88c3ca184 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Wed, 19 Apr 2023 09:31:48 -0600 Subject: [PATCH 02/17] Fix issues with multiline generic type parameters --- src/Fantomas.Core.Tests/ClassTests.fs | 6 +- src/Fantomas.Core.Tests/DallasTests.fs | 13 +-- ...ineBetweenTypeDefinitionAndMembersTests.fs | 8 +- src/Fantomas.Core.Tests/SignatureTests.fs | 11 ++- .../TypeAnnotationTests.fs | 81 ++++++++++++++++++- .../TypeDeclarationTests.fs | 42 +++++++++- src/Fantomas.Core/CodePrinter.fs | 23 ++++-- src/Fantomas.Core/Context.fs | 2 +- 8 files changed, 158 insertions(+), 28 deletions(-) diff --git a/src/Fantomas.Core.Tests/ClassTests.fs b/src/Fantomas.Core.Tests/ClassTests.fs index 0bcaec3ad9..782d63095c 100644 --- a/src/Fantomas.Core.Tests/ClassTests.fs +++ b/src/Fantomas.Core.Tests/ClassTests.fs @@ -1187,8 +1187,10 @@ module rec Xterm [] type Terminal = abstract onKey: - IEvent<{| key: string - domEvent: KeyboardEvent |}> with get, set + IEvent< + {| key: string + domEvent: KeyboardEvent |} + > with get, set abstract onLineFeed: IEvent with get, set """ diff --git a/src/Fantomas.Core.Tests/DallasTests.fs b/src/Fantomas.Core.Tests/DallasTests.fs index 36238d6007..0b1ad27234 100644 --- a/src/Fantomas.Core.Tests/DallasTests.fs +++ b/src/Fantomas.Core.Tests/DallasTests.fs @@ -1515,11 +1515,14 @@ let autoCompleteItems: cmap * - (Position -> option) * - FSharp.Compiler.Syntax.ParsedInput> = + : cmap< + DeclName, + DeclarationListItem * + Position * + string * + (Position -> option) * + FSharp.Compiler.Syntax.ParsedInput + > = cmap () """ diff --git a/src/Fantomas.Core.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs b/src/Fantomas.Core.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs index aac4e5812c..1db3c91ccb 100644 --- a/src/Fantomas.Core.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs +++ b/src/Fantomas.Core.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs @@ -387,10 +387,10 @@ let ``multiline abstract member without constraints, 2175`` () = type FuseSortFunctionItem = abstract Item: key: string -> - U2<{| ``$``: string |}, ResizeArray<{| ``$``: - string - idx: - float |}>> with get, set + U2< + {| ``$``: string |}, + ResizeArray<{| ``$``: string; idx: float |}> + > with get, set abstract X: int """ diff --git a/src/Fantomas.Core.Tests/SignatureTests.fs b/src/Fantomas.Core.Tests/SignatureTests.fs index 41df952e01..784ae08d83 100644 --- a/src/Fantomas.Core.Tests/SignatureTests.fs +++ b/src/Fantomas.Core.Tests/SignatureTests.fs @@ -1554,9 +1554,14 @@ namespace Foo type Bar = member Hello : thing : - XLongLongLongLongLongLongLongLong 'a, bool -> 'b, bool -> 'c, bool -> 'd, bool -> ('e -> 'f) -> 'g, ('h - -> 'i) - -> 'j> * + XLongLongLongLongLongLongLongLong< + bool -> 'a, + bool -> 'b, + bool -> 'c, + bool -> 'd, + bool -> ('e -> 'f) -> 'g, + ('h -> 'i) -> 'j + > * item : int list -> LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong """ diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 1b632b83c2..367181cee5 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -2,6 +2,7 @@ module Fantomas.Core.Tests.TypeAnnotationTests open NUnit.Framework open FsUnit +open Fantomas.Core open Fantomas.Core.Tests.TestHelpers [] @@ -72,9 +73,13 @@ type X = equal """ type X = - Teq + Teq< + int, + list int, + System.DateTime array, + // + int + > """ [] @@ -116,7 +121,11 @@ type CancellableTaskResultBuilderBase with and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)> ( sm: - byref>>, + byref< + ResumableStateMachine< + CancellableTaskResultStateMachineData<'TOverall, 'Error> + > + >, task: CancellationToken -> ^TaskLike, continuation: ('TResult1 @@ -124,3 +133,67 @@ type CancellableTaskResultBuilderBase with ) : bool = true """ + +[] +let `` Aligned bracket style in anonymous record is respected, #2706`` () = + formatSourceString + false + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo<{| + kind: string + properties: {| statisticsEnabled: bool |} + |}> +""" + { config with + MultilineBracketStyle = Aligned } + |> prepend newline + |> should + equal + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo< + {| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" + +[] +let `` Aligned bracket style in anonymous record is respected for multiple types, #2706`` () = + formatSourceString + false + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo<{| + kind: string + properties: {| statisticsEnabled: bool |} + |},{| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" + { config with + MultilineBracketStyle = Aligned } + |> prepend newline + |> should + equal + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo< + {| + kind: string + properties: {| statisticsEnabled: bool |} + |}, + {| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 3fbc55d9ff..802f27000e 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2818,8 +2818,12 @@ and [] Bar<'context, 'a> = (fun inner -> if inner then let bv = - unbox 'b>> + unbox< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > bf this.InnerEquals af bf cont @@ -2832,6 +2836,40 @@ and [] Bar<'context, 'a> = } """ +[] +let ``multiple nested generic types`` () = + formatSourceString + false + """ +let bv = + unbox< + Fooadfadadfdadfadfadfadfadfadfsfdsfadfadadfada< + Foo< + innerContextLongLongLong, + bb + > + > + > + bf +""" + { config with MaxLineLength = 10 } + |> prepend newline + |> should + equal + """ +let bv = + unbox< + Fooadfadadfdadfadfadfadfadfadfsfdsfadfadadfada< + Foo< + innerContextLongLongLong, + bb + > + > + > + + bf +""" + [] let ``a huge amount of type declarations`` () = let sourceCode = diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index d1f2476efe..f4feb8e0e6 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -2267,13 +2267,21 @@ let genKeepIdentMatchClause (startNode: Node) (e: Expr) ctx = indentSepNlnUnindent (genExpr e) ctx let colGenericTypeParameters typeParameters = - coli sepComma typeParameters (fun idx t -> - let leadingSpace = - match t with - | Type.Var n when idx = 0 && String.startsWithOrdinal "^" n.Text -> sepSpace - | _ -> sepNone + let short sep = + coli sep typeParameters (fun idx t -> + let leadingSpace = + match t with + | Type.Var n when idx = 0 && String.startsWithOrdinal "^" n.Text -> sepSpace + | _ -> sepNone + + leadingSpace +> genType t) + + let long = indentSepNlnUnindent (short (sepComma +> sepNln)) +> sepNln - leadingSpace +> genType t) + // Multiline text type params should be unmodified + match typeParameters with + | [ Type.StaticConstant(Constant.FromText textNode) ] when textNode.Text.Contains("\n") -> (short sepComma) + | _ -> expressionFitsOnRestOfLine (short sepComma) long let genFunctionNameWithMultilineLids (trailing: Context -> Context) (longIdent: IdentListNode) = match longIdent.Content with @@ -3130,7 +3138,8 @@ let genType (t: Type) = +> optSingle genIdentListNodeWithDot node.PostIdentifier +> genSingleTextNode node.LessThen +> addExtraSpace - +> col sepComma node.Arguments genType + +> leadingExpressionIsMultiline (colGenericTypeParameters node.Arguments) (fun isMultiline -> + if isMultiline then !- " " else sepNone) +> addExtraSpace +> genSingleTextNode node.GreaterThan |> genNode node diff --git a/src/Fantomas.Core/Context.fs b/src/Fantomas.Core/Context.fs index b6b2a60a5d..31540dcb3f 100644 --- a/src/Fantomas.Core/Context.fs +++ b/src/Fantomas.Core/Context.fs @@ -662,7 +662,7 @@ let leadingExpressionResult leadingExpression continuationExpression (ctx: Conte continuationExpression ((lineCountBefore, columnBefore), (lineCountAfter, columnAfter)) contextAfterLeading -/// A leading expression is not consider multiline if it has a comment before it. +/// A leading expression is not considered multiline if it has a comment before it. /// For example /// let a = 7 /// // foo From 92ccc38418a3a5d1461ab7075fa9816621672328 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Tue, 2 May 2023 10:20:45 -0600 Subject: [PATCH 03/17] Refactor a few things per feedback --- src/Fantomas.Core/CodePrinter.fs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index f4feb8e0e6..91e5f23b77 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -2267,7 +2267,7 @@ let genKeepIdentMatchClause (startNode: Node) (e: Expr) ctx = indentSepNlnUnindent (genExpr e) ctx let colGenericTypeParameters typeParameters = - let short sep = + let genParameters sep = coli sep typeParameters (fun idx t -> let leadingSpace = match t with @@ -2276,12 +2276,13 @@ let colGenericTypeParameters typeParameters = leadingSpace +> genType t) - let long = indentSepNlnUnindent (short (sepComma +> sepNln)) +> sepNln + let long = indentSepNlnUnindent (genParameters (sepComma +> sepNln)) +> sepNln + let short = genParameters sepComma // Multiline text type params should be unmodified match typeParameters with - | [ Type.StaticConstant(Constant.FromText textNode) ] when textNode.Text.Contains("\n") -> (short sepComma) - | _ -> expressionFitsOnRestOfLine (short sepComma) long + | [ Type.StaticConstant(Constant.FromText textNode) ] when textNode.Text.Contains("\n") -> short + | _ -> expressionFitsOnRestOfLine short long let genFunctionNameWithMultilineLids (trailing: Context -> Context) (longIdent: IdentListNode) = match longIdent.Content with @@ -3139,7 +3140,7 @@ let genType (t: Type) = +> genSingleTextNode node.LessThen +> addExtraSpace +> leadingExpressionIsMultiline (colGenericTypeParameters node.Arguments) (fun isMultiline -> - if isMultiline then !- " " else sepNone) + onlyIf isMultiline (!- " ")) +> addExtraSpace +> genSingleTextNode node.GreaterThan |> genNode node From 9466eeaea1d88ca633645d69e45b0bce5040f47e Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Sat, 11 Nov 2023 09:48:36 -0700 Subject: [PATCH 04/17] Updates --- .../TypeAnnotationTests.fs | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 367181cee5..1619874911 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -135,7 +135,7 @@ type CancellableTaskResultBuilderBase with """ [] -let `` Aligned bracket style in anonymous record is respected, #2706`` () = +let ``Aligned bracket style in anonymous record is respected, #2706`` () = formatSourceString false """ @@ -163,7 +163,7 @@ let private asJson (arm: IArmResource) = """ [] -let `` Aligned bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``Aligned bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString false """ @@ -197,3 +197,75 @@ let private asJson (arm: IArmResource) = |} > """ + +[] +let ``Cramped bracket style in anonymous record is respected for multiple types, #2706`` () = + formatSourceString + false + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo<{| + kind: string + properties: {| statisticsEnabled: bool |} + |},{| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" + { config with + MultilineBracketStyle = Cramped } + |> prepend newline + |> should + equal + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo< + {| + kind: string + properties: {| statisticsEnabled: bool |} + |}, + {| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" + +[] +let ``Stroustrup bracket style in anonymous record is respected for multiple types, #2706`` () = + formatSourceString + false + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo<{| + kind: string + properties: {| statisticsEnabled: bool |} + |},{| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" + { config with + MultilineBracketStyle = Stroustrup } + |> prepend newline + |> should + equal + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo< + {| + kind: string + properties: {| statisticsEnabled: bool |} + |}, + {| + kind: string + properties: {| statisticsEnabled: bool |} + |} + > +""" From 8c70d940b638f32487e28308a3d6f1186b213886 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Sat, 11 Nov 2023 11:14:15 -0700 Subject: [PATCH 05/17] Rebase and add new test --- .../TypeAnnotationTests.fs | 12 +++---- .../TypeDeclarationTests.fs | 33 +++++++++++++++++++ src/Fantomas.Core/CodePrinter.fs | 4 +-- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 1619874911..cf774be536 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -223,14 +223,10 @@ let private asJson (arm: IArmResource) = let private asJson (arm: IArmResource) = arm.JsonModel |> convertTo< - {| - kind: string - properties: {| statisticsEnabled: bool |} - |}, - {| - kind: string - properties: {| statisticsEnabled: bool |} - |} + {| kind: string + properties: {| statisticsEnabled: bool |} |}, + {| kind: string + properties: {| statisticsEnabled: bool |} |} > """ diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 802f27000e..43fcdbbacf 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2719,6 +2719,39 @@ module OrderProcessing = -> Result // output (Result b/c one of deps returns a Result) """ +[] +let ``type application including nested multiline function type`` () = + formatSourceString + false + """ +let bv = unbox 'b>> bf + """ + { config with + MaxLineLength = 30 + SpaceBeforeUppercaseInvocation = true + SpaceBeforeClassConstructor = true + SpaceBeforeMember = true + SpaceBeforeColon = true + SpaceBeforeSemicolon = true + MultilineBracketStyle = Aligned + AlignFunctionSignatureToIndentation = true + AlternativeLongMemberDefinitions = true + MultiLineLambdaClosingNewline = true + NewlineBetweenTypeDefinitionAndMembers = false } + |> prepend newline + |> should + equal + """ +let bv = + unbox< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + bf +""" + [] let ``generic type arguments in function invocation, 1637`` () = formatSourceString diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 91e5f23b77..8fce8e02b9 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -1192,7 +1192,7 @@ let genExpr (e: Expr) = |> genNode node | Expr.TypeApp node -> fun ctx -> - let startColum = ctx.Column + let startColumn = ctx.Column genNode node @@ -1201,7 +1201,7 @@ let genExpr (e: Expr) = +> colGenericTypeParameters node.TypeParameters // we need to make sure each expression in the function application has offset at least greater than // See: https://github.com/fsprojects/fantomas/issues/1611 - +> addFixedSpaces startColum + +> addFixedSpaces startColumn +> genSingleTextNode node.GreaterThan) ctx | Expr.TryWithSingleClause node -> From 0fe41743d0498941ccedaf45a60f56092b5e3616 Mon Sep 17 00:00:00 2001 From: nojaf Date: Sat, 11 Nov 2023 21:21:21 +0100 Subject: [PATCH 06/17] Add one extra space to ensure expr remains an application. --- src/Fantomas.Core.Tests/LetBindingTests.fs | 2 +- src/Fantomas.Core.Tests/TypeAnnotationTests.fs | 8 ++++---- src/Fantomas.Core.Tests/TypeDeclarationTests.fs | 8 ++++---- src/Fantomas.Core/CodePrinter.fs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Fantomas.Core.Tests/LetBindingTests.fs b/src/Fantomas.Core.Tests/LetBindingTests.fs index 06aa4eb3f2..9a200e94ed 100644 --- a/src/Fantomas.Core.Tests/LetBindingTests.fs +++ b/src/Fantomas.Core.Tests/LetBindingTests.fs @@ -1800,7 +1800,7 @@ module PoorlyIndented = select name from things where id = :id - " > + " > dependency cmd.AsyncExecute(id = thingId) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index cf774be536..df8e111518 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -159,7 +159,7 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -195,7 +195,7 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -227,7 +227,7 @@ let private asJson (arm: IArmResource) = properties: {| statisticsEnabled: bool |} |}, {| kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -263,5 +263,5 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 43fcdbbacf..527b2d5073 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2747,8 +2747,8 @@ let bv = Foo< 'innerContextLongLongLong, 'bb -> 'b - > - > + > + > bf """ @@ -2856,7 +2856,7 @@ and [] Bar<'context, 'a> = 'innerContextLongLongLong, 'bb -> 'b > - > + > bf this.InnerEquals af bf cont @@ -2898,7 +2898,7 @@ let bv = bb > > - > + > bf """ diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 8fce8e02b9..5194fa8b19 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -1192,7 +1192,7 @@ let genExpr (e: Expr) = |> genNode node | Expr.TypeApp node -> fun ctx -> - let startColumn = ctx.Column + let startColumn = ctx.Column + 1 genNode node From 0539e98de5fd8ba6647dd14c577f03f26867078a Mon Sep 17 00:00:00 2001 From: nojaf Date: Sat, 11 Nov 2023 21:37:14 +0100 Subject: [PATCH 07/17] Only add extra space when in SynExpr.App --- src/Fantomas.Core.Tests/LetBindingTests.fs | 2 +- .../TypeAnnotationTests.fs | 8 ++-- .../TypeDeclarationTests.fs | 7 ++-- src/Fantomas.Core/CodePrinter.fs | 38 +++++++++++-------- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/Fantomas.Core.Tests/LetBindingTests.fs b/src/Fantomas.Core.Tests/LetBindingTests.fs index 9a200e94ed..06aa4eb3f2 100644 --- a/src/Fantomas.Core.Tests/LetBindingTests.fs +++ b/src/Fantomas.Core.Tests/LetBindingTests.fs @@ -1800,7 +1800,7 @@ module PoorlyIndented = select name from things where id = :id - " > + " > dependency cmd.AsyncExecute(id = thingId) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index df8e111518..cf774be536 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -159,7 +159,7 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -195,7 +195,7 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -227,7 +227,7 @@ let private asJson (arm: IArmResource) = properties: {| statisticsEnabled: bool |} |}, {| kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -263,5 +263,5 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 527b2d5073..e9147d1e8e 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2882,8 +2882,8 @@ let bv = bb > > - > - bf + > + bf """ { config with MaxLineLength = 10 } |> prepend newline @@ -2899,8 +2899,7 @@ let bv = > > > - - bf + bf """ [] diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 5194fa8b19..f63721d4d9 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -1183,27 +1183,19 @@ let genExpr (e: Expr) = else indentSepNlnUnindent f ctx - (genExpr node.FunctionExpr + let genFuncExpr = + match node.FunctionExpr with + | Expr.TypeApp node -> genTypeApp true node + | _ -> genExpr node.FunctionExpr + + (genFuncExpr +> ensureArgumentsAreNotAlignedWithFunctionName (col sepNln node.Arguments genExpr)) ctx expressionFitsOnRestOfLine shortExpression longExpression ctx |> genNode node - | Expr.TypeApp node -> - fun ctx -> - let startColumn = ctx.Column + 1 - - genNode - node - (genExpr node.Identifier - +> genSingleTextNode node.LessThan - +> colGenericTypeParameters node.TypeParameters - // we need to make sure each expression in the function application has offset at least greater than - // See: https://github.com/fsprojects/fantomas/issues/1611 - +> addFixedSpaces startColumn - +> genSingleTextNode node.GreaterThan) - ctx + | Expr.TypeApp node -> genTypeApp false node | Expr.TryWithSingleClause node -> let genClause = let clauseNode = node.Clause @@ -2030,6 +2022,22 @@ let genAppSingleParenArgExpr (addSpace: Context -> Context) (node: ExprAppSingle expressionFitsOnRestOfLine short long |> genNode node +/// When called from `SynExpr.App` we need to ensure the node.GreaterThan is placed one space further than the start column. +/// This is to ensure the application remains an application. +let genTypeApp (addAdditionalColumnOffset: bool) (node: ExprTypeAppNode) (ctx: Context) : Context = + let startColumn = ctx.Column + (if addAdditionalColumnOffset then 1 else 0) + + genNode + node + (genExpr node.Identifier + +> genSingleTextNode node.LessThan + +> colGenericTypeParameters node.TypeParameters + // we need to make sure each expression in the function application has offset at least greater than + // See: https://github.com/fsprojects/fantomas/issues/1611 + +> addFixedSpaces startColumn + +> genSingleTextNode node.GreaterThan) + ctx + let genClauses (clauses: MatchClauseNode list) = let lastIndex = clauses.Length - 1 From 4f287b7af6ac2cbccfcc6a4e57507c182226ecd5 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Sat, 11 Nov 2023 11:14:15 -0700 Subject: [PATCH 08/17] Rebase and add new test --- src/Fantomas.Core.Tests/TypeDeclarationTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index e9147d1e8e..694b01cc73 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2747,8 +2747,8 @@ let bv = Foo< 'innerContextLongLongLong, 'bb -> 'b - > - > + > + > bf """ From 1cd2a3731c56cf121bd86721dbac4b697efbf76e Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Mon, 13 Nov 2023 11:52:18 -0700 Subject: [PATCH 09/17] Add test --- .../TypeDeclarationTests.fs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 694b01cc73..a0e66510f4 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2902,6 +2902,29 @@ let bv = bf """ +[] +let ``Trivia inside multiline generic type parameters`` () = + formatSourceString + false + """ +type X = + Teq< // + int + // + > +""" + config + |> prepend newline + |> should + equal + """ +type X = + Teq< // + int + // + > +""" + [] let ``a huge amount of type declarations`` () = let sourceCode = From e2581e797e785d9612f0fe1d8bdc1efe321bd2d4 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Sat, 18 Nov 2023 14:11:41 -0700 Subject: [PATCH 10/17] WIP --- .../TypeAnnotationTests.fs | 113 ++++++++++++++++++ .../TypeDeclarationTests.fs | 33 ----- 2 files changed, 113 insertions(+), 33 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index cf774be536..559b42d7ca 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -265,3 +265,116 @@ let private asJson (arm: IArmResource) = |} > """ + +[] +let ``type application including nested multiline function type`` () = + formatSourceString + false + """ +let bv = unbox 'b>> bf + """ + { config with + MaxLineLength = 30 + SpaceBeforeUppercaseInvocation = true + SpaceBeforeClassConstructor = true + SpaceBeforeMember = true + SpaceBeforeColon = true + SpaceBeforeSemicolon = true + MultilineBracketStyle = Aligned + AlignFunctionSignatureToIndentation = true + AlternativeLongMemberDefinitions = true + MultiLineLambdaClosingNewline = true + NewlineBetweenTypeDefinitionAndMembers = false } + |> prepend newline + |> should + equal + """ +let bv = + unbox< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + bf +""" + + +[] +let ``test for AppLongIdentAndSingleParenArg`` () = + formatSourceString false + """ +let private asJson (arm: IArmResource) = + arm.JsonModel + |> convertTo<{| + kind: string + properties: {| statisticsEnabled: bool |} + |}> +""" + config + |> prepend newline + |> should + equal + """ + """ + +[] +let ``test for AppSingleParenArg`` () = + formatSourceString false + """ +""" + config + |> prepend newline + |> should + equal + """ + """ + +[] +let ``test for AppWithLambda`` () = + formatSourceString false + """ +""" + config + |> prepend newline + |> should + equal + """ + """ + +[] +let ``test for NestedIndexWithoutDot`` () = + formatSourceString false + """ +""" + config + |> prepend newline + |> should + equal + """ + """ + +[] +let ``test for EndsWithDualListApp`` () = + formatSourceString false + """ +""" + config + |> prepend newline + |> should + equal + """ + """ + +[] +let ``test for EndsWithSingleListApp`` () = + formatSourceString false + """ +""" + config + |> prepend newline + |> should + equal + """ + """ + \ No newline at end of file diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index a0e66510f4..50c7669e11 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2719,39 +2719,6 @@ module OrderProcessing = -> Result // output (Result b/c one of deps returns a Result) """ -[] -let ``type application including nested multiline function type`` () = - formatSourceString - false - """ -let bv = unbox 'b>> bf - """ - { config with - MaxLineLength = 30 - SpaceBeforeUppercaseInvocation = true - SpaceBeforeClassConstructor = true - SpaceBeforeMember = true - SpaceBeforeColon = true - SpaceBeforeSemicolon = true - MultilineBracketStyle = Aligned - AlignFunctionSignatureToIndentation = true - AlternativeLongMemberDefinitions = true - MultiLineLambdaClosingNewline = true - NewlineBetweenTypeDefinitionAndMembers = false } - |> prepend newline - |> should - equal - """ -let bv = - unbox< - Foo< - 'innerContextLongLongLong, - 'bb -> 'b - > - > - bf -""" - [] let ``generic type arguments in function invocation, 1637`` () = formatSourceString From 4d9bbd19415a8743cb2c4ba3d6315ef213e545f5 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Wed, 22 Nov 2023 15:14:52 -0700 Subject: [PATCH 11/17] Update tests --- .../TypeAnnotationTests.fs | 271 +++++++++++++----- .../TypeDeclarationTests.fs | 2 - src/Fantomas.Core/CodePrinter.fs | 1 + 3 files changed, 200 insertions(+), 74 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 559b42d7ca..e7997cbd18 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -137,7 +137,6 @@ type CancellableTaskResultBuilderBase with [] let ``Aligned bracket style in anonymous record is respected, #2706`` () = formatSourceString - false """ let private asJson (arm: IArmResource) = arm.JsonModel @@ -165,7 +164,6 @@ let private asJson (arm: IArmResource) = [] let ``Aligned bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString - false """ let private asJson (arm: IArmResource) = arm.JsonModel @@ -201,7 +199,6 @@ let private asJson (arm: IArmResource) = [] let ``Cramped bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString - false """ let private asJson (arm: IArmResource) = arm.JsonModel @@ -233,7 +230,6 @@ let private asJson (arm: IArmResource) = [] let ``Stroustrup bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString - false """ let private asJson (arm: IArmResource) = arm.JsonModel @@ -266,25 +262,27 @@ let private asJson (arm: IArmResource) = > """ +let forcedLongDefnConfig = + { config with + MaxLineLength = 30 + SpaceBeforeUppercaseInvocation = true + SpaceBeforeClassConstructor = true + SpaceBeforeMember = true + SpaceBeforeColon = true + SpaceBeforeSemicolon = true + MultilineBracketStyle = Aligned + AlignFunctionSignatureToIndentation = true + // AlternativeLongMemberDefinitions = true + MultiLineLambdaClosingNewline = true + NewlineBetweenTypeDefinitionAndMembers = false } + [] let ``type application including nested multiline function type`` () = - formatSourceString - false + forcedLongDefnConfig + |> formatSourceString """ let bv = unbox 'b>> bf """ - { config with - MaxLineLength = 30 - SpaceBeforeUppercaseInvocation = true - SpaceBeforeClassConstructor = true - SpaceBeforeMember = true - SpaceBeforeColon = true - SpaceBeforeSemicolon = true - MultilineBracketStyle = Aligned - AlignFunctionSignatureToIndentation = true - AlternativeLongMemberDefinitions = true - MultiLineLambdaClosingNewline = true - NewlineBetweenTypeDefinitionAndMembers = false } |> prepend newline |> should equal @@ -299,82 +297,211 @@ let bv = bf """ - [] -let ``test for AppLongIdentAndSingleParenArg`` () = - formatSourceString false - """ -let private asJson (arm: IArmResource) = - arm.JsonModel - |> convertTo<{| - kind: string - properties: {| statisticsEnabled: bool |} - |}> -""" - config +let ``Multiline type argument with AppLongIdentAndSingleParenArg`` () = + + { config with + MaxLineLength = 30 + SpaceBeforeUppercaseInvocation = true + SpaceBeforeClassConstructor = true + SpaceBeforeMember = true + SpaceBeforeColon = true + SpaceBeforeSemicolon = true + MultilineBracketStyle = Aligned + AlignFunctionSignatureToIndentation = true + AlternativeLongMemberDefinitions = true + MultiLineLambdaClosingNewline = true + NewlineBetweenTypeDefinitionAndMembers = false } + |> formatSourceString + """ +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >("../../../", "....") +""" |> prepend newline - |> should - equal - """ + |> should + equal """ + """ + [] -let ``test for AppSingleParenArg`` () = - formatSourceString false +let ``Multiline type argument with AppLongIdentAndSingleParenArg 2`` () = + + { config with + MaxLineLength = 30 + SpaceBeforeClassConstructor = true + MultilineBracketStyle = Aligned } + |> formatSourceString """ -""" - config +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >("../../../", "....") +""" |> prepend newline - |> should - equal - """ + |> should + equal """ - +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > ( + "../../../", + "...." + ) +""" + [] -let ``test for AppWithLambda`` () = - formatSourceString false - """ -""" - config +let ``Multiline type argument with AppLongIdentAndSingleParenArg 3`` () = + { config with + MaxLineLength = 30 + SpaceBeforeClassConstructor = false + MultilineBracketStyle = Aligned } + |> formatSourceString + """ +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >("../../../", "....") +""" |> prepend newline - |> should - equal + |> should + equal """ +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >( + "../../../", + "...." + ) """ - + [] -let ``test for NestedIndexWithoutDot`` () = - formatSourceString false +let ``Multiline type argument with AppSingleParenArg`` () = + forcedLongDefnConfig + |> formatSourceString """ -""" - config +someFunc< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >(a,b) +""" |> prepend newline - |> should - equal - """ + |> should + equal """ - +someFunc< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >(a,b) +""" + [] -let ``test for EndsWithDualListApp`` () = - formatSourceString false - """ -""" - config +let ``Multiline type argument with AppWithLambda`` () = + forcedLongDefnConfig + |> formatSourceString + """ +someFunc< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > (fun x -> x) +""" |> prepend newline - |> should - equal + |> should + equal """ """ - + [] -let ``test for EndsWithSingleListApp`` () = - formatSourceString false +let ``Multiline type argument with NestedIndexWithoutDot`` () = + forcedLongDefnConfig + |> formatSourceString """ -""" - config +something< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >["thing"][8](a,b) +""" |> prepend newline - |> should - equal + |> should + equal """ +something< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + >["thing"][8](a,b) +""" + +[] +let ``Multiline type argument with EndsWithDualListApp`` () = + forcedLongDefnConfig + |> formatSourceString + """ +div< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > [ ClassName "container" ] [ str "meh" ] +""" + |> prepend newline + |> should + equal """ - \ No newline at end of file +div< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + [ ClassName "container" ] + [ str "meh" ] +""" + +[] +let ``Multiline type argument with EndsWithSingleListApp`` () = + forcedLongDefnConfig + |> formatSourceString + """ +input< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > [ Type "text" ] +""" + |> prepend newline + |> should + equal + """ +input< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + [ Type "text" ] +""" diff --git a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs index 50c7669e11..3dc368c1a7 100644 --- a/src/Fantomas.Core.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Core.Tests/TypeDeclarationTests.fs @@ -2839,7 +2839,6 @@ and [] Bar<'context, 'a> = [] let ``multiple nested generic types`` () = formatSourceString - false """ let bv = unbox< @@ -2872,7 +2871,6 @@ let bv = [] let ``Trivia inside multiline generic type parameters`` () = formatSourceString - false """ type X = Teq< // diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index f63721d4d9..14c9e52c3c 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -3150,6 +3150,7 @@ let genType (t: Type) = +> leadingExpressionIsMultiline (colGenericTypeParameters node.Arguments) (fun isMultiline -> onlyIf isMultiline (!- " ")) +> addExtraSpace + // TODO: I think we need to add a space here +> genSingleTextNode node.GreaterThan |> genNode node | Type.StructTuple node -> From 0209297dda6b2d28bc2e2822b0e4002f69f0507a Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Sat, 25 Nov 2023 14:47:52 -0700 Subject: [PATCH 12/17] Refactor test configs --- .../TypeAnnotationTests.fs | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index e7997cbd18..1dcdb0127c 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -262,23 +262,11 @@ let private asJson (arm: IArmResource) = > """ -let forcedLongDefnConfig = - { config with - MaxLineLength = 30 - SpaceBeforeUppercaseInvocation = true - SpaceBeforeClassConstructor = true - SpaceBeforeMember = true - SpaceBeforeColon = true - SpaceBeforeSemicolon = true - MultilineBracketStyle = Aligned - AlignFunctionSignatureToIndentation = true - // AlternativeLongMemberDefinitions = true - MultiLineLambdaClosingNewline = true - NewlineBetweenTypeDefinitionAndMembers = false } - [] let ``type application including nested multiline function type`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ let bv = unbox 'b>> bf @@ -391,7 +379,9 @@ path.Replace< [] let ``Multiline type argument with AppSingleParenArg`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ someFunc< @@ -415,7 +405,9 @@ someFunc< [] let ``Multiline type argument with AppWithLambda`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ someFunc< @@ -433,7 +425,9 @@ someFunc< [] let ``Multiline type argument with NestedIndexWithoutDot`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ something< @@ -457,7 +451,9 @@ something< [] let ``Multiline type argument with EndsWithDualListApp`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ div< @@ -483,7 +479,9 @@ div< [] let ``Multiline type argument with EndsWithSingleListApp`` () = - forcedLongDefnConfig + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned } |> formatSourceString """ input< From 346ca923eae02e54a1252e18754c2490c7bc0d99 Mon Sep 17 00:00:00 2001 From: Josh DeGraw Date: Thu, 4 Jan 2024 13:34:48 -0700 Subject: [PATCH 13/17] Fix issue and update newly broken tests --- src/Fantomas.Core.Tests/LetBindingTests.fs | 2 +- .../TypeAnnotationTests.fs | 118 ++++++++++++------ src/Fantomas.Core/CodePrinter.fs | 4 +- 3 files changed, 85 insertions(+), 39 deletions(-) diff --git a/src/Fantomas.Core.Tests/LetBindingTests.fs b/src/Fantomas.Core.Tests/LetBindingTests.fs index 06aa4eb3f2..9a200e94ed 100644 --- a/src/Fantomas.Core.Tests/LetBindingTests.fs +++ b/src/Fantomas.Core.Tests/LetBindingTests.fs @@ -1800,7 +1800,7 @@ module PoorlyIndented = select name from things where id = :id - " > + " > dependency cmd.AsyncExecute(id = thingId) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 1dcdb0127c..1f8a912403 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -135,7 +135,7 @@ type CancellableTaskResultBuilderBase with """ [] -let ``Aligned bracket style in anonymous record is respected, #2706`` () = +let ``aligned bracket style in anonymous record is respected, #2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -158,11 +158,11 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] -let ``Aligned bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``aligned bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -193,11 +193,11 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] -let ``Cramped bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``cramped bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -224,11 +224,11 @@ let private asJson (arm: IArmResource) = properties: {| statisticsEnabled: bool |} |}, {| kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] -let ``Stroustrup bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``stroustrup bracket style in anonymous record is respected for multiple types, #2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -259,7 +259,7 @@ let private asJson (arm: IArmResource) = kind: string properties: {| statisticsEnabled: bool |} |} - > + > """ [] @@ -286,8 +286,7 @@ let bv = """ [] -let ``Multiline type argument with AppLongIdentAndSingleParenArg`` () = - +let ``multiline type argument with AppLongIdentAndSingleParenArg`` () = { config with MaxLineLength = 30 SpaceBeforeUppercaseInvocation = true @@ -313,12 +312,19 @@ path.Replace< |> should equal """ - - """ +path.Replace< + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > ( + "../../../", + "...." +) +""" [] -let ``Multiline type argument with AppLongIdentAndSingleParenArg 2`` () = - +let ``multiline type argument with AppLongIdentAndSingleParenArg 2`` () = { config with MaxLineLength = 30 SpaceBeforeClassConstructor = true @@ -341,14 +347,14 @@ path.Replace< 'innerContextLongLongLong, 'bb -> 'b > - > ( - "../../../", - "...." - ) + >( + "../../../", + "...." +) """ [] -let ``Multiline type argument with AppLongIdentAndSingleParenArg 3`` () = +let ``multiline type argument with AppLongIdentAndSingleParenArg 3`` () = { config with MaxLineLength = 30 SpaceBeforeClassConstructor = false @@ -371,14 +377,14 @@ path.Replace< 'innerContextLongLongLong, 'bb -> 'b > - >( - "../../../", - "...." - ) - """ + >( + "../../../", + "...." +) +""" [] -let ``Multiline type argument with AppSingleParenArg`` () = +let ``multiline type argument with AppSingleParenArg`` () = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } @@ -396,15 +402,18 @@ someFunc< equal """ someFunc< - Foo< - 'innerContextLongLongLong, - 'bb -> 'b - > - >(a,b) + Foo< + 'innerContextLongLongLong, + 'bb -> 'b + > + > ( + a, + b +) """ [] -let ``Multiline type argument with AppWithLambda`` () = +let ``multiline type argument with AppWithLambda`` () = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } @@ -421,10 +430,17 @@ someFunc< |> should equal """ - """ +someFunc< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + (fun x -> x) +""" [] -let ``Multiline type argument with NestedIndexWithoutDot`` () = +let ``multiline type argument with NestedIndexWithoutDot`` () = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } @@ -446,11 +462,11 @@ something< 'innerContextLongLongLong, 'bb -> 'b > - >["thing"][8](a,b) + >["thing"][8](a, b) """ [] -let ``Multiline type argument with EndsWithDualListApp`` () = +let ``multiline type argument with EndsWithDualListApp`` () = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } @@ -478,7 +494,37 @@ div< """ [] -let ``Multiline type argument with EndsWithSingleListApp`` () = +let ``multiline type argument with elmish EndsWithDualListApp`` () = + { config with + MaxLineLength = 30 + MultilineBracketStyle = Aligned + ExperimentalElmish = true } + |> formatSourceString + """ +div< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > [ ClassName "container" ] [ str "meh" ] +""" + |> prepend newline + |> should + equal + """ +div< + Bar< + 'innerContextLongLongLong, + 'bb -> 'b + > + > + [ ClassName "container" ] [ + str "meh" + ] +""" + +[] +let ``multiline type argument with EndsWithSingleListApp`` () = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 14c9e52c3c..3db62b8452 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -1195,7 +1195,7 @@ let genExpr (e: Expr) = expressionFitsOnRestOfLine shortExpression longExpression ctx |> genNode node - | Expr.TypeApp node -> genTypeApp false node + | Expr.TypeApp node -> expressionFitsOnRestOfLine (genTypeApp false node) (genTypeApp true node) | Expr.TryWithSingleClause node -> let genClause = let clauseNode = node.Clause @@ -2358,7 +2358,7 @@ let (|EndsWithSingleRecordApp|_|) (config: FormatConfig) (appNode: ExprAppNode) visit args visit appNode.Arguments - + let genAppWithLambda sep (node: ExprAppWithLambdaNode) = let short = genExpr node.FunctionName From 51f76cb2b3c5f069421cf6b3d33a46956737cec4 Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 9 Jan 2024 17:06:57 +0100 Subject: [PATCH 14/17] Format CodePrinter --- src/Fantomas.Core/CodePrinter.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 3db62b8452..7d4549d10f 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -2358,7 +2358,7 @@ let (|EndsWithSingleRecordApp|_|) (config: FormatConfig) (appNode: ExprAppNode) visit args visit appNode.Arguments - + let genAppWithLambda sep (node: ExprAppWithLambdaNode) = let short = genExpr node.FunctionName From 9f4f46c880af2774b32691ad389125615dccd173 Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 9 Jan 2024 17:41:08 +0100 Subject: [PATCH 15/17] Use more typical unit test template. --- .../TypeAnnotationTests.fs | 90 ++++++++----------- 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 1f8a912403..6979b938fd 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -262,15 +262,18 @@ let private asJson (arm: IArmResource) = > """ -[] -let ``type application including nested multiline function type`` () = +let alignedMaxLine30 = { config with MaxLineLength = 30 MultilineBracketStyle = Aligned } - |> formatSourceString + +[] +let ``type application including nested multiline function type`` () = + formatSourceString """ let bv = unbox 'b>> bf - """ +""" + alignedMaxLine30 |> prepend newline |> should equal @@ -287,19 +290,7 @@ let bv = [] let ``multiline type argument with AppLongIdentAndSingleParenArg`` () = - { config with - MaxLineLength = 30 - SpaceBeforeUppercaseInvocation = true - SpaceBeforeClassConstructor = true - SpaceBeforeMember = true - SpaceBeforeColon = true - SpaceBeforeSemicolon = true - MultilineBracketStyle = Aligned - AlignFunctionSignatureToIndentation = true - AlternativeLongMemberDefinitions = true - MultiLineLambdaClosingNewline = true - NewlineBetweenTypeDefinitionAndMembers = false } - |> formatSourceString + formatSourceString """ path.Replace< Foo< @@ -308,6 +299,18 @@ path.Replace< > >("../../../", "....") """ + { config with + MaxLineLength = 30 + SpaceBeforeUppercaseInvocation = true + SpaceBeforeClassConstructor = true + SpaceBeforeMember = true + SpaceBeforeColon = true + SpaceBeforeSemicolon = true + MultilineBracketStyle = Aligned + AlignFunctionSignatureToIndentation = true + AlternativeLongMemberDefinitions = true + MultiLineLambdaClosingNewline = true + NewlineBetweenTypeDefinitionAndMembers = false } |> prepend newline |> should equal @@ -325,11 +328,7 @@ path.Replace< [] let ``multiline type argument with AppLongIdentAndSingleParenArg 2`` () = - { config with - MaxLineLength = 30 - SpaceBeforeClassConstructor = true - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ path.Replace< Foo< @@ -338,6 +337,8 @@ path.Replace< > >("../../../", "....") """ + { alignedMaxLine30 with + SpaceBeforeClassConstructor = true } |> prepend newline |> should equal @@ -355,11 +356,7 @@ path.Replace< [] let ``multiline type argument with AppLongIdentAndSingleParenArg 3`` () = - { config with - MaxLineLength = 30 - SpaceBeforeClassConstructor = false - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ path.Replace< Foo< @@ -368,6 +365,7 @@ path.Replace< > >("../../../", "....") """ + alignedMaxLine30 |> prepend newline |> should equal @@ -385,10 +383,7 @@ path.Replace< [] let ``multiline type argument with AppSingleParenArg`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ someFunc< Foo< @@ -397,6 +392,7 @@ someFunc< > >(a,b) """ + alignedMaxLine30 |> prepend newline |> should equal @@ -414,10 +410,7 @@ someFunc< [] let ``multiline type argument with AppWithLambda`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ someFunc< Bar< @@ -426,6 +419,7 @@ someFunc< > > (fun x -> x) """ + alignedMaxLine30 |> prepend newline |> should equal @@ -441,10 +435,7 @@ someFunc< [] let ``multiline type argument with NestedIndexWithoutDot`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ something< Foo< @@ -453,6 +444,7 @@ something< > >["thing"][8](a,b) """ + alignedMaxLine30 |> prepend newline |> should equal @@ -467,10 +459,7 @@ something< [] let ``multiline type argument with EndsWithDualListApp`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ div< Bar< @@ -479,6 +468,7 @@ div< > > [ ClassName "container" ] [ str "meh" ] """ + alignedMaxLine30 |> prepend newline |> should equal @@ -495,11 +485,7 @@ div< [] let ``multiline type argument with elmish EndsWithDualListApp`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned - ExperimentalElmish = true } - |> formatSourceString + formatSourceString """ div< Bar< @@ -508,6 +494,8 @@ div< > > [ ClassName "container" ] [ str "meh" ] """ + { alignedMaxLine30 with + ExperimentalElmish = true } |> prepend newline |> should equal @@ -525,10 +513,7 @@ div< [] let ``multiline type argument with EndsWithSingleListApp`` () = - { config with - MaxLineLength = 30 - MultilineBracketStyle = Aligned } - |> formatSourceString + formatSourceString """ input< Bar< @@ -537,6 +522,7 @@ input< > > [ Type "text" ] """ + alignedMaxLine30 |> prepend newline |> should equal From 9f00368774a6d18b35296de50af74450e7b0915a Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 9 Jan 2024 17:55:36 +0100 Subject: [PATCH 16/17] Add additional unit tests. --- .../TypeAnnotationTests.fs | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs index 6979b938fd..d24c12d665 100644 --- a/src/Fantomas.Core.Tests/TypeAnnotationTests.fs +++ b/src/Fantomas.Core.Tests/TypeAnnotationTests.fs @@ -135,7 +135,7 @@ type CancellableTaskResultBuilderBase with """ [] -let ``aligned bracket style in anonymous record is respected, #2706`` () = +let ``aligned bracket style in anonymous record is respected, 2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -162,7 +162,7 @@ let private asJson (arm: IArmResource) = """ [] -let ``aligned bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``aligned bracket style in anonymous record is respected for multiple types, 2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -197,7 +197,7 @@ let private asJson (arm: IArmResource) = """ [] -let ``cramped bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``cramped bracket style in anonymous record is respected for multiple types, 2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -228,7 +228,7 @@ let private asJson (arm: IArmResource) = """ [] -let ``stroustrup bracket style in anonymous record is respected for multiple types, #2706`` () = +let ``stroustrup bracket style in anonymous record is respected for multiple types, 2706`` () = formatSourceString """ let private asJson (arm: IArmResource) = @@ -535,3 +535,47 @@ input< > [ Type "text" ] """ + +[] +let ``multiline type argument with index without dot`` () = + formatSourceString + """ +XYZ.app int -> int -> string>[tellMeWhy { return wouldSomeoneWriteThisCode }] +""" + alignedMaxLine30 + |> prepend newline + |> should + equal + """ +XYZ.app< + int + -> int + -> int + -> string + >[tellMeWhy { + return + wouldSomeoneWriteThisCode + }] +""" + +[] +let ``multiline type argument with Index with dot`` () = + formatSourceString + """ +XYZ.app int -> int -> string>.[tellMeWhy { return wouldSomeoneWriteThisCode }] +""" + alignedMaxLine30 + |> prepend newline + |> should + equal + """ +XYZ.app< + int + -> int + -> int + -> string + >.[tellMeWhy { + return + wouldSomeoneWriteThisCode +}] +""" From 9cc60a292356a1b44dfc224f21f9709de73ca3fc Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 9 Jan 2024 17:59:37 +0100 Subject: [PATCH 17/17] Add changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88857aa072..57dce7d890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 6.3.0-alpha-006 - 2024-01-09 + +### Changed +* Aligned bracket style in anonymous record is not respected. [#2706](https://github.com/fsprojects/fantomas/issues/2706) [style guide](https://github.com/fsharp/fslang-design/issues/756) + ## 6.3.0-alpha-005 - 2023-12-22 ### Changed