Skip to content

Commit 222f854

Browse files
committed
Eliminate SyntaxArena.default
SyntaxArena.default was a global arena which just leaked. Eliminate it, and make all Syntax factory/modifier API receive an optioal SyntaxArena parameter. If the parameter is omitted, use a new arena. rdar://101894396
1 parent ce11d7a commit 222f854

24 files changed

+9666
-7670
lines changed

CodeGeneration/Sources/generate-swiftsyntaxbuilder/BuildableCollectionNodesFile.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ let buildableCollectionNodesFile = SourceFile {
3333
if elementType.isBaseType && node.collectionElementChoices?.isEmpty ?? true {
3434
InitializerDecl(
3535
"""
36-
public init(_ elements: \(ArrayType(elementType: elementType.parameterType))) {
37-
self = \(node.type.syntaxBaseName)(elements.map { \(elementType.syntax)(fromProtocol: $0) })
36+
public init(_ elements: \(ArrayType(elementType: elementType.parameterType)), arena: SyntaxArena = SyntaxArena()) {
37+
self = \(node.type.syntaxBaseName)(elements.map { \(elementType.syntax)(fromProtocol: $0) }, arena: arena)
3838
}
3939
"""
4040
)

Sources/SwiftSyntax/Raw/RawSyntax.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ extension RawSyntax {
219219
/// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
220220
/// - Parameters:
221221
/// - leadingTrivia: The trivia to attach.
222-
func withLeadingTrivia(_ leadingTrivia: Trivia) -> RawSyntax? {
222+
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena) -> RawSyntax? {
223223
switch view {
224224
case .token(let tokenView):
225225
return .makeMaterializedToken(
@@ -229,7 +229,7 @@ extension RawSyntax {
229229
arena: arena)
230230
case .layout(let layoutView):
231231
for (index, child) in layoutView.children.enumerated() {
232-
if let replaced = child?.withLeadingTrivia(leadingTrivia) {
232+
if let replaced = child?.withLeadingTrivia(leadingTrivia, arena: arena) {
233233
return layoutView.replacingChild(at: index, with: replaced, arena: arena)
234234
}
235235
}
@@ -241,7 +241,7 @@ extension RawSyntax {
241241
/// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
242242
/// - Parameters:
243243
/// - trailingTrivia: The trivia to attach.
244-
func withTrailingTrivia(_ trailingTrivia: Trivia) -> RawSyntax? {
244+
func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena) -> RawSyntax? {
245245
switch view {
246246
case .token(let tokenView):
247247
return .makeMaterializedToken(
@@ -251,7 +251,7 @@ extension RawSyntax {
251251
arena: arena)
252252
case .layout(let layoutView):
253253
for (index, child) in layoutView.children.enumerated().reversed() {
254-
if let replaced = child?.withTrailingTrivia(trailingTrivia) {
254+
if let replaced = child?.withTrailingTrivia(trailingTrivia, arena: arena) {
255255
return layoutView.replacingChild(at: index, with: replaced, arena: arena)
256256
}
257257
}

Sources/SwiftSyntax/Raw/RawSyntaxTokenView.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,24 +151,24 @@ public struct RawSyntaxTokenView {
151151
/// Returns a `RawSyntax` node with the same source text but with the token
152152
/// kind changed to `newValue`.
153153
@_spi(RawSyntax)
154-
public func withKind(_ newValue: TokenKind) -> RawSyntax {
154+
public func withKind(_ newValue: TokenKind, arena: SyntaxArena) -> RawSyntax {
155155
switch raw.rawData.payload {
156156
case .parsedToken(_):
157157
// The wholeText can't be continuous anymore. Make a materialized token.
158158
return .makeMaterializedToken(
159159
kind: newValue,
160160
leadingTrivia: formLeadingTrivia(),
161161
trailingTrivia: formTrailingTrivia(),
162-
arena: raw.arena)
162+
arena: arena)
163163
case .materializedToken(var payload):
164164
let decomposed = newValue.decomposeToRaw()
165165
let rawKind = decomposed.rawKind
166-
let text: SyntaxText = (decomposed.string.map({raw.arena.intern($0)}) ??
166+
let text: SyntaxText = (decomposed.string.map({arena.intern($0)}) ??
167167
decomposed.rawKind.defaultText ??
168168
"")
169169
payload.tokenKind = rawKind
170170
payload.tokenText = text
171-
return RawSyntax(arena: raw.arena, payload: .materializedToken(payload))
171+
return RawSyntax(arena: arena, payload: .materializedToken(payload))
172172
default:
173173
preconditionFailure("'withTokenKind()' is called on non-token raw syntax")
174174
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,14 @@ public extension SyntaxProtocol {
481481

482482
/// Returns a new syntax node with its leading trivia replaced
483483
/// by the provided trivia.
484-
func withLeadingTrivia(_ leadingTrivia: Trivia) -> Self {
485-
return Self(Syntax(data.withLeadingTrivia(leadingTrivia)))!
484+
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena = SyntaxArena()) -> Self {
485+
return Self(Syntax(data.withLeadingTrivia(leadingTrivia, arena: arena)))!
486486
}
487487

488488
/// Returns a new syntax node with its trailing trivia replaced
489489
/// by the provided trivia.
490-
func withTrailingTrivia(_ trailingTrivia: Trivia) -> Self {
491-
return Self(Syntax(data.withTrailingTrivia(trailingTrivia)))!
490+
func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena = SyntaxArena()) -> Self {
491+
return Self(Syntax(data.withTrailingTrivia(trailingTrivia, arena: arena)))!
492492
}
493493

494494
/// Returns a new syntax node with its leading trivia removed.

Sources/SwiftSyntax/SyntaxArena.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@ struct SyntaxArenaRef: Equatable {
250250
}
251251
}
252252

253-
extension SyntaxArena {
254-
// FIXME: This is only for migration. All clients should move to "arena" model.
255-
//@available(*, deprecated, message: ".default SyntaxArena is subject to remove soon")
256-
public static let `default` = SyntaxArena()
257-
}
258-
259253
private func _defaultParseTriviaFunction(_ source: SyntaxText, _ position: TriviaPosition) -> [RawTriviaPiece] {
260254
preconditionFailure("Trivia parsing not supported")
261255
}

Sources/SwiftSyntax/SyntaxCollections.swift.gyb

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
117117
self._syntaxNode = Syntax(data)
118118
}
119119

120-
public init(_ children: [Element]) {
120+
public init(_ children: [Element], arena: SyntaxArena = SyntaxArena()) {
121121
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
122-
from: children.map { $0.raw }, arena: .default)
122+
from: children.map { $0.raw }, arena: arena)
123123
let data = SyntaxData.forRoot(raw)
124124
self.init(data)
125125
}
@@ -134,9 +134,10 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
134134
/// collection.
135135
/// - Returns: A new `${node.name}` with the new layout underlying it.
136136
internal func replacingLayout(
137-
_ layout: [RawSyntax?]) -> ${node.name} {
138-
let newRaw = layoutView.replacingLayout(with: layout, arena: .default)
139-
let newData = data.replacingSelf(newRaw)
137+
_ layout: [RawSyntax?],
138+
arena: SyntaxArena) -> ${node.name} {
139+
let newRaw = layoutView.replacingLayout(with: layout, arena: arena)
140+
let newData = data.replacingSelf(newRaw, arena: arena)
140141
return ${node.name}(newData)
141142
}
142143

@@ -145,10 +146,10 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
145146
///
146147
/// - Parameter syntax: The element to append.
147148
/// - Returns: A new `${node.name}` with that element appended to the end.
148-
public func appending(_ syntax: Element) -> ${node.name} {
149+
public func appending(_ syntax: Element, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
149150
var newLayout = layoutView.formLayoutArray()
150151
newLayout.append(syntax.raw)
151-
return replacingLayout(newLayout)
152+
return replacingLayout(newLayout, arena: arena)
152153
}
153154

154155
/// Creates a new `${node.name}` by prepending the provided syntax element
@@ -157,8 +158,8 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
157158
/// - Parameter syntax: The element to prepend.
158159
/// - Returns: A new `${node.name}` with that element prepended to the
159160
/// beginning.
160-
public func prepending(_ syntax: Element) -> ${node.name} {
161-
return inserting(syntax, at: 0)
161+
public func prepending(_ syntax: Element, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
162+
return inserting(syntax, at: 0, arena: arena)
162163
}
163164

164165
/// Creates a new `${node.name}` by inserting the provided syntax element
@@ -169,13 +170,13 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
169170
/// - index: The index at which to insert the element in the collection.
170171
///
171172
/// - Returns: A new `${node.name}` with that element appended to the end.
172-
public func inserting(_ syntax: Element, at index: Int) -> ${node.name} {
173+
public func inserting(_ syntax: Element, at index: Int, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
173174
var newLayout = layoutView.formLayoutArray()
174175
/// Make sure the index is a valid insertion index (0 to 1 past the end)
175176
precondition((newLayout.startIndex...newLayout.endIndex).contains(index),
176177
"inserting node at invalid index \(index)")
177178
newLayout.insert(syntax.raw, at: index)
178-
return replacingLayout(newLayout)
179+
return replacingLayout(newLayout, arena: arena)
179180
}
180181

181182
/// Creates a new `${node.name}` by replacing the syntax element
@@ -186,13 +187,13 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
186187
/// - syntax: The element to replace with.
187188
///
188189
/// - Returns: A new `${node.name}` with the new element at the provided index.
189-
public func replacing(childAt index: Int, with syntax: Element) -> ${node.name} {
190+
public func replacing(childAt index: Int, with syntax: Element, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
190191
var newLayout = layoutView.formLayoutArray()
191192
/// Make sure the index is a valid index for replacing
192193
precondition((newLayout.startIndex..<newLayout.endIndex).contains(index),
193194
"replacing node at invalid index \(index)")
194195
newLayout[index] = syntax.raw
195-
return replacingLayout(newLayout)
196+
return replacingLayout(newLayout, arena: arena)
196197
}
197198

198199
/// Creates a new `${node.name}` by removing the syntax element at the
@@ -201,55 +202,55 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
201202
/// - Parameter index: The index of the element to remove from the collection.
202203
/// - Returns: A new `${node.name}` with the element at the provided index
203204
/// removed.
204-
public func removing(childAt index: Int) -> ${node.name} {
205+
public func removing(childAt index: Int, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
205206
var newLayout = layoutView.formLayoutArray()
206207
newLayout.remove(at: index)
207-
return replacingLayout(newLayout)
208+
return replacingLayout(newLayout, arena: arena)
208209
}
209210

210211
/// Creates a new `${node.name}` by removing the first element.
211212
///
212213
/// - Returns: A new `${node.name}` with the first element removed.
213-
public func removingFirst() -> ${node.name} {
214+
public func removingFirst(arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
214215
var newLayout = layoutView.formLayoutArray()
215216
newLayout.removeFirst()
216-
return replacingLayout(newLayout)
217+
return replacingLayout(newLayout, arena: arena)
217218
}
218219

219220
/// Creates a new `${node.name}` by removing the last element.
220221
///
221222
/// - Returns: A new `${node.name}` with the last element removed.
222-
public func removingLast() -> ${node.name} {
223+
public func removingLast(arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
223224
var newLayout = layoutView.formLayoutArray()
224225
newLayout.removeLast()
225-
return replacingLayout(newLayout)
226+
return replacingLayout(newLayout, arena: arena)
226227
}
227228

228229
/// Returns a new `${node.name}` with its leading trivia replaced
229230
/// by the provided trivia.
230-
public func withLeadingTrivia(_ leadingTrivia: Trivia) -> ${node.name} {
231-
return ${node.name}(data.withLeadingTrivia(leadingTrivia))
231+
public func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
232+
return ${node.name}(data.withLeadingTrivia(leadingTrivia, arena: arena))
232233
}
233234

234235
/// Returns a new `${node.name}` with its trailing trivia replaced
235236
/// by the provided trivia.
236-
public func withTrailingTrivia(_ trailingTrivia: Trivia) -> ${node.name} {
237-
return ${node.name}(data.withTrailingTrivia(trailingTrivia))
237+
public func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
238+
return ${node.name}(data.withTrailingTrivia(trailingTrivia, arena: arena))
238239
}
239240

240241
/// Returns a new `${node.name}` with its leading trivia removed.
241-
public func withoutLeadingTrivia() -> ${node.name} {
242-
return withLeadingTrivia([])
242+
public func withoutLeadingTrivia(arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
243+
return withLeadingTrivia([], arena: arena)
243244
}
244245

245246
/// Returns a new `${node.name}` with its trailing trivia removed.
246-
public func withoutTrailingTrivia() -> ${node.name} {
247-
return withTrailingTrivia([])
247+
public func withoutTrailingTrivia(arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
248+
return withTrailingTrivia([], arena: arena)
248249
}
249250

250251
/// Returns a new `${node.name}` with all trivia removed.
251-
public func withoutTrivia() -> ${node.name} {
252-
return withoutLeadingTrivia().withoutTrailingTrivia()
252+
public func withoutTrivia(arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
253+
return withoutLeadingTrivia(arena: arena).withoutTrailingTrivia(arena: arena)
253254
}
254255

255256
/// The leading trivia (spaces, newlines, etc.) associated with this `${node.name}`.

Sources/SwiftSyntax/SyntaxData.swift

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,11 @@ struct SyntaxData {
325325
/// - parameter newRaw: The new RawSyntax that will back the new `Data`
326326
/// - returns: A tuple of both the new root node and the new data with the raw
327327
/// layout replaced.
328-
func replacingSelf(
329-
_ newRaw: RawSyntax) -> SyntaxData {
328+
func replacingSelf(_ newRaw: RawSyntax, arena: SyntaxArena) -> SyntaxData {
330329
// If we have a parent already, then ask our current parent to copy itself
331330
// recursively up to the root.
332331
if let parent = parent {
333-
let parentData = parent.replacingChild(newRaw, at: indexInParent)
332+
let parentData = parent.replacingChild(newRaw, at: indexInParent, arena: arena)
334333
let newParent = Syntax(parentData)
335334
return SyntaxData(absoluteRaw.replacingSelf(newRaw, newRootId: parentData.nodeId.rootId), parent: newParent)
336335
} else {
@@ -349,22 +348,22 @@ struct SyntaxData {
349348
/// - Returns: The new root node created by this operation, and the new child
350349
/// syntax data.
351350
/// - SeeAlso: replacingSelf(_:)
352-
func replacingChild(_ child: RawSyntax?, at index: Int) -> SyntaxData {
353-
let newRaw = raw.layoutView!.replacingChild(at: index, with: child, arena: .default)
354-
return replacingSelf(newRaw)
351+
func replacingChild(_ child: RawSyntax?, at index: Int, arena: SyntaxArena) -> SyntaxData {
352+
let newRaw = raw.layoutView!.replacingChild(at: index, with: child, arena: arena)
353+
return replacingSelf(newRaw, arena: arena)
355354
}
356355

357-
func withLeadingTrivia(_ leadingTrivia: Trivia) -> SyntaxData {
358-
if let raw = raw.withLeadingTrivia(leadingTrivia) {
359-
return replacingSelf(raw)
356+
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena) -> SyntaxData {
357+
if let raw = raw.withLeadingTrivia(leadingTrivia, arena: arena) {
358+
return replacingSelf(raw, arena: arena)
360359
} else {
361360
return self
362361
}
363362
}
364363

365-
func withTrailingTrivia(_ trailingTrivia: Trivia) -> SyntaxData {
366-
if let raw = raw.withTrailingTrivia(trailingTrivia) {
367-
return replacingSelf(raw)
364+
func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena) -> SyntaxData {
365+
if let raw = raw.withTrailingTrivia(trailingTrivia, arena: arena) {
366+
return replacingSelf(raw, arena: arena)
368367
} else {
369368
return self
370369
}

Sources/SwiftSyntax/SyntaxFactory.swift.gyb

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ public enum SyntaxFactory {
3131
@available(*, deprecated, message: "Use initializer on TokenSyntax")
3232
public static func makeToken(_ kind: TokenKind, presence: SourcePresence,
3333
leadingTrivia: Trivia = [],
34-
trailingTrivia: Trivia = []) -> TokenSyntax {
34+
trailingTrivia: Trivia = [],
35+
arena: SyntaxArena = SyntaxArena()) -> TokenSyntax {
3536
let raw = RawSyntax.makeMaterializedToken(kind: kind, leadingTrivia: leadingTrivia,
36-
trailingTrivia: trailingTrivia, presence: presence, arena: .default)
37+
trailingTrivia: trailingTrivia, presence: presence, arena: arena)
3738
let data = SyntaxData.forRoot(raw)
3839
return TokenSyntax(data)
3940
}
4041

4142
@available(*, deprecated, message: "Use initializer on UnknownSyntax")
42-
public static func makeUnknownSyntax(tokens: [TokenSyntax]) -> UnknownSyntax {
43+
public static func makeUnknownSyntax(tokens: [TokenSyntax],
44+
arena: SyntaxArena = SyntaxArena()) -> UnknownSyntax {
4345
let raw = RawSyntax.makeLayout(kind: .unknown,
44-
from: tokens.map { $0.raw }, arena: .default)
46+
from: tokens.map { $0.raw }, arena: arena)
4547
let data = SyntaxData.forRoot(raw)
4648
return UnknownSyntax(data)
4749
}
@@ -68,7 +70,7 @@ public enum SyntaxFactory {
6870
% end
6971
% child_params = ', '.join(child_params)
7072
@available(*, deprecated, message: "Use initializer on ${node.name}")
71-
public static func make${node.syntax_kind}(${child_params}) -> ${node.name} {
73+
public static func make${node.syntax_kind}(${child_params}, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
7274
let layout: [RawSyntax?] = [
7375
% for child in node.children:
7476
% if child.is_optional:
@@ -79,16 +81,17 @@ public enum SyntaxFactory {
7981
% end
8082
]
8183
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
82-
from: layout, arena: .default)
84+
from: layout, arena: arena)
8385
let data = SyntaxData.forRoot(raw)
8486
return ${node.name}(data)
8587
}
8688
% elif node.is_syntax_collection():
8789
@available(*, deprecated, message: "Use initializer on ${node.name}")
8890
public static func make${node.syntax_kind}(
89-
_ elements: [${node.collection_element_type}]) -> ${node.name} {
91+
_ elements: [${node.collection_element_type}],
92+
arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
9093
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
91-
from: elements.map { $0.raw }, arena: .default)
94+
from: elements.map { $0.raw }, arena: arena)
9295
let data = SyntaxData.forRoot(raw)
9396
return ${node.name}(data)
9497
}
@@ -97,7 +100,7 @@ public enum SyntaxFactory {
97100
% if not node.is_base():
98101
% default_presence = 'missing' if node.is_missing() else 'present'
99102
@available(*, deprecated, message: "Use initializer on ${node.name}")
100-
public static func makeBlank${node.syntax_kind}(presence: SourcePresence = .${default_presence}) -> ${node.name} {
103+
public static func makeBlank${node.syntax_kind}(presence: SourcePresence = .${default_presence}, arena: SyntaxArena = SyntaxArena()) -> ${node.name} {
101104
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .${node.swift_syntax_kind},
102105
from: [
103106
% for child in node.children:
@@ -107,7 +110,7 @@ public enum SyntaxFactory {
107110
${make_missing_swift_child(child)},
108111
% end
109112
% end
110-
], arena: .default))
113+
], arena: arena))
111114
return ${node.name}(data)
112115
}
113116
% end

0 commit comments

Comments
 (0)