@@ -15,30 +15,46 @@ import LanguageServerProtocol
15
15
import LSPLogging
16
16
import SKSupport
17
17
18
+ public struct DocumentTokens {
19
+ /// Lexical tokens, e.g. keywords, raw identifiers, ...
20
+ public var lexical : [ SemanticToken ] = [ ]
21
+ /// Syntactic tokens, e.g. declarations, etc.
22
+ public var syntactic : [ SemanticToken ] = [ ]
23
+ /// Semantic tokens, e.g. variable references, type references, ...
24
+ public var semantic : [ SemanticToken ] = [ ]
25
+
26
+ public var merged : [ SemanticToken ] {
27
+ [ lexical, syntactic, semantic] . reduce ( [ ] , mergeSemanticTokens)
28
+ }
29
+ public var sorted : [ SemanticToken ] {
30
+ merged. sorted { $0. start < $1. start }
31
+ }
32
+
33
+ public mutating func withEachKind( _ action: ( inout [ SemanticToken ] ) -> Void ) {
34
+ action ( & lexical)
35
+ action ( & syntactic)
36
+ action ( & semantic)
37
+ }
38
+ }
39
+
18
40
public struct DocumentSnapshot {
19
41
public var document : Document
20
42
public var version : Int
21
43
public var lineTable : LineTable
22
- public var syntacticTokens : [ SemanticToken ]
23
- public var semanticTokens : [ SemanticToken ]
44
+ public var tokens : DocumentTokens
24
45
25
46
public var text : String { lineTable. content }
26
47
27
- public var allTokens : [ SemanticToken ] { mergeSemanticTokens ( syntacticTokens, semanticTokens) }
28
- public var sortedTokens : [ SemanticToken ] { allTokens. sorted { $0. start < $1. start } }
29
-
30
48
public init (
31
49
document: Document ,
32
50
version: Int ,
33
51
lineTable: LineTable ,
34
- syntacticTokens: [ SemanticToken ] ,
35
- semanticTokens: [ SemanticToken ]
52
+ tokens: DocumentTokens
36
53
) {
37
54
self . document = document
38
55
self . version = version
39
56
self . lineTable = lineTable
40
- self . syntacticTokens = syntacticTokens
41
- self . semanticTokens = semanticTokens
57
+ self . tokens = tokens
42
58
}
43
59
44
60
func index( of pos: Position ) -> String . Index ? {
@@ -51,16 +67,14 @@ public final class Document {
51
67
public let language : Language
52
68
var latestVersion : Int
53
69
var latestLineTable : LineTable
54
- var latestSyntacticTokens : [ SemanticToken ]
55
- var latestSemanticTokens : [ SemanticToken ]
70
+ var latestTokens : DocumentTokens
56
71
57
72
init ( uri: DocumentURI , language: Language , version: Int , text: String ) {
58
73
self . uri = uri
59
74
self . language = language
60
75
self . latestVersion = version
61
76
self . latestLineTable = LineTable ( text)
62
- self . latestSyntacticTokens = [ ]
63
- self . latestSemanticTokens = [ ]
77
+ self . latestTokens = DocumentTokens ( )
64
78
}
65
79
66
80
/// **Not thread safe!** Use `DocumentManager.latestSnapshot` instead.
@@ -69,8 +83,7 @@ public final class Document {
69
83
document: self ,
70
84
version: latestVersion,
71
85
lineTable: latestLineTable,
72
- syntacticTokens: latestSyntacticTokens,
73
- semanticTokens: latestSemanticTokens
86
+ tokens: latestTokens
74
87
)
75
88
}
76
89
}
@@ -184,12 +197,11 @@ public final class DocumentManager {
184
197
} )
185
198
}
186
199
187
- update ( tokens: & document. latestSyntacticTokens)
188
- update ( tokens: & document. latestSemanticTokens)
200
+ document. latestTokens. withEachKind ( update ( tokens: ) )
189
201
} else {
190
202
// Full text replacement.
191
203
document. latestLineTable = LineTable ( edit. text)
192
- document. latestSyntacticTokens = [ ]
204
+ document. latestTokens = DocumentTokens ( )
193
205
}
194
206
195
207
}
@@ -213,17 +225,36 @@ public final class DocumentManager {
213
225
throw Error . missingDocument ( uri)
214
226
}
215
227
216
- document. latestSemanticTokens = tokens
228
+ document. latestTokens. semantic = tokens
229
+ return document. latestSnapshot
230
+ }
231
+ }
232
+
233
+ /// Replaces the syntactic tokens for a document.
234
+ ///
235
+ /// - parameter uri: The URI of the document to be updated
236
+ /// - parameter tokens: The tokens to be used
237
+ @discardableResult
238
+ public func replaceSyntacticTokens(
239
+ _ uri: DocumentURI ,
240
+ tokens: [ SemanticToken ]
241
+ ) throws -> DocumentSnapshot {
242
+ return try queue. sync {
243
+ guard let document = documents [ uri] else {
244
+ throw Error . missingDocument ( uri)
245
+ }
246
+
247
+ document. latestTokens. syntactic = tokens
217
248
return document. latestSnapshot
218
249
}
219
250
}
220
251
221
- /// Adds the given the syntactic tokens to a document.
252
+ /// Adds the given lexical tokens to a document.
222
253
///
223
254
/// - parameter uri: The URI of the document to be updated
224
255
/// - parameter tokens: The tokens to be added
225
256
@discardableResult
226
- public func addSyntacticTokens (
257
+ public func addLexicalTokens (
227
258
_ uri: DocumentURI ,
228
259
tokens: [ SemanticToken ]
229
260
) throws -> DocumentSnapshot {
@@ -241,10 +272,8 @@ public final class DocumentManager {
241
272
}
242
273
}
243
274
244
- removeAllOverlapping ( tokens: & document. latestSyntacticTokens)
245
- removeAllOverlapping ( tokens: & document. latestSemanticTokens)
246
-
247
- document. latestSyntacticTokens += tokens
275
+ document. latestTokens. withEachKind ( removeAllOverlapping ( tokens: ) )
276
+ document. latestTokens. lexical += tokens
248
277
}
249
278
250
279
return document. latestSnapshot
0 commit comments