Skip to content

Commit

Permalink
Consider selection range when collecting trivia.
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed Jun 3, 2022
1 parent a0da393 commit ae01ca3
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/Fantomas.Core.Tests/FormatAstTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let parseAndFormat fn sourceCode =
|> fst

let formattedCode =
CodeFormatter.FormatASTAsync(ast, [], fn sourceCode, config)
CodeFormatter.FormatASTAsync(ast, fn sourceCode, config)
|> Async.RunSynchronously
|> String.normalizeNewLine
|> fun s -> s.TrimEnd('\n')
Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core.Tests/FormattingSelectionOnlyTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ functionApplication
let ``only format trivia inside the selection`` () =
formatSelectionOnly
false
(mkSelection (5, 0) (6, 20))
(mkSelection (5, 0) (6, 10))
"""
let x = 0
Expand Down
1 change: 0 additions & 1 deletion src/Fantomas.Core.Tests/SynLongIdentTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ let ``backticks can be added from AST only scenarios`` () =

CodeFormatter.FormatASTAsync(
tree,
[],
None,
{ config with
StrictMode = true
Expand Down
9 changes: 4 additions & 5 deletions src/Fantomas.Core.Tests/TestHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ open NUnit.Framework
open FsCheck
open FsUnit
open FSharp.Compiler.Text
open FSharp.Compiler.Syntax
open FSharp.Compiler.Xml
open Fantomas.Core.FormatConfig
open Fantomas.Core

Expand Down Expand Up @@ -45,11 +43,12 @@ let formatSourceStringWithDefines defines (s: string) config =
let source = CodeFormatterImpl.getSourceText s
let! asts = CodeFormatterImpl.parse false source

let ast, defineCombination =
let ast =
Array.filter (fun (_, d: DefineCombination) -> List.sort d = List.sort defines) asts
|> Array.head
|> fst

return CodeFormatterImpl.formatWith (Some source) defineCombination ast config
return CodeFormatterImpl.formatWith (Some source) ast config None
}
|> Async.RunSynchronously

Expand All @@ -67,7 +66,7 @@ let isValidFSharpCode isFsiFile s =
|> Async.RunSynchronously

let formatAST a s c =
CodeFormatter.FormatASTAsync(a, [], s, c)
CodeFormatter.FormatASTAsync(a, s, c)
|> Async.RunSynchronously

let equal x =
Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core.Tests/TriviaTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ open Fantomas.Core.FormatConfig
let private toTrivia source =
let sourceText = CodeFormatterImpl.getSourceText source
let ast, _ = Fantomas.FCS.Parse.parseFile false sourceText []
Trivia.collectTrivia FormatConfig.Default sourceText ast
Trivia.collectTrivia FormatConfig.Default sourceText ast None

let private toTriviaWithDefines source =
let sourceText = CodeFormatterImpl.getSourceText source
Expand All @@ -24,7 +24,7 @@ let private toTriviaWithDefines source =
let defineCombinations = Defines.getDefineCombination hashDirectives

defineCombinations
|> List.map (fun dc -> dc, Trivia.collectTrivia FormatConfig.Default sourceText ast)
|> List.map (fun dc -> dc, Trivia.collectTrivia FormatConfig.Default sourceText ast None)
|> Map.ofList

[<Test>]
Expand Down
13 changes: 4 additions & 9 deletions src/Fantomas.Core/CodeFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@ open FSharp.Compiler.Syntax
[<Sealed>]
type CodeFormatter =
static member ParseAsync(isSignature, source) : Async<(ParsedInput * string list) array> =
async {
let! asts =
CodeFormatterImpl.getSourceText source
|> CodeFormatterImpl.parse isSignature

return asts
}
CodeFormatterImpl.getSourceText source
|> CodeFormatterImpl.parse isSignature

static member FormatASTAsync(ast: ParsedInput, defines: string list, source, config) : Async<string> =
static member FormatASTAsync(ast: ParsedInput, source, config) : Async<string> =
let sourceAndTokens = Option.map CodeFormatterImpl.getSourceText source

CodeFormatterImpl.formatAST ast defines sourceAndTokens config
CodeFormatterImpl.formatAST ast sourceAndTokens config None
|> async.Return

static member FormatDocumentAsync(isSignature, source, config) =
Expand Down
3 changes: 1 addition & 2 deletions src/Fantomas.Core/CodeFormatter.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ type CodeFormatter =
static member ParseAsync: isSignature: bool * source: string -> Async<(ParsedInput * string list) array>

/// Format an abstract syntax tree using an optional source for trivia processing
static member FormatASTAsync:
ast: ParsedInput * defines: string list * source: string option * config: FormatConfig -> Async<string>
static member FormatASTAsync: ast: ParsedInput * source: string option * config: FormatConfig -> Async<string>

/// Format a source string using given config
static member FormatDocumentAsync: isSignature: bool * source: string * config: FormatConfig -> Async<string>
Expand Down
15 changes: 10 additions & 5 deletions src/Fantomas.Core/CodeFormatterImpl.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,14 @@ let parse (isSignature: bool) (source: ISourceText) : Async<(ParsedInput * Defin
})
|> Async.Parallel

let formatWith (sourceText: ISourceText option) (defineCombination: DefineCombination) ast config =
let formatWith
(sourceText: ISourceText option)
(ast: ParsedInput)
(config: FormatConfig)
(selection: range option)
: string =
let formattedSourceCode =
let context = Context.Context.Create config sourceText defineCombination ast
let context = Context.Context.Create config sourceText ast selection

context
|> genParsedInput ASTContext.Default ast
Expand All @@ -72,7 +77,7 @@ let format (config: FormatConfig) (isSignature: bool) (source: ISourceText) : As
asts
|> Array.map (fun (ast', defineCombination) ->
async {
let formattedCode = formatWith (Some source) defineCombination ast' config
let formattedCode = formatWith (Some source) ast' config None
return (defineCombination, formattedCode)
})
|> Async.Parallel
Expand Down Expand Up @@ -117,5 +122,5 @@ Please raise an issue at https://fsprojects.github.io/fantomas-tools/#/fantomas/
let formatDocument config isSignature source = format config isSignature source

/// Format an abstract syntax tree using given config
let formatAST ast defines sourceText config =
formatWith sourceText defines ast config
let formatAST ast sourceText config selection =
formatWith sourceText ast config selection
4 changes: 2 additions & 2 deletions src/Fantomas.Core/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ type internal Context =
FileName = String.Empty
SourceText = None }

static member Create config (source: ISourceText option) (defineCombination: DefineCombination) (ast: ParsedInput) =
static member Create config (source: ISourceText option) (ast: ParsedInput) (selection: range option) =
let trivia, sourceText =
match source with
| Some source when not config.StrictMode -> Trivia.collectTrivia config source ast, Some source
| Some source when not config.StrictMode -> Trivia.collectTrivia config source ast selection, Some source
| _ -> [], None

let triviaByNodes =
Expand Down
2 changes: 1 addition & 1 deletion src/Fantomas.Core/Selection.fs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ let formatSelection
MaxLineLength = maxLineLength }

let selection =
CodeFormatterImpl.formatAST tree [] (Some sourceText) selectionConfig
CodeFormatterImpl.formatAST tree (Some sourceText) selectionConfig (Some selection)

return Some(selection.TrimEnd([| '\r'; '\n' |]))
}
40 changes: 33 additions & 7 deletions src/Fantomas.Core/Trivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ let private addTriviaToTriviaNode (startOfSourceCode: int) (triviaNodes: TriviaN
let internal collectTriviaFromDirectives
(source: ISourceText)
(directives: ConditionalDirectiveTrivia list)
(selection: range option)
: Trivia list =
directives
|> List.map (function
Expand All @@ -216,8 +217,16 @@ let internal collectTriviaFromDirectives

| ConditionalDirectiveTrivia.Else r -> { Item = Directive "#else"; Range = r }
| ConditionalDirectiveTrivia.EndIf r -> { Item = Directive "#endif"; Range = r })
|> fun trivia ->
match selection with
| None -> trivia
| Some selection -> List.filter (fun t -> RangeHelpers.rangeContainsRange selection t.Range) trivia

let internal collectTriviaFromCodeComments (source: ISourceText) (codeComments: CommentTrivia list) : Trivia list =
let internal collectTriviaFromCodeComments
(source: ISourceText)
(codeComments: CommentTrivia list)
(selection: range option)
: Trivia list =
codeComments
|> List.map (function
| CommentTrivia.BlockComment r ->
Expand All @@ -236,6 +245,10 @@ let internal collectTriviaFromCodeComments (source: ISourceText) (codeComments:
)

{ Item = item; Range = r })
|> fun trivia ->
match selection with
| None -> trivia
| Some selection -> List.filter (fun t -> RangeHelpers.rangeContainsRange selection t.Range) trivia

// TODO: optimize the range of which newlines are allowed in
// for a selection, the newlines should be found inside the selection
Expand All @@ -247,6 +260,7 @@ let internal collectTriviaFromBlankLines
(source: ISourceText)
(triviaNode: TriviaNodeAssigner)
(codeComments: CommentTrivia list)
(codeRange: range)
: Trivia list =
let fileIndex = triviaNode.Range.FileIndex

Expand Down Expand Up @@ -290,9 +304,10 @@ let internal collectTriviaFromBlankLines
}
)

let max = source.GetLineCount() - 1
let min = codeRange.StartLine - 1
let max = codeRange.EndLine - 1

(0, [ 0..max ])
(min, [ min..max ])
||> List.chooseState (fun count idx ->
if ignoreLines.Contains(idx + 1) then
0, None
Expand All @@ -317,7 +332,12 @@ let internal collectTriviaFromBlankLines
3. Merge trivia with triviaNodes
4. genTrivia should use ranges to identify what extra content should be added from what triviaNode
*)
let collectTrivia (config: FormatConfig) (source: ISourceText) (ast: ParsedInput) : TriviaNode list =
let collectTrivia
(config: FormatConfig)
(source: ISourceText)
(ast: ParsedInput)
(selection: range option)
: TriviaNode list =
let triviaNodesFromAST, directives, codeComments =
match ast with
| ParsedInput.ImplFile (ParsedImplFileInput (hds, mns, directives, codeComments)) ->
Expand All @@ -326,9 +346,15 @@ let collectTrivia (config: FormatConfig) (source: ISourceText) (ast: ParsedInput
sigAstToNode ast.FullRange mns, directives, codeComments

let trivia =
[ yield! collectTriviaFromDirectives source directives
yield! collectTriviaFromCodeComments source codeComments
yield! collectTriviaFromBlankLines config source triviaNodesFromAST codeComments ]
[ yield! collectTriviaFromDirectives source directives selection
yield! collectTriviaFromCodeComments source codeComments selection
yield!
collectTriviaFromBlankLines
config
source
triviaNodesFromAST
codeComments
(Option.defaultValue ast.FullRange selection) ]
|> List.sortBy (fun n -> n.Range.Start.Line, n.Range.Start.Column)

// TODO: do we still need this?
Expand Down
4 changes: 0 additions & 4 deletions src/Fantomas.Core/TriviaHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ open Fantomas.Core.TriviaTypes

[<RequireQualifiedAccess>]
module internal TriviaHelpers =
let findInRange (trivia: TriviaNode list) (range: Range) =
trivia
|> List.tryFind (fun t -> RangeHelpers.rangeContainsRange range t.Range)

let ``has content after after that matches``
(findTrivia: TriviaNode -> bool)
(contentAfter: TriviaContent -> bool)
Expand Down

0 comments on commit ae01ca3

Please sign in to comment.