From 848afb82dbfc4bc84bb00e4355ae943789603e18 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Fri, 4 Sep 2020 10:43:39 +0200 Subject: [PATCH] Limit range for arrow token trivia in desugared lambda. Fixes #1082. (#1085) --- src/Fantomas.Tests/PatternMatchingTests.fs | 29 ++++++++++++++++++++++ src/Fantomas/CodePrinter.fs | 15 ++++++++--- src/Fantomas/SourceParser.fs | 7 +++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/Fantomas.Tests/PatternMatchingTests.fs b/src/Fantomas.Tests/PatternMatchingTests.fs index df195f0cc5..f706a6573f 100644 --- a/src/Fantomas.Tests/PatternMatchingTests.fs +++ b/src/Fantomas.Tests/PatternMatchingTests.fs @@ -711,3 +711,32 @@ let (|AndExpr|_|) = | ListSplitPick "&&" chooser (e1, e2) -> Some(BoolExpr.And(e1, e2)) | _ -> None """ + +[] +let ``comment after arrow should not be duplicated, 1082`` () = + formatSourceString false """ +List.tryFind(fun { Type = t; Range = r } -> + match t with + | MainNode SynMemberDefn_Member + | MainNode SynMemberSig_Member -> // trying to get AST trivia + RangeHelpers.``range contains`` r rangeOfBindingAndRhs + + | Token(MEMBER, _) -> // trying to get token trivia + r.StartLine = rangeOfBindingAndRhs.StartLine + + | _ -> false + ) +""" config + |> prepend newline + |> should equal """ +List.tryFind (fun { Type = t; Range = r } -> + match t with + | MainNode SynMemberDefn_Member + | MainNode SynMemberSig_Member -> // trying to get AST trivia + RangeHelpers.``range contains`` r rangeOfBindingAndRhs + + | Token (MEMBER, _) -> // trying to get token trivia + r.StartLine = rangeOfBindingAndRhs.StartLine + + | _ -> false) +""" diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 638d77e123..faf95c6766 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -1312,15 +1312,22 @@ and genExpr astContext synExpr = | Paren(DesugaredLambda(cps, e)) -> fun (ctx: Context) -> let lastLineOnlyContainsParenthesis = lastLineOnlyContains [| ' ';'('|] ctx + + let arrowRange = + List.last cps + |> snd + |> fun lastPatRange -> + mkRange "arrow range" lastPatRange.End e.Range.Start + let hasLineCommentAfterArrow = - findTriviaTokenFromName RARROW synExpr.Range ctx + findTriviaTokenFromName RARROW arrowRange ctx |> Option.isSome let expr = sepOpenT -- "fun " - +> col sepSpace cps (genComplexPats astContext) - +> triviaAfterArrow synExpr.Range + +> col sepSpace cps (fst >> genComplexPats astContext) + +> triviaAfterArrow arrowRange +> ifElse hasLineCommentAfterArrow (genExpr astContext e) (ifElse lastLineOnlyContainsParenthesis (autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)) (autoNlnIfExpressionExceedsPageWidth (genExpr astContext e))) @@ -1329,7 +1336,7 @@ and genExpr astContext synExpr = expr ctx | DesugaredLambda(cps, e) -> - !- "fun " +> col sepSpace cps (genComplexPats astContext) +> sepArrow + !- "fun " +> col sepSpace cps (fst >> genComplexPats astContext) +> sepArrow +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e) | Paren(Lambda(e, sps)) -> fun (ctx: Context) -> diff --git a/src/Fantomas/SourceParser.fs b/src/Fantomas/SourceParser.fs index c694232730..f885327003 100644 --- a/src/Fantomas/SourceParser.fs +++ b/src/Fantomas/SourceParser.fs @@ -1098,10 +1098,15 @@ let rec transformPatterns ss = function List.map loop sps |> ComplexPats | SPSTyped(sp, t) -> ComplexTyped(transformPatterns ss sp, t) +let getSynSimplePatsRange = + function + | SynSimplePats.SimplePats(_,r) + | SynSimplePats.Typed(_, _,r) -> r + /// Process compiler-generated matches in an appropriate way let (|DesugaredLambda|_|) = function | Lambda(DesugaredMatch(ss, e), spss) -> - Some(List.map (transformPatterns ss) spss, e) + Some(List.map (fun sp -> transformPatterns ss sp, getSynSimplePatsRange sp) spss, e) | _ -> None // Type definitions