Skip to content

Commit 7c2bc5f

Browse files
committed
wip: fix review comments.
1 parent 8a62bd3 commit 7c2bc5f

File tree

1 file changed

+47
-22
lines changed

1 file changed

+47
-22
lines changed

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

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

143+
144+
class PendingSyntaxNode {
145+
private let _parent: PendingSyntaxNode?
146+
private var kind: PendingSyntaxKind
147+
148+
private enum PendingSyntaxNodeKind {
149+
/// We already have a `Syntax` node realised for this node
150+
case realized(node: Syntax)
151+
/// This node does not have a `Syntax` node instantiated yet. If needed, we
152+
/// need to compute it from its parent RawSyntax node
153+
case virtual(index: Int)
154+
}
155+
156+
var node: Syntax {
157+
switch kind {
158+
case .realized(let node): return node
159+
case .virtual(let index): {
160+
let node = parent!.node.child(at: index)!
161+
kind = .realized(node)
162+
return node
163+
}
164+
}
165+
}
166+
167+
var parent: PendingSyntaxNode {
168+
return _parent!
169+
}
170+
171+
init(_ root: Syntax) {
172+
self.parent = nil
173+
self.kind = .realized(root)
174+
}
175+
176+
init(_ parent: PendingSyntaxNode, _ idx: Int) {
177+
self.parent = parent
178+
self.kind = .virtual(index: idx)
179+
}
180+
}
181+
182+
143183
/// The raw syntax walker traverses the raw syntax tree to find
144184
/// node kinds the SyntaxVisitor is interested and feed these syntax nodes to
145185
/// SyntaxVisitor.
146186
/// By traversing the raw syntax tree, we avoid realizing syntax nodes that're
147187
/// not interesting to users' SyntaxVisitor.
148188
class RawSyntaxVisitor {
149189
private let visitor: SyntaxVisitor
150-
private var childIdxChain: [Int]
151-
private var nodeChain: [Syntax]
190+
private var currentNode: PendingSyntaxNode
152191

153192
required init(_ visitor: SyntaxVisitor, _ root: Syntax) {
154193
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)
194+
self.currentNode = PendingSyntaxNode(root)
161195
}
162196

163197
func shouldVisit(_ kind: SyntaxKind) -> Bool {
@@ -169,31 +203,22 @@ class RawSyntaxVisitor {
169203
}
170204

171205
func addChildIdx(_ idx: Int) {
172-
childIdxChain.append(idx)
206+
currentNode = PendingSyntaxNode(currentNode, idx)
173207
}
174208

175209
func moveUp() {
176-
if childIdxChain.isEmpty {
177-
nodeChain.removeLast()
178-
} else {
179-
childIdxChain.removeLast()
180-
}
210+
currentNode = currentNode.parent
181211
}
182212

183213
func visitPost() {
184-
visitor.visitPost(nodeChain.last!)
214+
visitor.visitPost(currentNode.node)
185215
}
186216

187217
// The current raw syntax node is interesting for the user, so realize a
188218
// correponding syntax node and feed it into the visitor.
189219
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)
220+
visitor.visitPre(currentNode.node)
221+
return visitor.visit(currentNode.node)
197222
}
198223
}
199224

0 commit comments

Comments
 (0)