@@ -106,7 +106,7 @@ open class SyntaxRewriter {
106
106
107
107
% end
108
108
109
- final func visit ( _ data: SyntaxData) - > Syntax {
109
+ private func visit ( _ data: SyntaxData) - > Syntax {
110
110
switch data. raw. kind {
111
111
case . token:
112
112
let node = TokenSyntax ( data)
@@ -133,8 +133,9 @@ open class SyntaxRewriter {
133
133
}
134
134
}
135
135
136
- final func visitChildren < SyntaxType : SyntaxProtocol> ( _ node: SyntaxType)
137
- - > SyntaxType {
136
+ fileprivate final func visitChildren < SyntaxType : SyntaxProtocol> (
137
+ _ node: SyntaxType
138
+ ) - > SyntaxType {
138
139
// Walk over all children of this node and rewrite them. Don't store any
139
140
// rewritten nodes until the first non-`nil` value is encountered. When this
140
141
// happens, retrieve all previous syntax nodes from the parent node to
@@ -222,220 +223,144 @@ public enum SyntaxVisitorContinueKind {
222
223
case skipChildren
223
224
}
224
225
225
- public protocol SyntaxVisitor {
226
+ open class SyntaxVisitor {
227
+ public init ( ) { }
228
+
226
229
% for node in SYNTAX_NODES:
227
230
% if is_visitable ( node) :
228
231
/// Visiting `${node.name}` specifically.
229
232
/// - Parameter node: the node we are visiting.
230
233
/// - Returns: how should we continue visiting.
231
- mutating func visit( _ node: ${ node. name} ) -> SyntaxVisitorContinueKind
234
+ open func visit( _ node: ${ node. name} ) -> SyntaxVisitorContinueKind {
235
+ return . visitChildren
236
+ }
232
237
233
238
/// The function called after visiting `${node.name}` and its descendents.
234
239
/// - node: the node we just finished visiting.
235
- mutating func visitPost( _ node: ${ node. name} )
240
+ open func visitPost( _ node: ${ node. name} ) { }
236
241
% end
237
242
% end
238
243
239
244
/// Visiting `TokenSyntax` specifically.
240
245
/// - Parameter node: the node we are visiting.
241
246
/// - Returns: how should we continue visiting.
242
- mutating func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind
247
+ open func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind {
248
+ return . visitChildren
249
+ }
243
250
244
251
/// The function called after visiting the node and its descendents.
245
252
/// - node: the node we just finished visiting.
246
- mutating func visitPost( _ node: TokenSyntax )
253
+ open func visitPost( _ node: TokenSyntax ) { }
247
254
248
255
/// Visiting `UnknownSyntax` specifically.
249
256
/// - Parameter node: the node we are visiting.
250
257
/// - Returns: how should we continue visiting.
251
- mutating func visit( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind
252
-
253
- /// The function called after visiting the node and its descendents.
254
- /// - node: the node we just finished visiting.
255
- mutating func visitPost( _ node: UnknownSyntax )
256
- }
257
-
258
- public extension SyntaxVisitor {
259
- % for node in SYNTAX_NODES:
260
- % if is_visitable ( node) :
261
- mutating func visit( _ node: ${ node. name} ) -> SyntaxVisitorContinueKind {
258
+ open func visit( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind {
262
259
return . visitChildren
263
260
}
264
- mutating func visitPost( _ node: ${ node. name} ) { }
265
- % end
266
- % end
267
261
268
- mutating func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind {
269
- return . visitChildren
270
- }
271
- mutating func visitPost( _ node: TokenSyntax ) { }
262
+ /// The function called after visiting the node and its descendents.
263
+ /// - node: the node we just finished visiting.
264
+ open func visitPost( _ node: UnknownSyntax ) { }
272
265
273
- mutating func visit ( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind {
274
- return . visitChildren
266
+ public func walk ( _ node: Syntax ) {
267
+ visit ( node . data )
275
268
}
276
- mutating func visitPost( _ node: UnknownSyntax ) { }
277
- }
278
-
279
- /// A `SyntaxVisitor` that can visit the nodes as generic `Syntax` values.
280
- ///
281
- /// This is a separate protocol because this kind of visitation is slower than
282
- /// the type-specific visitation of `SyntaxVisitor`. Use `SyntaxAnyVisitor` if
283
- /// the `visitAny(_)` function would be useful to have, otherwise use
284
- /// `SyntaxVisitor`.
285
- ///
286
- /// This works by introducing default implementations of the type-specific
287
- /// visit function that delegate to `visitAny(_)`. A conformant type that
288
- /// provides a custom type-specific visit function, should also call
289
- /// `visitAny(_)` in its implementation, if calling `visitAny` is needed:
290
- ///
291
- /// struct MyVisitor: SyntaxAnyVisitor {
292
- /// func visitAny(_ node: Syntax) -> SyntaxVisitorContinueKind {
293
- /// <code>
294
- /// }
295
- ///
296
- /// func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
297
- /// <code>
298
- /// // Call this to pass tokens to `visitAny(_)` as well if needed
299
- /// visitAny(token)
300
- /// }
301
- ///
302
- public protocol SyntaxAnyVisitor : SyntaxVisitor {
303
- mutating func visitAny( _ node: Syntax ) -> SyntaxVisitorContinueKind
304
- mutating func visitAnyPost( _ node: Syntax )
305
- }
306
-
307
- public extension SyntaxAnyVisitor {
308
- mutating func visitAnyPost( _ node: Syntax ) { }
309
269
310
270
% for node in SYNTAX_NODES:
311
- % if is_visitable ( node) :
312
- mutating func visit( _ node: ${ node. name} ) -> SyntaxVisitorContinueKind {
313
- return visitAny ( Syntax ( node) )
314
- }
315
- mutating func visitPost( _ node: ${ node. name} ) {
316
- return visitAnyPost ( Syntax ( node) )
317
- }
271
+ /// Implementation detail of doVisit(_:_:). Do not call directly.
272
+ private func visitImpl${ node. name} ( _ data: SyntaxData) {
273
+ % if node. is_base ( ) :
274
+ let node = Unknown${ node. name} ( data)
275
+ let needsChildren = ( visit ( node) == . visitChildren)
276
+ // Avoid calling into visitChildren if possible.
277
+ if needsChildren && node. raw. numberOfChildren > 0 {
278
+ visitChildren ( node)
279
+ }
280
+ visitPost ( node)
281
+ % else :
282
+ let node = ${ node. name} ( data)
283
+ let needsChildren = ( visit ( node) == . visitChildren)
284
+ // Avoid calling into visitChildren if possible.
285
+ if needsChildren && node. raw. numberOfChildren > 0 {
286
+ visitChildren ( node)
287
+ }
288
+ visitPost ( node)
318
289
% end
290
+ }
291
+
319
292
% end
320
293
321
- mutating func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind {
322
- return visitAny ( Syntax ( token) )
323
- }
324
- mutating func visitPost( _ node: TokenSyntax ) {
325
- return visitAnyPost ( Syntax ( node) )
294
+ private func visit( _ data: SyntaxData ) {
295
+ switch data. raw. kind {
296
+ case . token:
297
+ let node = TokenSyntax ( data)
298
+ _ = visit ( node)
299
+ // No children to visit.
300
+ visitPost ( node)
301
+ case . unknown:
302
+ let node = UnknownSyntax ( data)
303
+ let needsChildren = ( visit ( node) == . visitChildren)
304
+ // Avoid calling into visitChildren if possible.
305
+ if needsChildren && node. raw. numberOfChildren > 0 {
306
+ visitChildren ( node)
307
+ }
308
+ visitPost ( node)
309
+ // The implementation of every generated case goes into its own function. This
310
+ // circumvents an issue where the compiler allocates stack space for every
311
+ // case statement next to each other in debug builds, causing it to allocate
312
+ // ~50KB per call to this function. rdar://55929175
313
+ % for node in SYNTAX_NODES:
314
+ case . ${ node. swift_syntax_kind} :
315
+ visitImpl ${ node. name} ( data)
316
+ % end
317
+ }
326
318
}
327
319
328
- mutating func visit( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind {
329
- return visitAny ( Syntax ( node) )
330
- }
331
- mutating func visitPost( _ node: UnknownSyntax ) {
332
- return visitAnyPost ( Syntax ( node) )
320
+ private func visitChildren< SyntaxType: SyntaxProtocol > ( _ node: SyntaxType ) {
321
+ let syntaxNode = Syntax ( node)
322
+ let parentBox = SyntaxBox ( syntaxNode)
323
+ for childRaw in PresentRawSyntaxChildren ( syntaxNode) {
324
+ let childData = SyntaxData ( childRaw, parentBox: parentBox)
325
+ visit ( childData)
326
+ }
333
327
}
334
328
}
335
329
336
- /// A class version of the `SyntaxVisitor` protocol. This is useful if you
337
- /// intend to have subclasses overriding specific methods of a common base
338
- /// `SyntaxVisitor` class.
339
- ///
340
- /// It workarounds the issue of not being able to override the default
341
- /// implementations of the protocol (see https://bugs.swift.org/browse/SR-103).
342
- open class SyntaxVisitorBase : SyntaxVisitor {
330
+ open class SyntaxAnyVisitor {
343
331
public init ( ) { }
344
332
345
- % for node in SYNTAX_NODES:
346
- % if is_visitable( node) :
347
- open func visit( _ node: ${ node. name} ) -> SyntaxVisitorContinueKind {
348
- return . visitChildren
349
- }
350
- open func visitPost( _ node: ${ node. name} ) { }
351
- % end
352
- % end
353
-
354
- open func visit( _ token: TokenSyntax ) -> SyntaxVisitorContinueKind {
333
+ /// Visiting `UnknownSyntax` specifically.
334
+ /// - Parameter node: the node we are visiting.
335
+ /// - Returns: how should we continue visiting.
336
+ open func visit( _ node: Syntax ) -> SyntaxVisitorContinueKind {
355
337
return . visitChildren
356
338
}
357
- open func visitPost( _ node: TokenSyntax ) { }
358
339
359
- open func visit( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind {
360
- return . visitChildren
361
- }
362
- open func visitPost( _ node: UnknownSyntax ) { }
363
- }
340
+ /// The function called after visiting the node and its descendents.
341
+ /// - node: the node we just finished visiting.
342
+ open func visitPost( _ node: Syntax ) { }
364
343
365
- public extension Syntax {
366
- func walk< Visitor> ( _ visitor: inout Visitor ) where Visitor : SyntaxVisitor {
367
- guard isPresent else { return }
368
- return doVisit ( data, & visitor)
344
+ public func walk( _ node: Syntax ) {
345
+ visit ( node. data)
369
346
}
370
- }
371
347
372
- public extension SyntaxProtocol {
373
- func walk< Visitor> ( _ visitor: inout Visitor ) where Visitor : SyntaxVisitor {
374
- return _syntaxNode. walk ( & visitor)
375
- }
376
- }
377
-
378
- % for node in SYNTAX_NODES:
379
- /// Implementation detail of doVisit(_:_:). Do not call directly.
380
- private func _doVisitImpl${ node. name} < Visitor> (
381
- _ data: SyntaxData, _ visitor : inout Visitor
382
- ) where Visitor : SyntaxVisitor {
383
- % if node. is_base ( ) :
384
- let node = Unknown${ node. name} ( data)
385
- let needsChildren = ( visitor. visit ( node) == . visitChildren)
348
+ private func visit( _ data: SyntaxData ) {
349
+ let node = Syntax ( data)
350
+ let needsChildren = ( visit ( node) == . visitChildren)
386
351
// Avoid calling into visitChildren if possible.
387
352
if needsChildren && node. raw. numberOfChildren > 0 {
388
- visitChildren ( node, & visitor )
353
+ visitChildren ( node)
389
354
}
390
- visitor. visitPost ( node)
391
- % else :
392
- let node = ${ node. name} ( data)
393
- let needsChildren = ( visitor. visit ( node) == . visitChildren)
394
- // Avoid calling into visitChildren if possible.
395
- if needsChildren && node. raw. numberOfChildren > 0 {
396
- visitChildren ( node, & visitor)
397
- }
398
- visitor. visitPost ( node)
399
- % end
400
- }
401
-
402
- % end
355
+ visitPost ( node)
356
+ }
403
357
404
- fileprivate func doVisit< Visitor> (
405
- _ data: SyntaxData , _ visitor: inout Visitor
406
- ) where Visitor : SyntaxVisitor {
407
- switch data. raw. kind {
408
- case . token:
409
- let node = TokenSyntax ( data)
410
- _ = visitor. visit ( node)
411
- // No children to visit.
412
- visitor. visitPost ( node)
413
- case . unknown:
414
- let node = UnknownSyntax ( data)
415
- let needsChildren = ( visitor. visit ( node) == . visitChildren)
416
- // Avoid calling into visitChildren if possible.
417
- if needsChildren && node. raw. numberOfChildren > 0 {
418
- visitChildren ( node, & visitor)
358
+ private func visitChildren( _ node: Syntax ) {
359
+ let parentBox = SyntaxBox ( node)
360
+ for childRaw in PresentRawSyntaxChildren ( node) {
361
+ let childData = SyntaxData ( childRaw, parentBox: parentBox)
362
+ visit ( childData)
419
363
}
420
- visitor. visitPost ( node)
421
- // The implementation of every generated case goes into its own function. This
422
- // circumvents an issue where the compiler allocates stack space for every
423
- // case statement next to each other in debug builds, causing it to allocate
424
- // ~50KB per call to this function. rdar://55929175
425
- % for node in SYNTAX_NODES:
426
- case . ${ node. swift_syntax_kind} :
427
- _doVisitImpl ${ node. name} ( data, & visitor)
428
- % end
429
364
}
430
- }
431
365
432
- fileprivate func visitChildren< SyntaxType: SyntaxProtocol , Visitor> (
433
- _ syntax: SyntaxType , _ visitor: inout Visitor
434
- ) where Visitor : SyntaxVisitor {
435
- let syntaxNode = Syntax ( syntax)
436
- let parentBox = SyntaxBox ( syntaxNode)
437
- for childRaw in PresentRawSyntaxChildren ( syntaxNode) {
438
- let childData = SyntaxData ( childRaw, parentBox: parentBox)
439
- doVisit ( childData, & visitor)
440
- }
441
366
}
0 commit comments