Skip to content

Commit 6184faf

Browse files
committed
Improve SyntaxVisitor performance
Refactor the implementation to match SyntaxRewriter, thereby gaining the same performance benefits.
1 parent 42b325f commit 6184faf

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,12 @@ open class SyntaxRewriter {
146146
// nodes are being collected.
147147
var newLayout: ContiguousArray<RawSyntax?>?
148148

149-
let parentBox = SyntaxBox(Syntax(node))
149+
let syntaxNode = Syntax(node)
150+
let parentBox = SyntaxBox(syntaxNode)
150151

151152
// Incrementing i manually is faster than using .enumerated()
152153
var childIndex = 0
153-
for (raw, info) in RawSyntaxChildren(Syntax(node)) {
154+
for (raw, info) in RawSyntaxChildren(syntaxNode) {
154155
defer { childIndex += 1 }
155156
guard let child = raw else {
156157
// Node does not exist. If we are collecting rewritten nodes, we need to
@@ -383,16 +384,16 @@ private func _doVisitImpl${node.name}<Visitor>(
383384
let node = Unknown${node.name}(data)
384385
let needsChildren = (visitor.visit(node) == .visitChildren)
385386
// Avoid calling into visitChildren if possible.
386-
if needsChildren && data.raw.numberOfChildren > 0 {
387-
visitChildren(data, parent: Syntax(node), &visitor)
387+
if needsChildren && node.raw.numberOfChildren > 0 {
388+
visitChildren(node, &visitor)
388389
}
389390
visitor.visitPost(node)
390391
% else:
391392
let node = ${node.name}(data)
392393
let needsChildren = (visitor.visit(node) == .visitChildren)
393394
// Avoid calling into visitChildren if possible.
394-
if needsChildren && data.raw.numberOfChildren > 0 {
395-
visitChildren(data, parent: Syntax(node), &visitor)
395+
if needsChildren && node.raw.numberOfChildren > 0 {
396+
visitChildren(node, &visitor)
396397
}
397398
visitor.visitPost(node)
398399
% end
@@ -413,8 +414,8 @@ fileprivate func doVisit<Visitor>(
413414
let node = UnknownSyntax(data)
414415
let needsChildren = (visitor.visit(node) == .visitChildren)
415416
// Avoid calling into visitChildren if possible.
416-
if needsChildren && data.raw.numberOfChildren > 0 {
417-
visitChildren(data, parent: Syntax(node), &visitor)
417+
if needsChildren && node.raw.numberOfChildren > 0 {
418+
visitChildren(node, &visitor)
418419
}
419420
visitor.visitPost(node)
420421
// The implementation of every generated case goes into its own function. This
@@ -428,11 +429,13 @@ fileprivate func doVisit<Visitor>(
428429
}
429430
}
430431

431-
fileprivate func visitChildren<Visitor>(
432-
_ data: SyntaxData, parent: Syntax, _ visitor: inout Visitor
432+
fileprivate func visitChildren<SyntaxType: SyntaxProtocol, Visitor>(
433+
_ syntax: SyntaxType, _ visitor: inout Visitor
433434
) where Visitor : SyntaxVisitor {
434-
for childRaw in PresentRawSyntaxChildren(data.absoluteRaw) {
435-
let childData = SyntaxData(childRaw, parent: parent)
435+
let syntaxNode = Syntax(syntax)
436+
let parentBox = SyntaxBox(syntaxNode)
437+
for childRaw in PresentRawSyntaxChildren(syntaxNode) {
438+
let childData = SyntaxData(childRaw, parentBox: parentBox)
436439
doVisit(childData, &visitor)
437440
}
438441
}

0 commit comments

Comments
 (0)