@@ -179,71 +179,78 @@ struct AbsoluteRawSyntax {
179
179
}
180
180
}
181
181
182
- /// Indirect wrapper for a `Syntax` node to avoid cyclic inclusion of the
183
- /// `Syntax` struct in `SyntaxData`
184
- class SyntaxBox : CustomStringConvertible ,
185
- CustomDebugStringConvertible , TextOutputStreamable {
186
- let value : Syntax
182
+ /// SyntaxData is the underlying storage for each Syntax node.
183
+ ///
184
+ /// SyntaxData is an implementation detail, and should not be exposed to clients
185
+ /// of SwiftSyntax.
186
+ struct SyntaxData {
187
+ private enum Info {
188
+ case root( Root )
189
+ indirect case edge( Edge )
190
+
191
+ // For root node.
192
+ struct Root {
193
+ var arena : SyntaxArena
194
+ }
187
195
188
- init ( _ value: Syntax ) {
189
- self . value = value
196
+ // For non-root nodes.
197
+ struct Edge {
198
+ var parent : SyntaxData
199
+ var absoluteInfo : AbsoluteSyntaxInfo
200
+ }
190
201
}
191
202
192
- // SyntaxBox should be transparent in all descriptions
203
+ private let info : Info
204
+ let raw : RawSyntax
193
205
194
- /// A source-accurate description of this node.
195
- var description : String {
196
- return value. description
206
+ private var rootInfo : Info . Root {
207
+ switch info {
208
+ case . root( let info) : return info
209
+ case . edge( let info) : return info. parent. rootInfo
210
+ }
197
211
}
198
212
199
- /// Returns a description used by dump.
200
- var debugDescription : String {
201
- return value. debugDescription
213
+ private var edgeInfo : Info . Edge ? {
214
+ switch info {
215
+ case . root( _) : return nil
216
+ case . edge( let info) : return info
217
+ }
202
218
}
203
219
204
- /// Prints the raw value of this node to the provided stream.
205
- /// - Parameter stream: The stream to which to print the raw tree.
206
- func write< Target> ( to target: inout Target )
207
- where Target: TextOutputStream {
208
- return value. write ( to: & target)
220
+ private var rootArena : SyntaxArena {
221
+ rootInfo. arena
209
222
}
210
- }
211
223
212
- /// SyntaxData is the underlying storage for each Syntax node.
213
- ///
214
- /// SyntaxData is an implementation detail, and should not be exposed to clients
215
- /// of SwiftSyntax.
216
- struct SyntaxData {
217
- private enum ParentOrArena {
218
- // For non-root nodes.
219
- case parent( SyntaxBox )
220
- // For root node.
221
- case arena( SyntaxArena )
222
- }
223
- private let parentOrArena : ParentOrArena
224
- private var arena : SyntaxArena {
225
- switch parentOrArena {
226
- case . arena( let arena) : return arena
227
- case . parent( let parentBox) : return parentBox. value. data. arena
224
+ private var root : SyntaxData {
225
+ switch info {
226
+ case . root( _) : return self
227
+ case . edge( let info) : return info. parent. root
228
228
}
229
229
}
230
- var parent : Syntax ? {
231
- switch parentOrArena {
232
- case . parent( let parentBox) : return parentBox. value
233
- case . arena( _) : return nil
234
- }
230
+
231
+ var parent : SyntaxData ? {
232
+ edgeInfo? . parent
235
233
}
236
- let absoluteRaw : AbsoluteRawSyntax
237
234
238
- var raw : RawSyntax { return absoluteRaw. raw }
235
+ var absoluteInfo : AbsoluteSyntaxInfo {
236
+ edgeInfo? . absoluteInfo ?? . forRoot( raw)
237
+ }
239
238
240
- var indexInParent : Int { return Int ( absoluteRaw. info. indexInParent) }
239
+ var absoluteRaw : AbsoluteRawSyntax {
240
+ AbsoluteRawSyntax ( raw: raw, info: absoluteInfo)
241
+ }
241
242
242
- var nodeId : SyntaxIdentifier { return absoluteRaw. info. nodeId }
243
+ var indexInParent : Int {
244
+ Int ( absoluteInfo. indexInParent)
245
+ }
246
+
247
+ var nodeId : SyntaxIdentifier {
248
+ absoluteInfo. nodeId
249
+ }
243
250
244
251
/// The position of the start of this node's leading trivia
245
252
var position : AbsolutePosition {
246
- return absoluteRaw . position
253
+ AbsolutePosition ( utf8Offset : Int ( absoluteInfo . offset ) )
247
254
}
248
255
249
256
/// The position of the start of this node's content, skipping its trivia
@@ -258,26 +265,30 @@ struct SyntaxData {
258
265
259
266
/// The end position of this node, including its trivia.
260
267
var endPosition : AbsolutePosition {
261
- return absoluteRaw . endPosition
268
+ position + raw . totalLength
262
269
}
263
270
264
271
/// "designated" memberwise initializer of `SyntaxData`.
265
- private init ( _ absoluteRaw: AbsoluteRawSyntax , parentOrArena: ParentOrArena ) {
266
- self . parentOrArena = parentOrArena
267
- self . absoluteRaw = absoluteRaw
272
+ private init ( _ raw: RawSyntax , info: Info ) {
273
+ self . raw = raw
274
+ self . info = info
275
+ }
276
+
277
+ init ( _ raw: RawSyntax , parent: SyntaxData , absoluteInfo: AbsoluteSyntaxInfo ) {
278
+ self . init ( raw, info: . edge( . init( parent: parent, absoluteInfo: absoluteInfo) ) )
268
279
}
269
280
270
281
/// Creates a `SyntaxData` with the provided raw syntax and parent.
271
282
/// - Parameters:
272
283
/// - absoluteRaw: The underlying `AbsoluteRawSyntax` of this node.
273
284
/// - parent: The parent of this node, or `nil` if this node is the root.
274
285
init ( _ absoluteRaw: AbsoluteRawSyntax , parent: Syntax ) {
275
- self . init ( absoluteRaw, parentOrArena : . parent( SyntaxBox ( parent ) ) )
286
+ self . init ( absoluteRaw. raw , parent : parent. data , absoluteInfo : absoluteRaw . info )
276
287
}
277
288
278
289
/// Creates a `SyntaxData` for a root raw node.
279
290
static func forRoot( _ raw: RawSyntax ) -> SyntaxData {
280
- SyntaxData ( . forRoot ( raw) , parentOrArena : . arena ( raw. arena) )
291
+ SyntaxData ( raw, info : . root ( . init ( arena : raw. arena) ) )
281
292
}
282
293
283
294
/// Returns the child data at the provided index in this data's layout.
@@ -295,7 +306,7 @@ struct SyntaxData {
295
306
var iter = RawSyntaxChildren ( absoluteRaw) . makeIterator ( )
296
307
for _ in 0 ..< index { _ = iter. next ( ) }
297
308
let ( raw, info) = iter. next ( ) !
298
- return SyntaxData ( AbsoluteRawSyntax ( raw: raw !, info : info ) , parent : parent )
309
+ return SyntaxData ( raw!, parent : self , absoluteInfo : info )
299
310
}
300
311
301
312
/// Creates a copy of `self` and recursively creates `SyntaxData` nodes up to
@@ -308,7 +319,7 @@ struct SyntaxData {
308
319
// If we have a parent already, then ask our current parent to copy itself
309
320
// recursively up to the root.
310
321
if let parent = parent {
311
- let parentData = parent. data . replacingChild ( newRaw, at: indexInParent)
322
+ let parentData = parent. replacingChild ( newRaw, at: indexInParent)
312
323
let newParent = Syntax ( parentData)
313
324
return SyntaxData ( absoluteRaw. replacingSelf ( newRaw, newRootId: parentData. nodeId. rootId) , parent: newParent)
314
325
} else {
0 commit comments