Skip to content

Commit

Permalink
Perf blank lines (#918)
Browse files Browse the repository at this point in the history
* Improve finding completely blank lines

* Inline type checks

* Don't check for trivia between attribute and binding if there are not attributes.
  • Loading branch information
nojaf committed Jun 13, 2020
1 parent 0ed30c7 commit 2a4e344
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
19 changes: 12 additions & 7 deletions src/Fantomas/TokenParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -465,20 +465,25 @@ let private findEmptyNewlinesInTokens (tokens: Token list) (lineCount) (ignoreRa
|> Option.map (fun t -> t.LineNumber)
|> Option.defaultValue lineCount

let ignoredLines =
ignoreRanges
|> List.collect(fun r -> [r.StartLine..r.EndLine])

let linesWithTokens =
tokens
|> List.groupBy (fun t -> t.LineNumber)

let completeEmptyLines =
[1 .. lastLineWithContent]
|> List.filter (fun line ->
not (List.exists (fun t -> t.LineNumber = line) tokens)
&& not (List.exists (fun (br:FSharp.Compiler.Range.range) -> br.StartLine < line && br.EndLine > line) ignoreRanges)
)
|> List.except (ignoredLines @ List.map fst linesWithTokens)
|> List.filter (fun line -> not (List.exists (fun t -> t.LineNumber = line) tokens))
|> List.map createNewLine

let linesWithOnlySpaces =
tokens
|> List.groupBy (fun t -> t.LineNumber)
linesWithTokens
|> List.filter (fun (ln, g) -> ln <= lastLineWithContent && (List.length g) = 1 && (List.head g).TokenInfo.TokenName = "WHITESPACE")
|> List.map (fst >> createNewLine)

completeEmptyLines @ linesWithOnlySpaces

let getTriviaFromTokens (tokens: Token list) linesCount =
Expand Down
14 changes: 8 additions & 6 deletions src/Fantomas/Trivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ let private findFirstNodeOnLine (nodes: TriviaNode list) lineNumber : TriviaNode
|> List.filter (fun { Range =r } -> r.StartLine = lineNumber)
|> List.tryHead

let private mainNodeIs name (t:TriviaNodeAssigner) =
let inline private mainNodeIs name (t:TriviaNodeAssigner) =
match t.Type with
| MainNode(mn) -> mn = name
| _ -> false
Expand All @@ -54,7 +54,7 @@ let private nodesContainsBothAnonModuleAndOpen (nodes: TriviaNodeAssigner list)

// the member keyword is not part of an AST node range
// so it is not an ideal candidate node to have trivia content
let private isNotMemberKeyword (node: TriviaNodeAssigner) =
let inline private isNotMemberKeyword (node: TriviaNodeAssigner) =
match node.Type with
| Token({ TokenInfo = ti }) when (ti.TokenName = "MEMBER") -> false
| _ -> true
Expand Down Expand Up @@ -232,7 +232,7 @@ let private findASTNodeOfTypeThatContains (nodes: TriviaNodeAssigner list) typeN
| _ -> false)
|> List.tryHead

let private addTriviaToTriviaNode (startOfSourceCode:int) (triviaNodes: TriviaNodeAssigner list) trivia =
let private addTriviaToTriviaNode triviaBetweenAttributeAndParentBinding (startOfSourceCode:int) (triviaNodes: TriviaNodeAssigner list) trivia =
match trivia with
| { Item = Comment(LineCommentOnSingleLine(_)) as comment; Range = range } when (commentIsAfterLastTriviaNode triviaNodes range) ->
// Comment on is on its own line after all Trivia nodes, most likely at the end of a module
Expand Down Expand Up @@ -381,8 +381,10 @@ let collectTrivia tokens lineCount (ast: ParsedInput) =
let triviaNodesFromAST =
flattenNodeToList node
|> filterNodes
|> List.map mapNodeToTriviaNode
|> List.choose id
|> List.choose mapNodeToTriviaNode

let hasAnyAttributes = List.exists (fun (tn:TriviaNodeAssigner) -> match tn.Type with | MainNode("SynAttributeList") -> true | _ -> false) triviaNodesFromAST
let triviaBetweenAttributeAndParentBinding = if hasAnyAttributes then triviaBetweenAttributeAndParentBinding else (fun _ _ -> None)
let triviaNodesFromTokens = TokenParser.getTriviaNodesFromTokens tokens
let triviaNodes = triviaNodesFromAST @ triviaNodesFromTokens |> List.sortBy (fun n -> n.Range.Start.Line, n.Range.Start.Column)

Expand All @@ -391,7 +393,7 @@ let collectTrivia tokens lineCount (ast: ParsedInput) =
match trivias with
| [] -> []
| _ ->
List.fold (addTriviaToTriviaNode startOfSourceCode) triviaNodes trivias
List.fold (addTriviaToTriviaNode triviaBetweenAttributeAndParentBinding startOfSourceCode) triviaNodes trivias
|> List.choose (fun tn ->
if triviaNodeIsNotEmpty tn then
{ Type = tn.Type
Expand Down

0 comments on commit 2a4e344

Please sign in to comment.