From 50f5ffd4596587bbee91a4623a2ac0da4a07f6f0 Mon Sep 17 00:00:00 2001 From: Retheesh Erathu Date: Tue, 19 Oct 2021 06:32:52 +0200 Subject: [PATCH] Respect column info for multi-line comments Fixes https://github.com/fsprojects/fantomas/issues/1223 --- src/Fantomas.Tests/CommentTests.fs | 79 +++++++++++++++++++++- src/Fantomas.Tests/LambdaTests.fs | 2 +- src/Fantomas.Tests/PatternMatchingTests.fs | 2 +- src/Fantomas.Tests/TokenParserTests.fs | 4 +- src/Fantomas.Tests/TriviaTests.fs | 18 ++--- src/Fantomas/Context.fs | 41 +++++++++-- src/Fantomas/TokenParser.fs | 2 +- src/Fantomas/Trivia.fs | 25 +++++-- src/Fantomas/TriviaTypes.fs | 2 +- 9 files changed, 148 insertions(+), 27 deletions(-) diff --git a/src/Fantomas.Tests/CommentTests.fs b/src/Fantomas.Tests/CommentTests.fs index 48a6f26acc..d44d6c6fc1 100644 --- a/src/Fantomas.Tests/CommentTests.fs +++ b/src/Fantomas.Tests/CommentTests.fs @@ -1647,4 +1647,81 @@ type TorDirectory = // comment } } -""" \ No newline at end of file +""" + +[] +let ``should not move the starting point of a multi-line comment, 1223`` () = + formatSourceString + false + """ +module Foo = + let private GetConfirmedEtherBalanceInternal (web3: Web3) (publicAddress: string): Async = + async { + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 +(* + if (Config.DebugLog) then + Infrastructure.LogError (SPrintF2 "Last block number and last confirmed block number: %s: %s" + (latestBlock.Value.ToString()) (blockForConfirmationReference.BlockNumber.Value.ToString())) + *) + return blockForConfirmationReference + } +""" + config + |> prepend newline + |> should + equal + """ +module Foo = + let private GetConfirmedEtherBalanceInternal (web3: Web3) (publicAddress: string) : Async = + async { + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 +(* + if (Config.DebugLog) then + Infrastructure.LogError (SPrintF2 "Last block number and last confirmed block number: %s: %s" + (latestBlock.Value.ToString()) (blockForConfirmationReference.BlockNumber.Value.ToString())) + *) + return blockForConfirmationReference + } +""" + +[] +let ``should not move the starting point of a multi-line comment (2), 1223`` () = + formatSourceString + false + """ +module Foo = + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 +(* test *) + return blockForConfirmationReference +""" + config + |> prepend newline + |> should + equal + """ +module Foo = + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 +(* test *) + return blockForConfirmationReference +""" + +[] +let ``should not move the starting point of a multi-line comment (3), 1223`` () = + formatSourceString + false + """ +module Foo = + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 + (* test *) + return blockForConfirmationReference +""" + config + |> prepend newline + |> should + equal + """ +module Foo = + let! blockForConfirmationReference = GetBlockToCheckForConfirmedBalance web3 + (* test *) + return blockForConfirmationReference +""" diff --git a/src/Fantomas.Tests/LambdaTests.fs b/src/Fantomas.Tests/LambdaTests.fs index 17a181ec1e..c9dfb48d36 100644 --- a/src/Fantomas.Tests/LambdaTests.fs +++ b/src/Fantomas.Tests/LambdaTests.fs @@ -793,7 +793,7 @@ let ``comment between opening parenthesis and lambda, 1190`` () = equal """ ( -(* comment before gets swallowed *) + (* comment before gets swallowed *) fun x -> x * 42) (fun x -> diff --git a/src/Fantomas.Tests/PatternMatchingTests.fs b/src/Fantomas.Tests/PatternMatchingTests.fs index d09df0ca75..ed05a9f262 100644 --- a/src/Fantomas.Tests/PatternMatchingTests.fs +++ b/src/Fantomas.Tests/PatternMatchingTests.fs @@ -1669,7 +1669,7 @@ let GenApp (cenv: cenv) cgbuf eenv (f, fty, tyargs, curriedArgs, m) sequel = arityInfo.Length = curriedArgs.Length) && - (* no tailcall out of exception handler, etc. *) + (* no tailcall out of exception handler, etc. *) (match sequelIgnoringEndScopesAndDiscard sequel with | Return | ReturnVoid -> true diff --git a/src/Fantomas.Tests/TokenParserTests.fs b/src/Fantomas.Tests/TokenParserTests.fs index e73791940c..ad2b8f9379 100644 --- a/src/Fantomas.Tests/TokenParserTests.fs +++ b/src/Fantomas.Tests/TokenParserTests.fs @@ -175,7 +175,7 @@ let ``single line block comment should be found in tokens`` () = let triviaNodes = getTriviaFromTokens tokens match List.tryLast triviaNodes with - | Some { Item = Comment (BlockComment (blockComment, _, _)) } -> blockComment == "(* not fonz *)" + | Some { Item = Comment (BlockComment (blockComment, _, _, _)) } -> blockComment == "(* not fonz *)" | _ -> failwith "expected block comment" [] @@ -197,7 +197,7 @@ let ``multi line block comment should be found in tokens`` () = |> String.normalizeNewLine match triviaNodes with - | [ { Item = Comment (BlockComment (blockComment, _, _)) + | [ { Item = Comment (BlockComment (blockComment, _, _, _)) Range = range } ] -> blockComment == expectedComment range.StartLine == 2 diff --git a/src/Fantomas.Tests/TriviaTests.fs b/src/Fantomas.Tests/TriviaTests.fs index eded38aeb9..4522a9b24f 100644 --- a/src/Fantomas.Tests/TriviaTests.fs +++ b/src/Fantomas.Tests/TriviaTests.fs @@ -149,7 +149,7 @@ let ``block comment added to trivia`` () = let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (comment, _, _)) ] } ] -> comment == "(* meh *)" + | [ { ContentBefore = [ Comment (BlockComment (comment, _, _, _)) ] } ] -> comment == "(* meh *)" | _ -> failwith "Expected block comment" [] @@ -162,7 +162,7 @@ let a = b let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (comment, _, true)) ] } ] -> comment == "(* meh *)" + | [ { ContentBefore = [ Comment (BlockComment (comment, _, true, _)) ] } ] -> comment == "(* meh *)" | _ -> failwith "Expected block comment" [] @@ -174,7 +174,7 @@ let ``block comment on newline EOF added to trivia`` () = let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentAfter = [ Comment (BlockComment (comment, true, _)) ] } ] -> comment == "(* meh *)" + | [ { ContentAfter = [ Comment (BlockComment (comment, true, _, _)) ] } ] -> comment == "(* meh *)" | _ -> failwith "Expected block comment" [] @@ -184,7 +184,7 @@ let ``block comment on EOF added to trivia`` () = let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentAfter = [ Comment (BlockComment (comment, _, _)) ] } ] -> comment == "(* meh *)" + | [ { ContentAfter = [ Comment (BlockComment (comment, _, _, _)) ] } ] -> comment == "(* meh *)" | _ -> failwith "Expected block comment" [] @@ -197,7 +197,7 @@ let a = c + d let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (comment, _, true)) ] } ] -> comment == "(* (* meh *) *)" + | [ { ContentBefore = [ Comment (BlockComment (comment, _, true, _)) ] } ] -> comment == "(* (* meh *) *)" | _ -> failwith "Expected block comment" @@ -211,7 +211,7 @@ let a = 9 let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (comment, _, true)) ] } ] -> comment == "(* // meh *)" + | [ { ContentBefore = [ Comment (BlockComment (comment, _, true, _)) ] } ] -> comment == "(* // meh *)" | _ -> failwith "Expected block comment" @@ -231,7 +231,7 @@ bla *)""" |> String.normalizeNewLine match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (comment, _, true)) ] } ] -> comment == expectedComment + | [ { ContentBefore = [ Comment (BlockComment (comment, _, true, _)) ] } ] -> comment == expectedComment | _ -> failwith "Expected block comment" @@ -247,7 +247,7 @@ x let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (combinedComment, _, true)) ] } ] -> + | [ { ContentBefore = [ Comment (BlockComment (combinedComment, _, true, _)) ] } ] -> combinedComment == "(* foo *)\n(* bar *)" | _ -> Assert.Fail(sprintf "Unexpected trivia %A" triviaNodes) @@ -278,7 +278,7 @@ MEH let triviaNodes = toTrivia source |> List.head match triviaNodes with - | [ { ContentBefore = [ Comment (BlockComment (c, _, true)) ] } ] -> c == (String.normalizeNewLine comment) + | [ { ContentBefore = [ Comment (BlockComment (c, _, true, _)) ] } ] -> c == (String.normalizeNewLine comment) | _ -> failwith "Expected block comment" [] diff --git a/src/Fantomas/Context.fs b/src/Fantomas/Context.fs index 83cc4f952a..a2ad3321d8 100644 --- a/src/Fantomas/Context.fs +++ b/src/Fantomas/Context.fs @@ -1170,11 +1170,42 @@ let internal printTriviaContent (c: TriviaContent) (ctx: Context) = sprintf "%s%s" (if addSpace then " " else String.empty) s writerEvent (WriteBeforeNewline comment) - | Comment (BlockComment (s, before, after)) -> - ifElse (before && addNewline) sepNlnForTrivia sepNone - +> sepSpace - -- s - +> sepSpace + | Comment (BlockComment (blockComment, before, after, commentRange)) -> + let printAtZeroIndent (f: Context -> Context) ctx = + let writerModel = ctx.WriterModel + let oldIndent = writerModel.Indent + let oldColumn = writerModel.AtColumn + + (writerEvent (SetAtColumn 0) + >> writerEvent (SetIndent 0) + >> f + >> writerEvent (RestoreAtColumn oldColumn) + >> writerEvent (RestoreIndent oldIndent)) + ctx + + let printComment = + if before && addNewline then + (String.replicate (commentRange.StartColumn) " ") + else + String.empty + + let printNewLn = + if before && addNewline then + "\n" + else + String.empty + + let comment = + sprintf "%s%s%s" printNewLn printComment blockComment + + ifElse + (before && addNewline) + (printAtZeroIndent (writerEvent (Write comment))) + (printAtZeroIndent ( + sepSpace + +> writerEvent (Write comment) + +> sepSpace + )) +> ifElse after sepNlnForTrivia sepNone | Comment (LineCommentOnSingleLine (s, commentRange)) -> (ifElse addNewline sepNlnForTrivia sepNone) diff --git a/src/Fantomas/TokenParser.fs b/src/Fantomas/TokenParser.fs index f861b16161..1b46c56e18 100644 --- a/src/Fantomas/TokenParser.fs +++ b/src/Fantomas/TokenParser.fs @@ -949,7 +949,7 @@ let rec private getTriviaFromTokensThemSelves getRangeBetween mkRange headToken (Option.defaultValue headToken lastToken) let info = - Trivia.Create(Comment(BlockComment(comment, false, false))) range + Trivia.Create(Comment(BlockComment(comment, false, false, range))) range |> List.prependItem foundTrivia getTriviaFromTokensThemSelves mkRange lastButOne lastToken rest info diff --git a/src/Fantomas/Trivia.fs b/src/Fantomas/Trivia.fs index 73a7cf7c71..d142982367 100644 --- a/src/Fantomas/Trivia.fs +++ b/src/Fantomas/Trivia.fs @@ -297,7 +297,7 @@ let private addTriviaToTriviaNode (fun tn -> tn.ContentAfter.Add(Comment(LineCommentOnSingleLine(comment, range)))) triviaNodes - | { Item = Comment (BlockComment (comment, _, _)) + | { Item = Comment (BlockComment (comment, _, _, _)) Range = range } -> let nodeAfter = findNodeAfterLineAndColumn triviaNodes range.StartLine range.StartColumn @@ -311,25 +311,38 @@ let private addTriviaToTriviaNode && na.Range.StartLine > range.EndLine) -> Some na - |> updateTriviaNode (fun tn -> tn.ContentBefore.Add(Comment(BlockComment(comment, true, true)))) triviaNodes + |> updateTriviaNode + (fun tn -> tn.ContentBefore.Add(Comment(BlockComment(comment, true, true, range)))) + triviaNodes | Some n, _ when n.Range.EndLine = range.StartLine -> Some n |> updateTriviaNode - (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, false, false)))) + (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, false, false, range)))) + triviaNodes + | Some nb, Some n when (nb.Range.EndLine > range.StartLine) -> + Some n + |> updateTriviaNode + (fun tn -> + let newline = tn.Range.StartLine > range.EndLine + tn.ContentBefore.Add(Comment(BlockComment(comment, true, newline, range)))) triviaNodes | _, Some n -> Some n |> updateTriviaNode (fun tn -> let newline = tn.Range.StartLine > range.EndLine - tn.ContentBefore.Add(Comment(BlockComment(comment, false, newline)))) + tn.ContentBefore.Add(Comment(BlockComment(comment, false, newline, range)))) triviaNodes | Some _, _ when (commentIsAfterLastTriviaNode triviaNodes range) -> findLastNode triviaNodes - |> updateTriviaNode (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, true, false)))) triviaNodes + |> updateTriviaNode + (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, true, false, range)))) + triviaNodes | Some n, _ -> Some n - |> updateTriviaNode (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, true, false)))) triviaNodes + |> updateTriviaNode + (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, true, false, range)))) + triviaNodes | None, None -> triviaNodes | { Item = Comment (LineCommentAfterSourceCode _ as comment) diff --git a/src/Fantomas/TriviaTypes.fs b/src/Fantomas/TriviaTypes.fs index f3793f1863..efdc503910 100644 --- a/src/Fantomas/TriviaTypes.fs +++ b/src/Fantomas/TriviaTypes.fs @@ -62,7 +62,7 @@ type Token = type Comment = | LineCommentAfterSourceCode of comment: string | LineCommentOnSingleLine of comment: string * range - | BlockComment of string * newlineBefore: bool * newlineAfter: bool + | BlockComment of string * newlineBefore: bool * newlineAfter: bool * range (* LineComment Examples