10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
- import Foundation
14
-
15
13
/// Box a value type into a reference type
16
14
class Box < T> {
17
15
let value : T
@@ -34,52 +32,21 @@ fileprivate enum RawSyntaxData {
34
32
/// are immutable and can be freely shared between syntax nodes.
35
33
final class RawSyntax {
36
34
fileprivate let data : RawSyntaxData
35
+ let totalLength : SourceLength
37
36
let presence : SourcePresence
38
37
39
- var _contentLength = LazyNonThreadSafeCache < Box < SourceLength > > ( )
40
-
41
- /// The length of this node excluding its leading and trailing trivia
42
- var contentLength : SourceLength {
43
- return _contentLength. value ( {
44
- if isMissing {
45
- return Box ( SourceLength . zero)
46
- }
47
- switch data {
48
- case . node( kind: _, layout: let layout) :
49
- let firstElementIndex = layout. firstIndex ( where: { $0 != nil } )
50
- let lastElementIndex = layout. lastIndex ( where: { $0 != nil } )
51
-
52
- var contentLength = SourceLength . zero
53
- for (offset, element) in layout. enumerated ( ) {
54
- guard let element = element else {
55
- continue
56
- }
57
- // Skip the node's leading trivia
58
- if offset != firstElementIndex {
59
- contentLength += element. leadingTriviaLength
60
- }
61
- contentLength += element. contentLength
62
- // Skip the node's trailing trivia
63
- if offset != lastElementIndex {
64
- contentLength += element. trailingTriviaLength
65
- }
66
- }
67
- return Box ( contentLength)
68
- case . token( kind: let kind, leadingTrivia: _, trailingTrivia: _) :
69
- return Box ( SourceLength ( of: kind. text) )
70
- }
71
- } ) . value
72
- }
73
-
74
- init ( kind: SyntaxKind , layout: [ RawSyntax ? ] , presence: SourcePresence ) {
38
+ init ( kind: SyntaxKind , layout: [ RawSyntax ? ] , length: SourceLength ,
39
+ presence: SourcePresence ) {
75
40
self . data = . node( kind: kind, layout: layout)
41
+ self . totalLength = length
76
42
self . presence = presence
77
43
}
78
44
79
45
init ( kind: TokenKind , leadingTrivia: Trivia , trailingTrivia: Trivia ,
80
- presence: SourcePresence ) {
46
+ length : SourceLength , presence: SourcePresence ) {
81
47
self . data = . token( kind: kind, leadingTrivia: leadingTrivia,
82
48
trailingTrivia: trailingTrivia)
49
+ self . totalLength = length
83
50
self . presence = presence
84
51
}
85
52
@@ -129,7 +96,8 @@ final class RawSyntax {
129
96
/// - Returns: A new RawSyntax `.node` with the provided kind and layout, with
130
97
/// `.missing` source presence.
131
98
static func missing( _ kind: SyntaxKind ) -> RawSyntax {
132
- return RawSyntax ( kind: kind, layout: [ ] , presence: . missing)
99
+ return RawSyntax ( kind: kind, layout: [ ] , length: SourceLength . zero,
100
+ presence: . missing)
133
101
}
134
102
135
103
/// Creates a RawSyntax token that's marked missing in the source with the
@@ -138,7 +106,8 @@ final class RawSyntax {
138
106
/// - Returns: A new RawSyntax `.token` with the provided kind, no
139
107
/// leading/trailing trivia, and `.missing` source presence.
140
108
static func missingToken( _ kind: TokenKind ) -> RawSyntax {
141
- return RawSyntax ( kind: kind, leadingTrivia: [ ] , trailingTrivia: [ ] , presence: . missing)
109
+ return RawSyntax ( kind: kind, leadingTrivia: [ ] , trailingTrivia: [ ] ,
110
+ length: SourceLength . zero, presence: . missing)
142
111
}
143
112
144
113
/// Returns a new RawSyntax node with the provided layout instead of the
@@ -149,7 +118,8 @@ final class RawSyntax {
149
118
func replacingLayout( _ newLayout: [ RawSyntax ? ] ) -> RawSyntax {
150
119
switch data {
151
120
case let . node( kind, _) :
152
- return RawSyntax ( kind: kind, layout: newLayout, presence: presence)
121
+ return . createAndCalcLength( kind: kind, layout: newLayout,
122
+ presence: presence)
153
123
case . token( _, _, _) : return self
154
124
}
155
125
}
@@ -251,9 +221,51 @@ extension RawSyntax {
251
221
return trailingTrivia? . sourceLength ?? . zero
252
222
}
253
223
254
- /// The length of this node including all of its trivia
255
- var totalLength : SourceLength {
256
- return leadingTriviaLength + contentLength + trailingTriviaLength
224
+ /// The length of this node excluding its leading and trailing trivia.
225
+ var contentLength : SourceLength {
226
+ return totalLength - ( leadingTriviaLength + trailingTriviaLength)
227
+ }
228
+
229
+ /// Convenience function to create a RawSyntax when its byte length is not
230
+ /// known in advance, e.g. it is programmatically constructed instead of
231
+ /// created by the parser.
232
+ ///
233
+ /// This is a separate function than in the initializer to make it more
234
+ /// explicit and visible in the code for the instances where we don't have
235
+ /// the length of the raw node already available.
236
+ static func createAndCalcLength( kind: SyntaxKind , layout: [ RawSyntax ? ] ,
237
+ presence: SourcePresence ) -> RawSyntax {
238
+ let length : SourceLength
239
+ if case . missing = presence {
240
+ length = SourceLength . zero
241
+ } else {
242
+ var totalen = SourceLength . zero
243
+ for child in layout {
244
+ totalen += child? . totalLength ?? . zero
245
+ }
246
+ length = totalen
247
+ }
248
+ return . init( kind: kind, layout: layout, length: length, presence: presence)
249
+ }
250
+
251
+ /// Convenience function to create a RawSyntax when its byte length is not
252
+ /// known in advance, e.g. it is programmatically constructed instead of
253
+ /// created by the parser.
254
+ ///
255
+ /// This is a separate function than in the initializer to make it more
256
+ /// explicit and visible in the code for the instances where we don't have
257
+ /// the length of the raw node already available.
258
+ static func createAndCalcLength( kind: TokenKind , leadingTrivia: Trivia ,
259
+ trailingTrivia: Trivia , presence: SourcePresence ) -> RawSyntax {
260
+ let length : SourceLength
261
+ if case . missing = presence {
262
+ length = SourceLength . zero
263
+ } else {
264
+ length = kind. sourceLength + leadingTrivia. sourceLength +
265
+ trailingTrivia. sourceLength
266
+ }
267
+ return . init( kind: kind, leadingTrivia: leadingTrivia,
268
+ trailingTrivia: trailingTrivia, length: length, presence: presence)
257
269
}
258
270
}
259
271
0 commit comments