@@ -141,3 +141,75 @@ open class SyntaxVisitor {
141
141
}
142
142
}
143
143
}
144
+
145
+ public protocol SyntaxTransformVisitor {
146
+ associatedtype ResultType = Void
147
+
148
+ func visit( _ token: TokenSyntax ) -> ResultType ?
149
+ func visit( _ node: UnknownSyntax ) -> ResultType ?
150
+
151
+ % for node in SYNTAX_NODES:
152
+ % if is_visitable( node) :
153
+ /// Visiting `${node.name}` specifically.
154
+ /// - Parameter node: the node we are visiting.
155
+ /// - Returns: nil by default.
156
+ func visit( _ node: ${ node. name} ) -> ResultType ?
157
+ % end
158
+ % end
159
+ }
160
+
161
+ extension SyntaxTransformVisitor {
162
+ public func visit( _ token: TokenSyntax ) -> ResultType ? { nil }
163
+ public func visit( _ node: UnknownSyntax ) -> ResultType ? { nil }
164
+
165
+ % for node in SYNTAX_NODES:
166
+ % if is_visitable( node) :
167
+ /// Visiting `${node.name}` specifically.
168
+ /// - Parameter node: the node we are visiting.
169
+ /// - Returns: nil by default.
170
+ public func visit( _ node: ${ node. name} ) -> ResultType ? {
171
+ % if node. is_base ( ) :
172
+ // Avoid calling into visitChildren if possible.
173
+ if !node. raw. layoutView!. children. isEmpty {
174
+ return visitChildren ( node) . first
175
+ }
176
+ return nil
177
+ % else :
178
+ // Avoid calling into visitChildren if possible.
179
+ if !node. raw. layoutView!. children. isEmpty {
180
+ return visitChildren ( node) . first
181
+ }
182
+ return nil
183
+ % end
184
+ }
185
+ % end
186
+ % end
187
+
188
+ public func visit( _ data: SyntaxData ) -> ResultType ? {
189
+ switch data. raw. kind {
190
+ case . token:
191
+ let node = TokenSyntax ( data)
192
+ return visit ( node)
193
+ case . unknown:
194
+ let node = UnknownSyntax ( data)
195
+ return visit ( node)
196
+ // The implementation of every generated case goes into its own function. This
197
+ // circumvents an issue where the compiler allocates stack space for every
198
+ // case statement next to each other in debug builds, causing it to allocate
199
+ // ~50KB per call to this function. rdar://55929175
200
+ % for node in NON_BASE_SYNTAX_NODES:
201
+ case . ${ node. swift_syntax_kind} :
202
+ let node = ${ node. name} ( data)
203
+ return visit ( node)
204
+ % end
205
+ }
206
+ }
207
+
208
+ public func visitChildren< SyntaxType: SyntaxProtocol > ( _ node: SyntaxType ) -> [ ResultType ] {
209
+ let syntaxNode = Syntax ( node)
210
+ return NonNilRawSyntaxChildren ( syntaxNode, viewMode: . sourceAccurate) . compactMap { childRaw in
211
+ let childData = SyntaxData ( childRaw, parent: syntaxNode)
212
+ return visit ( childData)
213
+ }
214
+ }
215
+ }
0 commit comments