@@ -20,7 +20,7 @@ internal struct RawSyntaxData {
20
20
case layout( Layout )
21
21
}
22
22
23
- /// Token tyoically created with `SyntaxFactory.makeToken()`.
23
+ /// Token typically created with `SyntaxFactory.makeToken()`.
24
24
struct MaterializedToken {
25
25
var tokenKind : RawTokenKind
26
26
var tokenText : SyntaxText
@@ -34,6 +34,7 @@ internal struct RawSyntaxData {
34
34
var kind : SyntaxKind
35
35
var layout : RawSyntaxBuffer
36
36
var byteLength : Int
37
+ /// Number of nodes in this subtree, excluding this node.
37
38
var descendantCount : Int
38
39
}
39
40
@@ -117,7 +118,7 @@ extension RawSyntax {
117
118
}
118
119
}
119
120
120
- /// Leading trivia text of this node if this node is a token. 'nil' otherwise .
121
+ /// The UTF-8 byte length of the leading trivia, assuming this node is a token.
121
122
var tokenLeadingTriviaByteLength : Int {
122
123
switch rawData. payload {
123
124
case . materializedToken( let dat) :
@@ -127,7 +128,7 @@ extension RawSyntax {
127
128
}
128
129
}
129
130
130
- /// Leading trivia text of this node if this node is a token. 'nil' otherwise .
131
+ /// The UTF-8 byte length of the trailing trivia, assuming this node is a token.
131
132
var tokenTrailingTriviaByteLength : Int {
132
133
switch rawData. payload {
133
134
case . materializedToken( let dat) :
@@ -142,7 +143,7 @@ extension RawSyntax {
142
143
case . materializedToken( let dat) :
143
144
return dat. leadingTrivia
144
145
case . layout( _) :
145
- preconditionFailure ( " tokenLeadingRawTriviaPieces is called on non-token raw syntax " )
146
+ preconditionFailure ( " ' tokenLeadingRawTriviaPieces' is called on non-token raw syntax" )
146
147
}
147
148
}
148
149
@@ -151,7 +152,7 @@ extension RawSyntax {
151
152
case . materializedToken( let dat) :
152
153
return dat. trailingTrivia
153
154
case . layout( _) :
154
- preconditionFailure ( " tokenTrailingRawTriviaPieces is called on non-token raw syntax " )
155
+ preconditionFailure ( " ' tokenTrailingRawTriviaPieces' is called on non-token raw syntax" )
155
156
}
156
157
}
157
158
}
@@ -211,11 +212,22 @@ extension RawSyntax {
211
212
}
212
213
213
214
var presence : SourcePresence {
214
- let isMissing = ( self . byteLength == 0 &&
215
- !self . isCollection &&
216
- !self . isUnknown &&
217
- !( isToken && self . rawTokenKind == . eof) )
218
- return isMissing ? . missing : . present
215
+ if self . byteLength != 0 {
216
+ // The node has source text associated with it. It's present.
217
+ return . present
218
+ }
219
+ if self . isCollection || self . isUnknown {
220
+ // We always consider collections 'present' because they can just be empty.
221
+ return . present
222
+ }
223
+ if isToken && self . rawTokenKind == . eof {
224
+ // The end of file token never has source code associated with it but we
225
+ // still consider it valid.
226
+ return . present
227
+ }
228
+
229
+ // If none of the above apply, the node is missing.
230
+ return . missing
219
231
}
220
232
221
233
/// The "width" of the node.
@@ -241,37 +253,29 @@ extension RawSyntax {
241
253
}
242
254
}
243
255
244
- /// Returns the leading `Trivia` length for a token node.
245
- /// - Returns: .zero if called on a layout node.
256
+ /// Returns the leading `Trivia` length, assuming this node is a token.
246
257
var tokenLeadingTriviaLength : SourceLength {
247
258
return SourceLength ( utf8Length: tokenLeadingTriviaByteLength)
248
259
}
249
260
250
- /// Returns the trailing `Trivia` length for a token node.
251
- /// - Returns: .zero if called on a layout node.
261
+ /// Returns the trailing `Trivia` length, assuming this node is a token.
252
262
var tokenTrailingTriviaLength : SourceLength {
253
263
return SourceLength ( utf8Length: tokenTrailingTriviaByteLength)
254
264
}
255
265
256
- /// Returns the leading `Trivia` for a token node.
257
- /// - Returns: nil if called on a layout node.
266
+ /// Returns the leading `Trivia`, assuming this node is a token.
258
267
func formTokenLeadingTrivia( ) -> Trivia ? {
259
- guard isToken else { return nil }
260
268
return Trivia ( pieces: tokenLeadingRawTriviaPieces. map ( { TriviaPiece ( raw: $0) } ) )
261
269
}
262
270
263
- /// Returns the trailing `Trivia` for a token node .
271
+ /// Returns the trailing `Trivia`, assuming this node is a token.
264
272
/// - Returns: nil if called on a layout node.
265
273
func formTokenTrailingTrivia( ) -> Trivia ? {
266
- guard isToken else { return nil }
267
274
return Trivia ( pieces: tokenTrailingRawTriviaPieces. map ( { TriviaPiece ( raw: $0) } ) )
268
275
}
269
276
270
- /// Passes token info to the provided closure as `UnsafeTokenText`.
271
- /// - Parameters:
272
- /// - body: The closure that accepts the `UnsafeTokenText` value. This value
273
- /// must not escape the closure.
274
- /// - Returns: Return value of `body`.
277
+ /// Calls `body` with the token text, assuming this node is a token. The token
278
+ /// text value must not escape the closure.
275
279
func withUnsafeTokenText< Result> (
276
280
_ body: ( SyntaxText ? ) -> Result
277
281
) -> Result {
@@ -282,6 +286,8 @@ extension RawSyntax {
282
286
Array ( children)
283
287
}
284
288
289
+ /// Assuming this node is a token, returns a `RawSyntax` node with the same
290
+ /// source text but with the token kind changed to `newValue`.
285
291
func withTokenKind( _ newValue: TokenKind ) -> RawSyntax {
286
292
switch payload {
287
293
case . materializedToken( var payload) :
@@ -294,7 +300,7 @@ extension RawSyntax {
294
300
payload. tokenText = text
295
301
return RawSyntax ( arena: arena, payload: . materializedToken( payload) )
296
302
default :
297
- preconditionFailure ( " withTokenKind() is called on non-token raw syntax " )
303
+ preconditionFailure ( " ' withTokenKind()' is called on non-token raw syntax" )
298
304
}
299
305
}
300
306
@@ -318,8 +324,8 @@ extension RawSyntax {
318
324
return nil
319
325
}
320
326
321
- /// Replaces the trailing trivia of the first token in this syntax tree by `trailingTrivia`.
322
- /// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
327
+ /// Replaces the trailing trivia of the last token in this syntax tree by `trailingTrivia`.
328
+ /// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
323
329
/// - Parameters:
324
330
/// - trailingTrivia: The trivia to attach.
325
331
func withTrailingTrivia( _ trailingTrivia: Trivia ) -> RawSyntax ? {
@@ -355,11 +361,13 @@ extension RawSyntax {
355
361
/// - Parameter kind: The token kind.
356
362
/// - Returns: A new RawSyntax `.token` with the provided kind, no
357
363
/// leading/trailing trivia, and `.missing` source presence.
358
- // @available(*, deprecated, message: "use 'makeEmptyToken ()' with SyntaxArena")
364
+ // @available(*, deprecated, message: "use 'makeMissingToken ()' with SyntaxArena")
359
365
static func missingToken( _ kind: TokenKind ) -> RawSyntax {
360
- . makeEmptyToken ( arena: . default, kind: kind)
366
+ . makeMissingToken ( arena: . default, kind: kind)
361
367
}
362
368
369
+ /// Assuming this node is a layout node, creates a new node of the same kind
370
+ /// but with children replaced by `elements`.
363
371
func replacingLayout< C: Collection > (
364
372
with elements: C ,
365
373
arena: SyntaxArena
@@ -453,6 +461,7 @@ extension RawSyntax {
453
461
with elements: C ,
454
462
arena: SyntaxArena
455
463
) -> RawSyntax where C. Element == RawSyntax ? {
464
+ precondition ( !self . isToken)
456
465
let newCount = children. count - range. count + elements. count
457
466
return . makeLayout( arena: arena,
458
467
kind: kind,
@@ -537,7 +546,7 @@ extension RawSyntax: TextOutputStreamable, CustomStringConvertible {
537
546
}
538
547
539
548
extension RawSyntax {
540
- /// Return the first `present` token of a layout node or self if it is a token .
549
+ /// Return the first token of a layout node that should be traversed by `viewMode` .
541
550
func firstToken( viewMode: SyntaxTreeViewMode ) -> RawSyntax ? {
542
551
guard viewMode. shouldTraverse ( node: self ) else { return nil }
543
552
if isToken { return self }
@@ -549,7 +558,7 @@ extension RawSyntax {
549
558
return nil
550
559
}
551
560
552
- /// Return the last `present` token of a layout node or self if it is a token .
561
+ /// Return the last token of a layout node that should be traversed by `viewMode` .
553
562
func lastToken( viewMode: SyntaxTreeViewMode ) -> RawSyntax ? {
554
563
guard viewMode. shouldTraverse ( node: self ) else { return nil }
555
564
if isToken { return self }
@@ -579,12 +588,17 @@ extension RawSyntax {
579
588
lastToken ( viewMode: . sourceAccurate) ? . tokenTrailingTriviaByteLength ?? 0
580
589
}
581
590
591
+ /// The length of this node’s content, without the first leading and the last
592
+ /// trailing trivia. Intermediate trivia inside a layout node is included in
593
+ /// this.
582
594
var contentByteLength : Int {
583
595
let result = byteLength - leadingTriviaByteLength - trailingTriviaByteLength
584
596
assert ( result >= 0 )
585
597
return result
586
598
}
587
599
600
+ /// The length of the token without leading or trailing trivia, assuming this
601
+ /// is a token node.
588
602
var tokenTextByteLength : Int {
589
603
switch rawData. payload {
590
604
case . materializedToken( let dat) :
@@ -612,6 +626,8 @@ extension RawSyntax {
612
626
}
613
627
}
614
628
629
+ // MARK: - Factories.
630
+
615
631
private func makeRawTriviaPieces( arena: SyntaxArena , leadingTrivia: Trivia , trailingTrivia: Trivia ) -> ( pieces: RawTriviaPieceBuffer , byteLength: Int ) {
616
632
let totalTriviaCount = leadingTrivia. count + trailingTrivia. count
617
633
@@ -626,19 +642,16 @@ private func makeRawTriviaPieces(arena: SyntaxArena, leadingTrivia: Trivia, trai
626
642
}
627
643
return ( pieces: . init( buffer) , byteLength: byteLength)
628
644
} else {
629
-
630
645
return ( pieces: . init( start: nil , count: 0 ) , byteLength: 0 )
631
646
}
632
647
}
633
648
634
- // MARK: - Factories.
635
-
636
649
extension RawSyntax {
637
650
/// "Designated" factory method to create a materialized token node.
638
651
///
639
652
/// This should not be called directly.
640
653
/// Use `makeMaterializedToken(arena:kind:leadingTrivia:trailingTrivia:)` or
641
- /// `makeEmptyToken (arena:kind:)` instead.
654
+ /// `makeMissingToken (arena:kind:)` instead.
642
655
///
643
656
/// - Parameters:
644
657
/// - arena: SyntaxArea to the result node data resides.
@@ -697,7 +710,7 @@ extension RawSyntax {
697
710
byteLength: numericCast ( byteLength) )
698
711
}
699
712
700
- static func makeEmptyToken (
713
+ static func makeMissingToken (
701
714
arena: SyntaxArena ,
702
715
kind: TokenKind
703
716
) -> RawSyntax {
0 commit comments