diff --git a/src/Fantomas.Tests/SignatureTests.fs b/src/Fantomas.Tests/SignatureTests.fs index 611d0efd47..cf32a67403 100644 --- a/src/Fantomas.Tests/SignatureTests.fs +++ b/src/Fantomas.Tests/SignatureTests.fs @@ -614,14 +614,31 @@ let ``operator with constraint`` () = """namespace Bar val inline (.+.) : x : ^a Foo -> y : ^b Foo -> ^c Foo when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) """ - config + { config with SpaceBeforeColon = true } + |> prepend newline + |> should + equal + """ +namespace Bar + +val inline (.+.) : x : ^a Foo -> y : ^b Foo -> ^c Foo when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) +""" + +[] +let ``operator with named constraint`` () = + formatSourceString + true + """namespace Bar + val inline (.+.) : x : ^a Foo -> y : ^b Foo -> z: ^c Foo when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) +""" + { config with SpaceBeforeColon = true } |> prepend newline |> should equal """ namespace Bar -val inline (.+.): x : ^a Foo -> y : ^b Foo -> ^c Foo when (^a or ^b): (static member (+): ^a * ^b -> ^c) +val inline (.+.) : x : ^a Foo -> y : ^b Foo -> z : ^c Foo when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) """ [] diff --git a/src/Fantomas.Tests/TypeDeclarationTests.fs b/src/Fantomas.Tests/TypeDeclarationTests.fs index acee9c4175..7bce3941c3 100644 --- a/src/Fantomas.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Tests/TypeDeclarationTests.fs @@ -1836,8 +1836,7 @@ type OuterType = equal """ type OuterType = - abstract Apply<'r> : InnerType<'r> - -> 'r when 'r : comparison + abstract Apply<'r> : InnerType<'r> -> 'r when 'r : comparison """ [] @@ -2374,3 +2373,42 @@ let deserialize (e: RecordedEvent): MyEvent = | nameof BData -> BData(JsonSerializer.Deserialize e.Data) | t -> failwithf "Invalid EventType: %s" t """ + +[] +let ``member constraint on next line should have extra indent, 1394`` () = + formatSourceString + false + """ +type Bar = | Bar of int +and Foo<'ret> = abstract Barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr<'a> : 'a -> 'ret when 'a : comparison +""" + { config with MaxLineLength = 80 } + |> prepend newline + |> should + equal + """ +type Bar = Bar of int + +and Foo<'ret> = + abstract Barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr<'a> : + 'a -> 'ret when 'a: comparison +""" + +[] +let ``member constraint on next line with long return type`` () = + formatSourceString + false + """ +type Foo = + abstract Baaaaaaaaaaaaaarrrrrrr<'a> : 'a -> int -> string -> string -> bool when 'a : comparison +""" + { config with MaxLineLength = 60 } + |> prepend newline + |> should + equal + """ +type Foo = + abstract Baaaaaaaaaaaaaarrrrrrr<'a> : + 'a -> int -> string -> string -> bool + when 'a: comparison +""" diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index b52ae8bb57..5a2ead74f3 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -952,7 +952,7 @@ and genVal astContext (Val (ats, px, ao, s, t, vi, isInline, _) as node) = +> ifElse (List.isNotEmpty namedArgs) (autoNlnIfExpressionExceedsPageWidth (genTypeList astContext namedArgs)) - (genConstraints astContext t) + (genConstraints astContext t vi) +> unindent ) |> genTriviaFor ValSpfn_ range @@ -3741,7 +3741,7 @@ and genMemberSig astContext node = +> genTypeParamPostfix astContext tds tcs +> sepColonX +> genTypeList astContext namedArgs - +> genConstraints astContext t + +> genConstraints astContext t vi -- (genPropertyKind (not isFunctionProperty) mf.MemberKind) ) @@ -3751,10 +3751,30 @@ and genMemberSig astContext node = | MSNestedType _ -> invalidArg "md" "This is not implemented in F# compiler" |> genTriviaFor mainNodeName range -and genConstraints astContext (t: SynType) = +and genConstraints astContext (t: SynType) (vi: SynValInfo) = match t with - | TWithGlobalConstraints (t, tcs) -> - genTypeByLookup astContext t + | TWithGlobalConstraints (ti, tcs) -> + let genType = + match ti, vi with + | TFuns ts, SynValInfo (curriedArgInfos, returnType) -> + let namedArgInfos = + (List.map List.head curriedArgInfos) + @ [ returnType ] + |> List.map (fun (SynArgInfo (_, _, i)) -> i) + + coli + sepArrow + ts + (fun i t -> + let genNamedArg = + List.tryItem i namedArgInfos + |> Option.bind id + |> optSingle (fun (Ident (s)) -> !-s +> sepColon) + + genNamedArg +> genType astContext false t) + | _ -> genType astContext false ti + + genType +> sepSpaceOrNlnIfExpressionExceedsPageWidth ( ifElse (List.isNotEmpty tcs) (!- "when ") sepSpace +> col wordAnd tcs (genTypeConstraint astContext) @@ -4313,7 +4333,7 @@ and genMemberDefn astContext node = +> sepColonX +> genTypeList astContext namedArgs -- genPropertyKind (not isFunctionProperty) mk - +> genConstraints astContext t + +> autoIndentAndNlnIfExpressionExceedsPageWidth (genConstraints astContext t vi) | md -> failwithf "Unexpected member definition: %O" md |> genTriviaFor (synMemberDefnToFsAstType node) node.Range