diff --git a/src/Fantomas.Tests/SynConstTests.fs b/src/Fantomas.Tests/SynConstTests.fs index 4834c786e3..ec6ab3af5d 100644 --- a/src/Fantomas.Tests/SynConstTests.fs +++ b/src/Fantomas.Tests/SynConstTests.fs @@ -308,3 +308,109 @@ let controlEscapes = "\a \b \f \v" """let hexEscape = "\x00" let controlEscapes = "\a \b \f \v" """ + +[] +let ``trivia after SynConst.Boolean, 1518`` () = + formatSourceString + false + """ + match ast with + | ParsedInput.SigFile _input -> + // There is not much to explore in signature files + true + | ParsedInput.ImplFile input -> validateImplFileInput input + + match t with + | TTuple _ -> not node.IsEmpty + | TFun _ -> true // Fun is grouped by brackets inside 'genType astContext true t' + | _ -> false + + let condition e = + match e with + | ElIf _ + | SynExpr.Lambda _ -> true + | _ -> false // "if .. then .. else" have precedence over "," + + let x = 9 +""" + config + |> prepend newline + |> should + equal + """ +match ast with +| ParsedInput.SigFile _input -> + // There is not much to explore in signature files + true +| ParsedInput.ImplFile input -> validateImplFileInput input + +match t with +| TTuple _ -> not node.IsEmpty +| TFun _ -> true // Fun is grouped by brackets inside 'genType astContext true t' +| _ -> false + +let condition e = + match e with + | ElIf _ + | SynExpr.Lambda _ -> true + | _ -> false // "if .. then .. else" have precedence over "," + +let x = 9 +""" + +[] +let ``trivia after SynConst.Char`` () = + formatSourceString + false + """ +let c = 'r' // meh +let x = 1 +""" + config + |> prepend newline + |> should + equal + """ +let c = 'r' // meh +let x = 1 +""" + +[] +let ``trivia after SynConst.Bytes`` () = + formatSourceString + false + """ +let bytes = "meh"B // meh +let x = 1 +""" + config + |> prepend newline + |> should + equal + """ +let bytes = "meh"B // meh +let x = 1 +""" + +[] +let ``trivia after SynConst.String, 1518`` () = + formatSourceString + false + " + let source = \"\"\"printfn foo + +printfn bar\"\"\" // difference is the 4 spaces on line 188 + + let x = 9 +" + config + |> prepend newline + |> should + equal + " +let source = \"\"\"printfn foo + +printfn bar\"\"\" // difference is the 4 spaces on line 188 + +let x = 9 +" diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 978247a6a0..7e0ef01c22 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -5173,7 +5173,9 @@ and genConst (c: SynConst) (r: Range) = +> !- ")" +> leaveNodeTokenByName r RPAREN |> genTriviaFor SynConst_Unit r - | SynConst.Bool (b) -> !-(if b then "true" else "false") + | SynConst.Bool (b) -> + !-(if b then "true" else "false") + |> genTriviaFor SynConst_Bool r | SynConst.Byte _ | SynConst.SByte _ | SynConst.Int16 _ @@ -5218,18 +5220,29 @@ and genConst (c: SynConst) (r: Range) = <| ctx | SynConst.Char (c) -> fun (ctx: Context) -> - let charContentFromTrivia = - TriviaHelpers.``get CharContent`` r ctx.TriviaMainNodes + let tn = + Map.tryFindOrEmptyList SynConst_Char ctx.TriviaMainNodes + |> List.tryFind (fun t -> RangeHelpers.rangeEq t.Range r) let expr = - match charContentFromTrivia with - | Some content -> !-content + match tn with + | Some ({ ContentItself = Some (CharContent (content)) } as tn) -> + printContentBefore tn -- content + +> printContentAfter tn + | Some tn -> + let escapedChar = Char.escape c + + printContentBefore tn + -- (sprintf "\'%s\'" escapedChar) + +> printContentAfter tn | None -> let escapedChar = Char.escape c !-(sprintf "\'%s\'" escapedChar) expr ctx - | SynConst.Bytes (bytes, r) -> genConstBytes bytes r + | SynConst.Bytes (bytes, r) -> + genConstBytes bytes r + |> genTriviaFor SynConst_Bytes r | SynConst.Measure (c, m) -> let measure = match m with diff --git a/src/Fantomas/TokenParser.fs b/src/Fantomas/TokenParser.fs index 633023253c..e40b00ac7e 100644 --- a/src/Fantomas/TokenParser.fs +++ b/src/Fantomas/TokenParser.fs @@ -41,12 +41,14 @@ let rec private tokenizeLine (tokenizer: FSharpLineTokenizer) sourceCodeLines st let extraToken = { TokenInfo = extraTokenInfo LineNumber = lineNumber - Content = getTokenText sourceCodeLines lineNumber extraTokenInfo } + Content = getTokenText sourceCodeLines lineNumber extraTokenInfo + Index = 0 } let token = { TokenInfo = tok LineNumber = lineNumber - Content = getTokenText sourceCodeLines lineNumber tok } + Content = getTokenText sourceCodeLines lineNumber tok + Index = 0 } tokenizeLine tokenizer sourceCodeLines state lineNumber (token :: extraToken :: tokens) @@ -54,7 +56,8 @@ let rec private tokenizeLine (tokenizer: FSharpLineTokenizer) sourceCodeLines st let token : Token = { TokenInfo = tok LineNumber = lineNumber - Content = getTokenText sourceCodeLines lineNumber tok } + Content = getTokenText sourceCodeLines lineNumber tok + Index = 0 } // Tokenize the rest, in the new state tokenizeLine tokenizer sourceCodeLines state lineNumber (token :: tokens) @@ -83,6 +86,7 @@ let private createHashToken lineNumber content offset = { LineNumber = lineNumber Content = content + Index = 0 TokenInfo = { TokenName = "HASH_IF" LeftColumn = left @@ -337,6 +341,7 @@ and tokenize defines (hashTokens: Token list) (content: string) : Token list = tokens combined + |> List.mapi (fun idx t -> { t with Index = idx }) let getDefinesWords (tokens: Token list) = tokens @@ -672,54 +677,26 @@ let rec private getTriviaFromTokensThemSelves foundTrivia = match tokens with - | (NoCommentToken nct) :: WhiteSpaceToken _ :: (LineComments (commentTokens, nextTokens)) -> - let comment = - let commentText = collectComment commentTokens - let firstCommentToken = List.head commentTokens - - (if nct.LineNumber < firstCommentToken.LineNumber then - LineCommentOnSingleLine commentText - else - LineCommentAfterSourceCode commentText) - |> Comment - - let range = - let headToken = List.head commentTokens - let lastToken = List.tryLast commentTokens - getRangeBetween mkRange headToken (Option.defaultValue headToken lastToken) - - let info = - Trivia.Create comment range - |> List.appendItem foundTrivia - - getTriviaFromTokensThemSelves mkRange allTokens (nct :: nextTokens) info - | (NoCommentToken nct) :: (LineComments (commentTokens, nextTokens)) -> - let comment = - let commentText = collectComment commentTokens - let firstCommentToken = List.head commentTokens - - (if nct.LineNumber < firstCommentToken.LineNumber - || (nct.TokenInfo.Tag = whiteSpaceTag - && firstCommentToken.LineNumber = nct.LineNumber) then - LineCommentOnSingleLine commentText - else - LineCommentAfterSourceCode commentText) - |> Comment - - let range = - let headToken = List.head commentTokens - let lastToken = List.tryLast commentTokens - getRangeBetween mkRange headToken (Option.defaultValue headToken lastToken) - - let info = - Trivia.Create comment range - |> List.appendItem foundTrivia + | LineComments (({ Index = headIndex + LineNumber = headLineNumber } :: _ as commentTokens), + nextTokens) -> + let prevToken = List.tryItem (headIndex - 1) allTokens + let prevButOneToken = List.tryItem (headIndex - 2) allTokens + + let commentType = + match prevButOneToken, prevToken with + | Some ({ LineNumber = ncln }), Some (WhiteSpaceToken _) -> + if ncln = headLineNumber then + LineCommentAfterSourceCode + else + LineCommentOnSingleLine + | Some ({ LineNumber = l1 }), Some ({ LineNumber = l2 }) when (headLineNumber = l1 && headLineNumber = l2) -> + LineCommentAfterSourceCode + | _ -> LineCommentOnSingleLine - getTriviaFromTokensThemSelves mkRange allTokens (nct :: nextTokens) info - | LineComments (commentTokens, nextTokens) -> let comment = collectComment commentTokens - |> LineCommentOnSingleLine + |> commentType |> Comment let range = diff --git a/src/Fantomas/TriviaHelpers.fs b/src/Fantomas/TriviaHelpers.fs index 55b64aef50..e0bb06ac57 100644 --- a/src/Fantomas/TriviaHelpers.fs +++ b/src/Fantomas/TriviaHelpers.fs @@ -125,15 +125,5 @@ module internal TriviaHelpers = | Some (StringContent sc) -> String.isMultiline sc | _ -> false - RangeHelpers.rangeEq tn.Range range && contentItSelfIsMultilineString ()) - - let ``get CharContent`` range (nodes: Map) = - Map.tryFindOrEmptyList SynConst_Char nodes - |> List.tryFind (fun t -> RangeHelpers.rangeEq t.Range range) - |> Option.bind - (fun tv -> - match tv.ContentItself with - | Some (CharContent c) -> Some c - | _ -> None) diff --git a/src/Fantomas/TriviaTypes.fs b/src/Fantomas/TriviaTypes.fs index 7a2991700f..22b4905386 100644 --- a/src/Fantomas/TriviaTypes.fs +++ b/src/Fantomas/TriviaTypes.fs @@ -56,7 +56,8 @@ type FsTokenType = type Token = { TokenInfo: FSharpTokenInfo LineNumber: int - Content: string } + Content: string + Index: int } type Comment = | LineCommentAfterSourceCode of comment: string