@@ -19,12 +19,10 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
19
19
indirect case nonRoot( NonRoot )
20
20
21
21
// For root node.
22
- struct Root : @unchecked Sendable {
23
- // Unchecked conformance to sendable is fine because `arena` is not
24
- // accessible. It is just used to keep the arena alive.
25
- private var arena : SyntaxArena
22
+ struct Root : Sendable {
23
+ private var arena : RetainedSyntaxArena
26
24
27
- init ( arena: SyntaxArena ) {
25
+ init ( arena: RetainedSyntaxArena ) {
28
26
self . arena = arena
29
27
}
30
28
}
@@ -125,11 +123,16 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
125
123
/// - rawNodeArena: The arena in which `raw` is allocated. It is passed to
126
124
/// make sure the arena doesn’t get de-allocated before the ``Syntax``
127
125
/// has a chance to retain it.
128
- static func forRoot( _ raw: RawSyntax , rawNodeArena: SyntaxArena ) -> Syntax {
126
+ static func forRoot( _ raw: RawSyntax , rawNodeArena: RetainedSyntaxArena ) -> Syntax {
129
127
precondition ( rawNodeArena == raw. arenaReference)
130
128
return Syntax ( raw, info: . root( . init( arena: rawNodeArena) ) )
131
129
}
132
130
131
+ static func forRoot( _ raw: RawSyntax , rawNodeArena: SyntaxArena ) -> Syntax {
132
+ precondition ( rawNodeArena == raw. arenaReference)
133
+ return Syntax ( raw, info: . root( . init( arena: RetainedSyntaxArena ( rawNodeArena) ) ) )
134
+ }
135
+
133
136
/// Returns the child data at the provided index in this data's layout.
134
137
/// - Note: This has O(n) performance, prefer using a proper Sequence type
135
138
/// if applicable, instead of this.
@@ -157,7 +160,7 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
157
160
/// - allocationArena: The arena in which new nodes should be allocated
158
161
/// - Returns: A syntax tree with all parents where this node has been
159
162
/// replaced by `newRaw`
160
- func replacingSelf( _ newRaw: RawSyntax , rawNodeArena: SyntaxArena , allocationArena: SyntaxArena ) -> Syntax {
163
+ func replacingSelf( _ newRaw: RawSyntax , rawNodeArena: RetainedSyntaxArena , allocationArena: SyntaxArena ) -> Syntax {
161
164
precondition ( newRaw. arenaReference == rawNodeArena)
162
165
// If we have a parent already, then ask our current parent to copy itself
163
166
// recursively up to the root.
@@ -182,45 +185,50 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
182
185
/// - Returns: The new root node created by this operation, and the new child
183
186
/// syntax data.
184
187
/// - SeeAlso: replacingSelf(_:)
185
- func replacingChild( at index: Int , with newChild: RawSyntax ? , rawNodeArena: SyntaxArena ? , allocationArena: SyntaxArena ) -> Syntax {
188
+ func replacingChild( at index: Int , with newChild: RawSyntax ? , rawNodeArena: RetainedSyntaxArena ? , allocationArena: SyntaxArena ) -> Syntax {
186
189
precondition ( newChild == nil || ( rawNodeArena != nil && newChild!. arenaReference == rawNodeArena!) )
187
190
// After newRaw has been allocated in `allocationArena`, `rawNodeArena` will
188
191
// be a child arena of `allocationArena` and thus, `allocationArena` will
189
192
// keep `newChild` alive.
190
193
let newRaw = withExtendedLifetime ( rawNodeArena) {
191
194
raw. layoutView!. replacingChild ( at: index, with: newChild, arena: allocationArena)
192
195
}
193
- return replacingSelf ( newRaw, rawNodeArena: allocationArena, allocationArena: allocationArena)
196
+ return replacingSelf ( newRaw, rawNodeArena: RetainedSyntaxArena ( allocationArena) , allocationArena: allocationArena)
197
+ }
198
+
199
+ /// Same as `replacingChild(at:with:rawNodeArena:allocationArena:)` but takes a `__SyntaxArena` instead of a `RetainedSyntaxArena`.
200
+ func replacingChild( at index: Int , with newChild: RawSyntax ? , rawNodeArena: SyntaxArena ? , allocationArena: SyntaxArena ) -> Syntax {
201
+ return self . replacingChild ( at: index, with: newChild, rawNodeArena: rawNodeArena. map ( RetainedSyntaxArena . init) , allocationArena: allocationArena)
194
202
}
195
203
196
204
/// Identical to `replacingChild(at: Int, with: RawSyntax?, arena: SyntaxArena)`
197
205
/// that ensures that the arena of`newChild` doesn’t get de-allocated before
198
206
/// `newChild` has been addded to the result.
199
207
func replacingChild( at index: Int , with newChild: Syntax ? , arena: SyntaxArena ) -> Syntax {
200
208
return withExtendedLifetime ( newChild) {
201
- return replacingChild ( at: index, with: newChild? . raw, rawNodeArena: newChild? . raw. arena , allocationArena: arena)
209
+ return replacingChild ( at: index, with: newChild? . raw, rawNodeArena: newChild? . raw. arenaReference . retained , allocationArena: arena)
202
210
}
203
211
}
204
212
205
213
func withLeadingTrivia( _ leadingTrivia: Trivia , arena: SyntaxArena ) -> Syntax {
206
214
if let raw = raw. withLeadingTrivia ( leadingTrivia, arena: arena) {
207
- return replacingSelf ( raw, rawNodeArena: arena, allocationArena: arena)
215
+ return replacingSelf ( raw, rawNodeArena: RetainedSyntaxArena ( arena) , allocationArena: arena)
208
216
} else {
209
217
return self
210
218
}
211
219
}
212
220
213
221
func withTrailingTrivia( _ trailingTrivia: Trivia , arena: SyntaxArena ) -> Syntax {
214
222
if let raw = raw. withTrailingTrivia ( trailingTrivia, arena: arena) {
215
- return replacingSelf ( raw, rawNodeArena: arena, allocationArena: arena)
223
+ return replacingSelf ( raw, rawNodeArena: RetainedSyntaxArena ( arena) , allocationArena: arena)
216
224
} else {
217
225
return self
218
226
}
219
227
}
220
228
221
229
func withPresence( _ presence: SourcePresence , arena: SyntaxArena ) -> Syntax {
222
230
if let raw = raw. tokenView? . withPresence ( presence, arena: arena) {
223
- return replacingSelf ( raw, rawNodeArena: arena, allocationArena: arena)
231
+ return replacingSelf ( raw, rawNodeArena: RetainedSyntaxArena ( arena) , allocationArena: arena)
224
232
} else {
225
233
return self
226
234
}
@@ -234,10 +242,15 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
234
242
}
235
243
236
244
@_spi ( RawSyntax)
237
- public init ( raw: RawSyntax , rawNodeArena: __shared SyntaxArena ) {
245
+ public init ( raw: RawSyntax , rawNodeArena: __shared RetainedSyntaxArena ) {
238
246
self = . forRoot( raw, rawNodeArena: rawNodeArena)
239
247
}
240
248
249
+ @_spi ( RawSyntax)
250
+ public init ( raw: RawSyntax , rawNodeArena: __shared SyntaxArena) {
251
+ self = . forRoot( raw, rawNodeArena: RetainedSyntaxArena ( rawNodeArena) )
252
+ }
253
+
241
254
/// Create a ``Syntax`` node from a specialized syntax node.
242
255
public init ( _ syntax: some SyntaxProtocol ) {
243
256
self = syntax. _syntaxNode
0 commit comments