From 33dfe680d17b885b7fee364a9a908109d9b5d1df Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Tue, 20 Apr 2021 19:50:55 +0200 Subject: [PATCH] Keep lambda at same line in multiline dotget. Fixes #1662. (#1663) --- src/Fantomas.Tests/DotGetTests.fs | 82 +++++++++++++++++++++++++++++++ src/Fantomas/CodePrinter.fs | 29 +++++++++++ src/Fantomas/SourceParser.fs | 6 +++ 3 files changed, 117 insertions(+) diff --git a/src/Fantomas.Tests/DotGetTests.fs b/src/Fantomas.Tests/DotGetTests.fs index a75ac7df96..29b79c0008 100644 --- a/src/Fantomas.Tests/DotGetTests.fs +++ b/src/Fantomas.Tests/DotGetTests.fs @@ -1125,3 +1125,85 @@ module Foo = () """ + +[] +let ``single line dotget lambda, followed by application`` () = + formatSourceString + false + """ +Foo(fun x -> x).Bar().Meh +""" + config + |> prepend newline + |> should + equal + """ +Foo(fun x -> x).Bar().Meh +""" + +[] +let ``multiline dotget lambda, followed by application, 1662`` () = + formatSourceString + false + """ +type Class() = + member this.``kk``() = + async { + mock + .Setup(fun m -> + m.CreateBlah + (It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Some mock) + .End + } + |> Async.StartImmediate +""" + config + |> prepend newline + |> should + equal + """ +type Class() = + member this.kk() = + async { + mock + .Setup(fun m -> + m.CreateBlah(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Some mock) + .End + } + |> Async.StartImmediate +""" + +[] +let ``multiline dotget lambda, followed by multiple applications`` () = + formatSourceString + false + """ +mock + .Setup(fun m -> + // some comment + m.CreateBlah + (It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Some mock) + .OrNot() + .End +""" + { config with MaxLineLength = 80 } + |> prepend newline + |> should + equal + """ +mock + .Setup(fun m -> + // some comment + m.CreateBlah( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + )) + .Returns(Some mock) + .OrNot() + .End +""" diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 52e53a04b6..22880ea406 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -1815,6 +1815,35 @@ and genExpr astContext synExpr ctx = +> !-(sprintf ".%s" s) +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (col sepSpace es (genExpr astContext)) + // Foo(fun x -> x).Bar().Meh + | DotGetAppDotGetAppParenLambda (e, px, appLids, es, lids) -> + let short = + genExpr astContext e + +> genExpr astContext px + +> genLidsWithDots appLids + +> col sepComma es (genExpr astContext) + +> genLidsWithDots lids + + let long = + let functionName = + match e with + | LongIdentPieces lids when (List.moreThanOne lids) -> genFunctionNameWithMultilineLids id lids + | TypeApp (LongIdentPieces lids, ts) when (List.moreThanOne lids) -> + genFunctionNameWithMultilineLids (genGenericTypeParameters astContext ts) lids + | _ -> genExpr astContext e + + functionName + +> indent + +> genExpr astContext px + +> sepNln + +> genLidsWithDotsAndNewlines appLids + +> col sepComma es (genExpr astContext) + +> sepNln + +> genLidsWithDotsAndNewlines lids + +> unindent + + fun ctx -> isShortExpression ctx.Config.MaxDotGetExpressionWidth short long ctx + // Foo().Bar | DotGetAppParen (e, px, lids) -> let shortAppExpr = diff --git a/src/Fantomas/SourceParser.fs b/src/Fantomas/SourceParser.fs index 8be6a72602..769291c755 100644 --- a/src/Fantomas/SourceParser.fs +++ b/src/Fantomas/SourceParser.fs @@ -995,6 +995,12 @@ let (|DotGetAppParen|_|) e = | DotGet (App (e, [ ConstExpr (SynConst.Unit, _) as px ]), lids) -> Some(e, px, lids) | _ -> None +let (|DotGetAppDotGetAppParenLambda|_|) (e: SynExpr) = + match e with + | DotGet (App (DotGet (App (e, [ Paren (_, SynExpr.Lambda _, _, _) as px ]), appLids), es), lids) -> + Some(e, px, appLids, es, lids) + | _ -> None + /// Gather series of application for line breaking let rec (|DotGetApp|_|) = function