8000 Introduce `SyntaxVisitorBase` · swiftlang/swift-syntax@69e8659 · GitHub
[go: up one dir, main page]

Skip to content

Commit 69e8659

Browse files
committed
Introduce SyntaxVisitorBase
This is useful if you intend to have subclasses overriding specific methods of a common base `SyntaxVisitor` class.
1 parent aa84ea6 commit 69e8659

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,35 @@ public extension SyntaxAnyVisitor {
221221
}
222222
}
223223

224+
/// A class version of the `SyntaxVisitor` protocol. This is useful if you
225+
/// intend to have subclasses overriding specific methods of a common base
226+
/// `SyntaxVisitor` class.
227+
///
228+
/// It workarounds the issue of not being able to override the default
229+
/// implementations of the protocol (see https://bugs.swift.org/browse/SR-103).
230+
open class SyntaxVisitorBase: SyntaxVisitor {
231+
public init() {}
232+
233+
% for node in SYNTAX_NODES:
234+
% if is_visitable(node):
235+
open func visit(_ node: ${node.name}) -> SyntaxVisitorContinueKind {
236+
return .visitChildren
237+
}
238+
open func visitPost(_ node: ${node.name}) {}
239+
% end
240+
% end
241+
242+
open func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
243+
return .visitChildren
244+
}
245+
open func visitPost(_ node: TokenSyntax) {}
246+
247+
open func visit(_ node: UnknownSyntax) -> SyntaxVisitorContinueKind {
248+
return .visitChildren
249+
}
250+
open func visitPost(_ node: UnknownSyntax) {}
251+
}
252+
224253
extension _SyntaxBase {
225254
func walk<Visitor>(_ visitor: inout Visitor) where Visitor : SyntaxVisitor {
226255
guard isPresent else { return }

Tests/SwiftSyntaxTest/VisitorTest.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class SyntaxVisitorTestCase: XCTestCase {
88
("testRewritingNodeWithEmptyChild", testRewritingNodeWithEmptyChild),
99
("testSyntaxRewriterVisitAny", testSyntaxRewriterVisitAny),
1010
("testSyntaxRewriterVisitCollection", testSyntaxRewriterVisitCollection),
11+
("testVisitorClass", testVisitorClass),
1112
]
1213

1314
public func testBasic() {
@@ -83,4 +84,22 @@ public class SyntaxVisitorTestCase: XCTestCase {
8384
XCTAssertEqual(4, visitor.numberOfCodeBlockItems)
8485
}())
8586
}
87+
88+
public func testVisitorClass() {
89+
class FuncCounter: SyntaxVisitorBase {
90+
var funcCount = 0
91+
override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
92+
funcCount += 1
93+
return super.visit(node)
94+
}
95+
}
96+
XCTAssertNoThrow(try {
97+
let parsed = try SyntaxParser.parse(getInput("visitor.swift"))
98+
var counter = FuncCounter()
99+
let hashBefore = parsed.hashValue
100+
parsed.walk(&counter)
101+
XCTAssertEqual(counter.funcCount, 3)
102+
XCTAssertEqual(hashBefore, parsed.hashValue)
103+
}())
104+
}
86105
}

0 commit comments

Comments
 (0)
0