Skip to content

Commit d62ad83

Browse files
authored
Merge pull request swiftlang#35 from nkcsgexi/enum-visit
Using enum case instead of boolean value to indicate how SyntaxVisitor should continue.
2 parents 63034c2 + 98c080c commit d62ad83

File tree

7 files changed

+49
-34
lines changed

7 files changed

+49
-34
lines changed

Sources/SwiftSyntax/RawSyntax.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ extension RawSyntax {
478478
if shouldVisit {
479479
// Visit this node realizes a syntax node.
480480
visitor.visitPre()
481-
visitChildren = visitor.visit()
481+
visitChildren = visitor.visit() == .visitChildren
482482
}
483483
if visitChildren {
484484
for (offset, element) in layout.enumerated() {

Sources/SwiftSyntax/SyntaxClassifier.swift.gyb

+6-5
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fileprivate class _SyntaxClassifier: SyntaxVisitor {
7070
}
7171
}
7272

73-
override func visit(_ token: TokenSyntax) {
73+
override func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
7474
assert(token.isPresent)
7575
// FIXME: We need to come up with some way in which the SyntaxClassifier can
7676
// classify trivia (i.e. comments). In particular we need to be able to
@@ -91,16 +91,17 @@ fileprivate class _SyntaxClassifier: SyntaxVisitor {
9191
assert(classifications[token] == nil,
9292
"\(token) has already been classified")
9393
classifications[token] = classification
94+
return .skipChildren
9495
}
9596

9697
% for node in SYNTAX_NODES:
9798
% if is_visitable(node):
98-
override func visit(_ node: ${node.name}) -> Bool {
99+
override func visit(_ node: ${node.name}) -> SyntaxVisitorContinueKind {
99100
if skipNodeIds.contains(node.raw.id) {
100-
return false
101+
return .skipChildren
101102
}
102103
% if node.is_unknown() or node.is_syntax_collection():
103-
return true
104+
return .visitChildren
104105
% else:
105106
% for child in node.children:
106107
% if child.is_optional:
@@ -123,7 +124,7 @@ fileprivate class _SyntaxClassifier: SyntaxVisitor {
123124
% end
124125
% end
125126
% end
126-
return false
127+
return .skipChildren
127128
% end
128129
}
129130
% end

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

+32-20
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,35 @@ open class SyntaxRewriter {
9494
}
9595
}
9696

97+
/// The enum describes how the SyntaxVistor should continue after visiting
98+
/// the current node.
99+
public enum SyntaxVisitorContinueKind {
100+
101+
/// The visitor should visit the descendents of the current node.
102+
case visitChildren
103+
104+
/// The visitor should avoid visiting the descendents of the current node.
105+
case skipChildren
106+
}
107+
97108
open class SyntaxVisitor {
98109
public init() {}
99110
% for node in SYNTAX_NODES:
100111
% if is_visitable(node):
101112
/// Visting ${node.name} specifically.
102113
/// - Parameter node: the node we are visiting.
103-
/// - Returns: whether we should visit the descendents of node.
104-
open func visit(_ node: ${node.name}) -> Bool {
105-
return true
114+
/// - Returns: how should we continue visiting.
115+
open func visit(_ node: ${node.name}) -> SyntaxVisitorContinueKind {
116+
return .visitChildren
106117
}
107118
% end
108119
% end
109120

110121
/// Visting UnknownSyntax specifically.
111122
/// - Parameter node: the node we are visiting.
112-
/// - Returns: whether we should visit the descendents of node.
113-
open func visit(_ node: UnknownSyntax) -> Bool {
114-
return true
123+
/// - Returns: how should we continue visiting.
124+
open func visit(_ node: UnknownSyntax) -> SyntaxVisitorContinueKind {
125+
return .visitChildren
115126
}
116127

117128
/// Whether we should ever visit a given syntax kind.
@@ -128,7 +139,9 @@ open class SyntaxVisitor {
128139
return true
129140
}
130141

131-
open func visit(_ token: TokenSyntax) {}
142+
open func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
143+
return .skipChildren
144+
}
132145

133146
/// The function called before visiting the node and its descendents.
134147
/// - node: the node we are about to visit.
@@ -138,18 +151,17 @@ open class SyntaxVisitor {
138151
/// - node: the node we just finished visiting.
139152
open func visitPost(_ node: Syntax) {}
140153

141-
public func visit(_ node: Syntax) -> Bool {
154+
public func visit(_ node: Syntax) -> SyntaxVisitorContinueKind {
142155
switch node.raw.kind {
143-
case .token: visit(node as! TokenSyntax)
156+
case .token: return visit(node as! TokenSyntax)
144157
% for node in SYNTAX_NODES:
145158
% if is_visitable(node):
146159
case .${node.swift_syntax_kind}: return visit(node as! ${node.name})
147160
% end
148161
% end
149162
case .unknown: return visit(node as! UnknownSyntax)
150-
default: break
163+
default: return .skipChildren
151164
}
152-
return false
153165
}
154166
}
155167

@@ -158,7 +170,7 @@ open class SyntaxVisitor {
158170
/// otherwise the node is represented as a child index list from a realized
159171
/// ancestor.
160172
class PendingSyntaxNode {
161-
let parent: PendingSyntaxNode?
173+
let parent: PendingSyntaxNode!
162174
private var kind: PendingSyntaxNodeKind
163175

164176
private enum PendingSyntaxNodeKind {
@@ -174,7 +186,7 @@ class PendingSyntaxNode {
174186
case .realized(let node):
175187
return node
176188
case .virtual(let index):
177-
let _node = parent!.node.child(at: index)!
189+
let _node = parent.node.child(at: index)!
178190
kind = .realized(node: _node)
179191
return _node
180192
}
@@ -199,7 +211,7 @@ class PendingSyntaxNode {
199211
/// not interesting to users' SyntaxVisitor.
200212
class RawSyntaxVisitor {
201213
private let visitor: SyntaxVisitor
202-
private var currentNode: PendingSyntaxNode?
214+
private var currentNode: PendingSyntaxNode!
203215

204216
required init(_ visitor: SyntaxVisitor, _ root: Syntax) {
205217
self.visitor = visitor
@@ -215,25 +227,25 @@ class RawSyntaxVisitor {
215227
}
216228

217229
func addChildIdx(_ idx: Int) {
218-
currentNode = PendingSyntaxNode(currentNode!, idx)
230+
currentNode = PendingSyntaxNode(currentNode, idx)
219231
}
220232

221233
func moveUp() {
222-
currentNode = currentNode!.parent
234+
currentNode = currentNode.parent
223235
}
224236

225237
func visitPre() {
226-
visitor.visitPre(currentNode!.node)
238+
visitor.visitPre(currentNode.node)
227239
}
228240

229241
func visitPost() {
230-
visitor.visitPost(currentNode!.node)
242+
visitor.visitPost(currentNode.node)
231243
}
232244

233245
// The current raw syntax node is interesting for the user, so realize a
234246
// correponding syntax node and feed it into the visitor.
235-
func visit() -> Bool {
236-
return visitor.visit(currentNode!.node)
247+
func visit() -> SyntaxVisitorContinueKind {
248+
return visitor.visit(currentNode.node)
237249
}
238250
}
239251

Sources/lit-test-helper/ClassifiedSyntaxTreePrinter.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,12 @@ class ClassifiedSyntaxTreePrinter: SyntaxVisitor {
115115
}
116116
}
117117

118-
override func visit(_ node: TokenSyntax) {
118+
override func visit(_ node: TokenSyntax) -> SyntaxVisitorContinueKind {
119119
visit(node.leadingTrivia)
120120
let classification = classifications[node] ?? SyntaxClassification.none
121121
recordCurrentClassification(classification)
122122
result += node.text
123123
visit(node.trailingTrivia)
124+
return .skipChildren
124125
}
125126
}

Tests/SwiftSyntaxTest/AbsolutePosition.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ public class AbsolutePositionTestCase: XCTestCase {
6464
_ = node.byteSize
6565
_ = node.positionAfterSkippingLeadingTrivia
6666
}
67-
override func visit(_ node: TokenSyntax) {
67+
override func visit(_ node: TokenSyntax) -> SyntaxVisitorContinueKind {
6868
XCTAssertEqual(node.positionAfterSkippingLeadingTrivia.utf8Offset,
6969
node.position.utf8Offset + node.leadingTrivia.byteSize)
70+
return .skipChildren
7071
}
7172
}
7273
parsed.walk(Visitor())

Tests/SwiftSyntaxTest/DiagnosticTest.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ public class DiagnosticTestCase: XCTestCase {
7676
self.url = url
7777
self.engine = engine
7878
}
79-
override func visit(_ function: FunctionDeclSyntax) -> Bool {
79+
override func visit(_ function: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
8080
let startLoc = function.identifier.startLocation(in: url)
8181
let endLoc = function.endLocation(in: url)
8282
engine.diagnose(.badFunction(function.identifier), location: startLoc) {
8383
$0.highlight(function.identifier.sourceRange(in: self.url))
8484
}
8585
engine.diagnose(.endOfFunction(function.identifier), location: endLoc)
86-
return true
86+
return .visitChildren
8787
}
8888
}
8989

Tests/SwiftSyntaxTest/VisitorTest.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ public class SyntaxVisitorTestCase: XCTestCase {
1313
public func testBasic() {
1414
class FuncCounter: SyntaxVisitor {
1515
var funcCount = 0
16-
override func visit(_ node: FunctionDeclSyntax) -> Bool {
16+
override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
1717
funcCount += 1
18-
return true
18+
return .visitChildren
1919
}
2020
}
2121
XCTAssertNoThrow(try {
@@ -70,9 +70,9 @@ public class SyntaxVisitorTestCase: XCTestCase {
7070
class VisitCollections: SyntaxVisitor {
7171
var numberOfCodeBlockItems = 0
7272

73-
override func visit(_ items: CodeBlockItemListSyntax) -> Bool {
73+
override func visit(_ items: CodeBlockItemListSyntax) -> SyntaxVisitorContinueKind {
7474
numberOfCodeBlockItems += items.count
75-
return true
75+
return .visitChildren
7676
}
7777
}
7878

0 commit comments

Comments
 (0)