Skip to content

Commit f174c4d

Browse files
committed
fix review comments.
1 parent 3bc84d2 commit f174c4d

File tree

2 files changed

+54
-27
lines changed

2 files changed

+54
-27
lines changed

Sources/SwiftSyntax/RawSyntax.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,13 @@ extension RawSyntax {
476476
let shouldVisit = visitor.shouldVisit(kind)
477477
var visitChildren = true
478478
if shouldVisit {
479-
480479
// Visit this node realizes a syntax node.
481-
visitChildren = visitor.visitCurrent()
480+
visitor.visitPre()
481+
visitChildren = visitor.visit()
482482
}
483483
if visitChildren {
484484
for (offset, element) in layout.enumerated() {
485485
guard let element = element else { continue }
486-
487486
// Teach the visitor to navigate to this child.
488487
visitor.addChildIdx(offset)
489488
element.accept(visitor)
@@ -494,7 +493,8 @@ extension RawSyntax {
494493
}
495494
case .token(let kind, _, _):
496495
if visitor.shouldVisit(kind) {
497-
_ = visitor.visitCurrent()
496+
visitor.visitPre()
497+
_ = visitor.visit()
498498
visitor.visitPost()
499499
}
500500
}

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -140,24 +140,57 @@ open class SyntaxVisitor {
140140
}
141141
}
142142

143+
144+
/// A wrapper over Syntax. A syntax node is only realized when explicitly asked;
145+
/// otherwise the node is represented as a child index list from a realized
146+
/// ancestor.
147+
class PendingSyntaxNode {
148+
let parent: PendingSyntaxNode?
149+
private var kind: PendingSyntaxNodeKind
150+
151+
private enum PendingSyntaxNodeKind {
152+
/// We already have a `Syntax` node realised for this node
153+
case realized(node: Syntax)
154+
/// This node does not have a `Syntax` node instantiated yet. If needed, we
155+
/// need to compute it from its parent RawSyntax node
156+
case virtual(index: Int)
157+
}
158+
159+
var node: Syntax {
160+
switch kind {
161+
case .realized(let node):
162+
return node
163+
case .virtual(let index):
164+
let _node = parent!.node.child(at: index)!
165+
kind = .realized(node: _node)
166+
return _node
167+
}
168+
}
169+
170+
init(_ root: Syntax) {
171+
self.parent = nil
172+
self.kind = .realized(node: root)
173+
}
174+
175+
init(_ parent: PendingSyntaxNode, _ idx: Int) {
176+
self.parent = parent
177+
self.kind = .virtual(index: idx)
178+
}
179+
}
180+
181+
143182
/// The raw syntax walker traverses the raw syntax tree to find
144183
/// node kinds the SyntaxVisitor is interested and feed these syntax nodes to
145184
/// SyntaxVisitor.
146185
/// By traversing the raw syntax tree, we avoid realizing syntax nodes that're
147186
/// not interesting to users' SyntaxVisitor.
148187
class RawSyntaxVisitor {
149188
private let visitor: SyntaxVisitor
150-
private var childIdxChain: [Int]
151-
private var nodeChain: [Syntax]
189+
private var currentNode: PendingSyntaxNode?
152190

153191
required init(_ visitor: SyntaxVisitor, _ root: Syntax) {
154192
self.visitor = visitor
155-
self.nodeChain = [root]
156-
self.childIdxChain = []
157-
}
158-
159-
convenience init(_ another: RawSyntaxVisitor, _ root: Syntax) {
160-
self.init(another.visitor, root)
193+
self.currentNode = PendingSyntaxNode(root)
161194
}
162195

163196
func shouldVisit(_ kind: SyntaxKind) -> Bool {
@@ -169,31 +202,25 @@ class RawSyntaxVisitor {
169202
}
170203

171204
func addChildIdx(_ idx: Int) {
172-
childIdxChain.append(idx)
205+
currentNode = PendingSyntaxNode(currentNode!, idx)
173206
}
174207

175208
func moveUp() {
176-
if childIdxChain.isEmpty {
177-
nodeChain.removeLast()
178-
} else {
179-
childIdxChain.removeLast()
180-
}
209+
currentNode = currentNode!.parent
210+
}
211+
212+
func visitPre() {
213+
visitor.visitPre(currentNode!.node)
181214
}
182215

183216
func visitPost() {
184-
visitor.visitPost(nodeChain.last!)
217+
visitor.visitPost(currentNode!.node)
185218
}
186219

187220
// The current raw syntax node is interesting for the user, so realize a
188221
// correponding syntax node and feed it into the visitor.
189-
func visitCurrent() -> Bool {
190-
for id in childIdxChain {
191-
nodeChain.append(nodeChain.last!.child(at: id)!)
192-
}
193-
childIdxChain.removeAll(keepingCapacity: true)
194-
let node = nodeChain.last!
195-
visitor.visitPre(node)
196-
return visitor.visit(node)
222+
func visit() -> Bool {
223+
return visitor.visit(currentNode!.node)
197224
}
198225
}
199226

0 commit comments

Comments
 (0)