Skip to content

Commit 465c321

Browse files
committed
Model Syntax nodes as structs
Avoid the overhead of existentials by modelling the entire syntax node hierarchy using structs with custom casting functions. This results in a major performance gain for SyntaxRewriter.
1 parent 0a55b1d commit 465c321

25 files changed

+613
-698
lines changed

Sources/SwiftSyntax/SourceLocation.swift

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,13 @@ public final class SourceLocationConverter {
227227
}
228228
}
229229

230-
extension _SyntaxBase {
230+
public extension Syntax {
231+
/// The starting location, in the provided file, of this Syntax node.
232+
/// - Parameters:
233+
/// - converter: The `SourceLocationConverter` that was previously
234+
/// initialized using the root tree of this node.
235+
/// - afterLeadingTrivia: Whether to skip leading trivia when getting
236+
/// the node's location. Defaults to `true`.
231237
func startLocation(
232238
converter: SourceLocationConverter,
233239
afterLeadingTrivia: Bool = true
@@ -238,6 +244,12 @@ extension _SyntaxBase {
238244
return converter.location(for: pos)
239245
}
240246

247+
/// The ending location, in the provided file, of this Syntax node.
248+
/// - Parameters:
249+
/// - converter: The `SourceLocationConverter` that was previously
250+
/// initialized using the root tree of this node.
251+
/// - afterTrailingTrivia: Whether to skip trailing trivia when getting
252+
/// the node's location. Defaults to `false`.
241253
func endLocation(
242254
converter: SourceLocationConverter,
243255
afterTrailingTrivia: Bool = false
@@ -251,30 +263,40 @@ extension _SyntaxBase {
251263
return converter.location(for: pos)
252264
}
253265

266+
/// The source range, in the provided file, of this Syntax node.
267+
/// - Parameters:
268+
/// - converter: The `SourceLocationConverter` that was previously
269+
/// initialized using the root tree of this node.
270+
/// - afterLeadingTrivia: Whether to skip leading trivia when getting
271+
/// the node's start location. Defaults to `true`.
272+
/// - afterTrailingTrivia: Whether to skip trailing trivia when getting
273+
/// the node's end location. Defaults to `false`.
254274
func sourceRange(
255275
converter: SourceLocationConverter,
256276
afterLeadingTrivia: Bool = true,
257277
afterTrailingTrivia: Bool = false
258278
) -> SourceRange {
259-
let start = startLocation(converter: converter, afterLeadingTrivia: afterLeadingTrivia)
260-
let end = endLocation(converter: converter, afterTrailingTrivia: afterTrailingTrivia)
279+
let start = startLocation(converter: converter,
280+
afterLeadingTrivia: afterLeadingTrivia)
281+
let end = endLocation(converter: converter,
282+
afterTrailingTrivia: afterTrailingTrivia)
261283
return SourceRange(start: start, end: end)
262284
}
263285
}
264286

265-
extension Syntax {
287+
public extension SyntaxProtocol {
266288
/// The starting location, in the provided file, of this Syntax node.
267289
/// - Parameters:
268290
/// - converter: The `SourceLocationConverter` that was previously
269291
/// initialized using the root tree of this node.
270292
/// - afterLeadingTrivia: Whether to skip leading trivia when getting
271293
/// the node's location. Defaults to `true`.
272-
public func startLocation(
294+
func startLocation(
273295
converter: SourceLocationConverter,
274296
afterLeadingTrivia: Bool = true
275297
) -> SourceLocation {
276-
return base.startLocation(converter: converter,
277-
afterLeadingTrivia: afterLeadingTrivia)
298+
return _syntaxNode.startLocation(converter: converter,
299+
afterLeadingTrivia: afterLeadingTrivia)
278300
}
279301

280302
/// The ending location, in the provided file, of this Syntax node.
@@ -283,12 +305,12 @@ extension Syntax {
283305
/// initialized using the root tree of this node.
284306
/// - afterTrailingTrivia: Whether to skip trailing trivia when getting
285307
/// the node's location. Defaults to `false`.
286-
public func endLocation(
308+
func endLocation(
287309
converter: SourceLocationConverter,
288310
afterTrailingTrivia: Bool = false
289311
) -> SourceLocation {
290-
return base.endLocation(converter: converter,
291-
afterTrailingTrivia: afterTrailingTrivia)
312+
return _syntaxNode.endLocation(converter: converter,
313+
afterTrailingTrivia: afterTrailingTrivia)
292314
}
293315

294316
/// The source range, in the provided file, of this Syntax node.
@@ -299,14 +321,14 @@ extension Syntax {
299321
/// the node's start location. Defaults to `true`.
300322
/// - afterTrailingTrivia: Whether to skip trailing trivia when getting
301323
/// the node's end location. Defaults to `false`.
302-
public func sourceRange(
324+
func sourceRange(
303325
converter: SourceLocationConverter,
304326
afterLeadingTrivia: Bool = true,
305327
afterTrailingTrivia: Bool = false
306328
) -> SourceRange {
307-
return base.sourceRange(converter: converter,
308-
afterLeadingTrivia: afterLeadingTrivia,
309-
afterTrailingTrivia: afterTrailingTrivia)
329+
return _syntaxNode.sourceRange(converter: converter,
330+
afterLeadingTrivia: afterLeadingTrivia,
331+
afterTrailingTrivia: afterTrailingTrivia)
310332
}
311333
}
312334

0 commit comments

Comments
 (0)