Skip to content

Commit

Permalink
Revisit trivia type names.
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed Jun 15, 2022
1 parent 748e658 commit 5fd1a7f
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 205 deletions.
256 changes: 123 additions & 133 deletions src/Fantomas.Core/AstTransformer.fs

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions src/Fantomas.Core/AstTransformer.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ val astToNode:
range: range ->
hds: FSharp.Compiler.Syntax.ParsedHashDirective list ->
mdls: FSharp.Compiler.Syntax.SynModuleOrNamespace list ->
TriviaTypes.TriviaNodeAssigner
TriviaTypes.TriviaNode

val sigAstToNode:
range: range -> ast: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig list -> TriviaTypes.TriviaNodeAssigner
val sigAstToNode: range: range -> ast: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig list -> TriviaTypes.TriviaNode
1 change: 0 additions & 1 deletion src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5728,7 +5728,6 @@ and genSynStaticOptimizationConstraint
!- " when "
+> col sepSpace constraints (genConstraint astContext)

// TODO: we do a double look in this case, both before and after
and genTriviaFor (mainNodeName: FsAstType) (range: Range) f ctx =
(enterNodeFor mainNodeName range
+> f
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 @@ -10,7 +10,7 @@ open Fantomas.Core.TriviaTypes
open Fantomas.Core.AstTransformer
open Fantomas.Core.Trivia

let private findNode (maxLineLength: int) (selection: range) (node: TriviaNodeAssigner) : TriviaNodeAssigner option =
let private findNode (maxLineLength: int) (selection: range) (node: TriviaNode) : TriviaNode option =
let isExactSelection =
selection.StartLine = node.Range.StartLine
&& selection.StartColumn = node.Range.StartColumn
Expand Down
57 changes: 22 additions & 35 deletions src/Fantomas.Core/Trivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ open Fantomas.Core.AstTransformer
open Fantomas.Core.TriviaTypes
open Fantomas.Core.FormatConfig

let findFirstNodeAfterLine (nodes: TriviaNodeAssigner list) (lineNumber: int) : TriviaNodeAssigner option =
let findFirstNodeAfterLine (nodes: TriviaNode list) (lineNumber: int) : TriviaNode option =
nodes
|> List.tryFind (fun tn -> tn.Range.StartLine > lineNumber)

let findLastNodeOnLine (nodes: TriviaNodeAssigner list) lineNumber : TriviaNodeAssigner option =
let findLastNodeOnLine (nodes: TriviaNode list) lineNumber : TriviaNode option =
nodes
|> List.filter (fun tn -> tn.Range.EndLine = lineNumber)
|> List.sortByDescending (fun tn -> tn.Range.EndColumn, tn.Range.StartColumn)
Expand All @@ -31,29 +31,29 @@ let findLastNodeOnLine (nodes: TriviaNodeAssigner list) lineNumber : TriviaNodeA
| h :: _ -> Some h
| [] -> None

let findLastNode (nodes: TriviaNodeAssigner list) : TriviaNodeAssigner option =
let findLastNode (nodes: TriviaNode list) : TriviaNode option =
match nodes with
| [] -> None
| nodes ->
nodes
|> List.maxBy (fun tn -> tn.Range.EndLine)
|> Some

let findNodeBeforeLineAndColumn (nodes: TriviaNodeAssigner seq) line column =
let findNodeBeforeLineAndColumn (nodes: TriviaNode seq) line column =
nodes
|> Seq.tryFindBack (fun tn ->
let range = tn.Range

range.StartLine <= line
&& range.StartColumn <= column)

let findNodeBeforeLineFromStart (nodes: TriviaNodeAssigner list) line =
let findNodeBeforeLineFromStart (nodes: TriviaNode list) line =
nodes
|> List.filter (fun tn -> tn.Range.EndLine < line)
|> List.sortByDescending (fun tn -> tn.Range.EndLine, -tn.Range.StartColumn)
|> List.tryFind (fun tn -> tn.Range.StartLine < line)

let findNodeAfterLineAndColumn (nodes: TriviaNodeAssigner seq) line column =
let findNodeAfterLineAndColumn (nodes: TriviaNode seq) line column =
nodes
|> Seq.tryFind (fun tn ->
let range = tn.Range
Expand All @@ -62,15 +62,15 @@ let findNodeAfterLineAndColumn (nodes: TriviaNodeAssigner seq) line column =
|| (range.StartLine = line
&& range.StartColumn > column))

let commentIsAfterLastTriviaNode (triviaNodes: TriviaNodeAssigner list) (range: Range) =
let commentIsAfterLastTriviaNode (triviaNodes: TriviaNode list) (range: Range) =
let hasNoNodesAfterRange =
triviaNodes
|> Seq.exists (fun tn -> tn.Range.EndLine > range.StartLine)
|> not

hasNoNodesAfterRange

// let updateTriviaNode (lens: TriviaNodeAssigner -> unit) (triviaNodes: TriviaNodeAssigner list) triviaNode =
// let updateTriviaNode (lens: TriviaNode -> unit) (triviaNodes: TriviaNode list) triviaNode =
// match triviaNode with
// | Some tNode ->
// // There are situations where the same range can be linked to multiple different AST nodes.
Expand All @@ -85,27 +85,14 @@ let commentIsAfterLastTriviaNode (triviaNodes: TriviaNodeAssigner list) (range:
// triviaNodes
// | None -> triviaNodes

let addAllTriviaAsContentAfter (trivia: Trivia list) (singleNode: TriviaNodeAssigner) =
let contentAfter =
trivia
|> List.skipWhile (fun tn -> tn.Item = Newline) // skip leading newlines
|> List.map (fun tn -> tn.Item)

{ Type = singleNode.Type
Range = singleNode.Range
ContentBefore = []
ContentItself = None
ContentAfter = contentAfter }
|> List.singleton

let printTriviaNode (node: TriviaNodeAssigner) : unit =
let rec visit (level: int) (node: TriviaNodeAssigner) =
let printTriviaNode (node: TriviaNode) : unit =
let rec visit (level: int) (node: TriviaNode) =
printfn "%s%A: %A" ("".PadRight(level * 2)) node.Type node.Range
Array.iter (visit (level + 1)) node.Children

visit 0 node

let rec findNodeWhereRangeFitsIn (root: TriviaNodeAssigner) (range: range) : TriviaNodeAssigner option =
let rec findNodeWhereRangeFitsIn (root: TriviaNode) (range: range) : TriviaNode option =
let doesSelectionFitInNode = RangeHelpers.rangeContainsRange root.Range range

if not doesSelectionFitInNode then
Expand All @@ -121,7 +108,7 @@ let rec findNodeWhereRangeFitsIn (root: TriviaNodeAssigner) (range: range) : Tri
| Some betterChild -> Some betterChild
| None -> Some root

// let addTriviaToTriviaNode (startOfSourceCode: int) (triviaNodes: TriviaNodeAssigner list) trivia = triviaNodes
// let addTriviaToTriviaNode (startOfSourceCode: int) (triviaNodes: TriviaNode list) trivia = triviaNodes
// match trivia with
// | { Item = Comment (LineCommentOnSingleLine _ as comment)
// Range = range } ->
Expand Down Expand Up @@ -210,12 +197,12 @@ let rec findNodeWhereRangeFitsIn (root: TriviaNodeAssigner) (range: range) : Tri
//
// | _ -> triviaNodes

// let triviaNodeIsNotEmpty (triviaNode: TriviaNodeAssigner) =
// let triviaNodeIsNotEmpty (triviaNode: TriviaNode) =
// not (Seq.isEmpty triviaNode.ContentAfter)
// || not (Seq.isEmpty triviaNode.ContentBefore)
// || Option.isSome triviaNode.ContentItself
//
// let transformNonEmptyNodes (nodes: TriviaNodeAssigner list) : TriviaNode list =
// let transformNonEmptyNodes (nodes: TriviaNode list) : TriviaNode list =
// nodes
// |> List.choose (fun tn ->
// if triviaNodeIsNotEmpty tn then
Expand Down Expand Up @@ -291,7 +278,7 @@ let internal collectTriviaFromCodeComments
let internal collectTriviaFromBlankLines
(config: FormatConfig)
(source: ISourceText)
(triviaNode: TriviaNodeAssigner)
(triviaNode: TriviaNode)
(codeComments: CommentTrivia list)
(codeRange: range)
: Trivia list =
Expand All @@ -308,7 +295,7 @@ let internal collectTriviaFromBlankLines
[ r.StartLine .. r.EndLine ]

let multilineStringsLines =
let rec visit (node: TriviaNodeAssigner) (finalContinuation: int list -> int list) =
let rec visit (node: TriviaNode) (finalContinuation: int list -> int list) =
let continuations: ((int list -> int list) -> int list) list =
Array.toList node.Children |> List.map visit

Expand Down Expand Up @@ -365,7 +352,7 @@ let internal collectTriviaFromBlankLines

/// The trivia is not a part of the tree
/// Either assign it on top of below the root node
let triviaBeforeOrAfterEntireTree (rootNode: TriviaNodeAssigner) (trivia: Trivia) : TriviaInstruction =
let triviaBeforeOrAfterEntireTree (rootNode: TriviaNode) (trivia: Trivia) : TriviaInstruction =
let isBefore = trivia.Range.EndLine < rootNode.Range.StartLine

let trivia =
Expand All @@ -381,7 +368,7 @@ let triviaBeforeOrAfterEntireTree (rootNode: TriviaNodeAssigner) (trivia: Trivia

/// Try to put the trivia on top of the closest node
/// If that didn't work put it after the last node
let simpleTriviaToTriviaInstruction (containerNode: TriviaNodeAssigner) (trivia: Trivia) : TriviaInstruction option =
let simpleTriviaToTriviaInstruction (containerNode: TriviaNode) (trivia: Trivia) : TriviaInstruction option =
containerNode.Children
|> Array.tryFind (fun node -> node.Range.StartLine > trivia.Range.StartLine)
|> Option.map (fun node ->
Expand All @@ -399,12 +386,12 @@ let simpleTriviaToTriviaInstruction (containerNode: TriviaNodeAssigner) (trivia:

/// Try and find the smallest possible node
let lineCommentAfterSourceCodeToTriviaInstruction
(containerNode: TriviaNodeAssigner)
(containerNode: TriviaNode)
(trivia: Trivia)
: TriviaInstruction option =
let lineNumber = trivia.Range.StartLine

let rec visit node : TriviaNodeAssigner option =
let rec visit node : TriviaNode option =
let result =
node.Children
|> Array.filter (fun node -> node.Range.EndLine = lineNumber)
Expand All @@ -429,7 +416,7 @@ let lineCommentAfterSourceCodeToTriviaInstruction
Range = node.Range
AddBefore = false })

let blockCommentToTriviaInstruction (containerNode: TriviaNodeAssigner) (trivia: Trivia) : TriviaInstruction option =
let blockCommentToTriviaInstruction (containerNode: TriviaNode) (trivia: Trivia) : TriviaInstruction option =
let nodeAfter =
findNodeAfterLineAndColumn containerNode.Children trivia.Range.StartLine trivia.Range.StartColumn

Expand Down Expand Up @@ -496,7 +483,7 @@ let blockCommentToTriviaInstruction (containerNode: TriviaNodeAssigner) (trivia:
// findNodeBeforeLineFromStart triviaNodes range.StartLine
// |> updateTriviaNode (fun tn -> tn.ContentAfter.Add(Comment(BlockComment(comment, true, true)))) triviaNodes

let mapTriviaToTriviaInstruction (rootNode: TriviaNodeAssigner) (trivia: Trivia) : TriviaInstruction option =
let mapTriviaToTriviaInstruction (rootNode: TriviaNode) (trivia: Trivia) : TriviaInstruction option =
let smallestNodeThatContainsTrivia = findNodeWhereRangeFitsIn rootNode trivia.Range

match smallestNodeThatContainsTrivia with
Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core/Trivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ open Fantomas.Core.FormatConfig

val collectTrivia: FormatConfig -> ISourceText -> ParsedInput -> TriviaForSelection option -> TriviaInstruction list

val printTriviaNode: TriviaNodeAssigner -> unit
val printTriviaNode: TriviaNode -> unit

val findNodeWhereRangeFitsIn: TriviaNodeAssigner -> range -> TriviaNodeAssigner option
val findNodeWhereRangeFitsIn: TriviaNode -> range -> TriviaNode option
55 changes: 25 additions & 30 deletions src/Fantomas.Core/TriviaTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -389,39 +389,34 @@ type FsAstType =
| File_
| SigFile_

type TriviaNode =
{ Type: FsAstType
ContentBefore: TriviaContent list
ContentItself: TriviaContent option
ContentAfter: TriviaContent list
Range: Range }

type FSharpASTNode = Choice<SynModuleDecl, SynModuleSigDecl, SynExpr>

type TriviaNodeAssignerOld(nodeType: FsAstType, range: Range, ?astNode: FSharpASTNode) =
member this.Type = nodeType
member this.Range = range
member this.HasFSharpASTNode = Option.isSome astNode
member this.FSharpASTNode = astNode
member val ContentBefore = ResizeArray<TriviaContent>() with get, set
member val ContentItself = Option<TriviaContent>.None with get, set
member val ContentAfter = ResizeArray<TriviaContent>() with get, set

type TriviaNodeAssigner =
{ Range: range
Type: FsAstType
Children: TriviaNodeAssigner array
FSharpASTNode: FSharpASTNode option }
/// A hierarchical node structure that represents AST nodes as found in the tree.
/// The tree structure might deviate from what the AST has, if it is a better fit for Fantomas.
/// For example some child nodes might be placed under a different parent.
type TriviaNode =
{
/// This range might be a .FullRange calculated range if it suits Fantomas better.
Range: range
Type: FsAstType
/// These children need to be traversed in both directions, hence the choice for an array collection.
Children: TriviaNode array
FSharpASTNode: FSharpASTNode option
}

/// Used in CodePrinter, to restore the assigned trivia
type TriviaInstruction =
{ Trivia: Trivia
Type: FsAstType
Range: range
AddBefore: bool }
{
Trivia: Trivia
Type: FsAstType
Range: range
/// Should the Trivia be added before the node range or after
AddBefore: bool
}

type TriviaForSelection =
{ Selection: range
RootNode: TriviaNodeAssigner }

// TODO: consider adding two Maps in the context to store before and after trivia
// Each map has key of type:FsAstType * startPos:int * startLine:int
{
Selection: range
/// Largest AST node that fits the selection range.
RootNode: TriviaNode
}

0 comments on commit 5fd1a7f

Please sign in to comment.