Skip to content

Commit 075fb36

Browse files
committed
Extract DocumentTokens structure
1 parent 6b6e3c8 commit 075fb36

File tree

2 files changed

+68
-41
lines changed

2 files changed

+68
-41
lines changed

Sources/SourceKitLSP/DocumentManager.swift

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,46 @@ import LanguageServerProtocol
1515
import LSPLogging
1616
import SKSupport
1717

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+
1840
public struct DocumentSnapshot {
1941
public var document: Document
2042
public var version: Int
2143
public var lineTable: LineTable
22-
public var syntacticTokens: [SemanticToken]
23-
public var semanticTokens: [SemanticToken]
44+
public var tokens: DocumentTokens
2445

2546
public var text: String { lineTable.content }
2647

27-
public var allTokens: [SemanticToken] { mergeSemanticTokens(syntacticTokens, semanticTokens) }
28-
public var sortedTokens: [SemanticToken] { allTokens.sorted { $0.start < $1.start } }
29-
3048
public init(
3149
document: Document,
3250
version: Int,
3351
lineTable: LineTable,
34-
syntacticTokens: [SemanticToken],
35-
semanticTokens: [SemanticToken]
52+
tokens: DocumentTokens
3653
) {
3754
self.document = document
3855
self.version = version
3956
self.lineTable = lineTable
40-
self.syntacticTokens = syntacticTokens
41-
self.semanticTokens = semanticTokens
57+
self.tokens = tokens
4258
}
4359

4460
func index(of pos: Position) -> String.Index? {
@@ -51,16 +67,14 @@ public final class Document {
5167
public let language: Language
5268
var latestVersion: Int
5369
var latestLineTable: LineTable
54-
var latestSyntacticTokens: [SemanticToken]
55-
var latestSemanticTokens: [SemanticToken]
70+
var latestTokens: DocumentTokens
5671

5772
init(uri: DocumentURI, language: Language, version: Int, text: String) {
5873
self.uri = uri
5974
self.language = language
6075
self.latestVersion = version
6176
self.latestLineTable = LineTable(text)
62-
self.latestSyntacticTokens = []
63-
self.latestSemanticTokens = []
77+
self.latestTokens = DocumentTokens()
6478
}
6579

6680
/// **Not thread safe!** Use `DocumentManager.latestSnapshot` instead.
@@ -69,8 +83,7 @@ public final class Document {
6983
document: self,
7084
version: latestVersion,
7185
lineTable: latestLineTable,
72-
syntacticTokens: latestSyntacticTokens,
73-
semanticTokens: latestSemanticTokens
86+
tokens: latestTokens
7487
)
7588
}
7689
}
@@ -184,12 +197,11 @@ public final class DocumentManager {
184197
})
185198
}
186199

187-
update(tokens: &document.latestSyntacticTokens)
188-
update(tokens: &document.latestSemanticTokens)
200+
document.latestTokens.withEachKind(update(tokens:))
189201
} else {
190202
// Full text replacement.
191203
document.latestLineTable = LineTable(edit.text)
192-
document.latestSyntacticTokens = []
204+
document.latestTokens = DocumentTokens()
193205
}
194206

195207
}
@@ -213,17 +225,36 @@ public final class DocumentManager {
213225
throw Error.missingDocument(uri)
214226
}
215227

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
217248
return document.latestSnapshot
218249
}
219250
}
220251

221-
/// Adds the given the syntactic tokens to a document.
252+
/// Adds the given lexical tokens to a document.
222253
///
223254
/// - parameter uri: The URI of the document to be updated
224255
/// - parameter tokens: The tokens to be added
225256
@discardableResult
226-
public func addSyntacticTokens(
257+
public func addLexicalTokens(
227258
_ uri: DocumentURI,
228259
tokens: [SemanticToken]
229260
) throws -> DocumentSnapshot {
@@ -241,10 +272,8 @@ public final class DocumentManager {
241272
}
242273
}
243274

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
248277
}
249278

250279
return document.latestSnapshot

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -161,26 +161,24 @@ public final class SwiftLanguageServer: ToolchainLanguageServer {
161161
}
162162
}
163163

164-
/// Update syntactic tokens for the given `snapshot`.
165-
func updateSyntacticTokens(
164+
/// Update lexical and syntactic tokens for the given `snapshot`.
165+
func updateLexicalAndSyntacticTokens(
166166
response: SKDResponseDictionary,
167167
for snapshot: DocumentSnapshot
168168
) {
169169
let uri = snapshot.document.uri
170-
guard let skTokens: SKDResponseArray = response[keys.syntaxmap] else {
171-
return
172-
}
173-
174170
let tokenParser = SemanticTokenParser(
175171
sourcekitd: sourcekitd,
176172
snapshot: snapshot
177173
)
178-
let tokens = tokenParser.parseTokens(skTokens)
179174

180-
do {
181-
try documentManager.addSyntacticTokens(uri, tokens: tokens)
182-
} catch {
183-
log("updating syntactic tokens for \(uri) failed: \(error)", level: .warning)
175+
if let syntaxMap: SKDResponseArray = response[keys.syntaxmap] {
176+
let tokens = tokenParser.parseTokens(syntaxMap)
177+
do {
178+
try documentManager.addLexicalTokens(uri, tokens: tokens)
179+
} catch {
180+
log("updating lexical tokens for \(uri) failed: \(error)", level: .warning)
181+
}
184182
}
185183
}
186184

@@ -367,7 +365,7 @@ extension SwiftLanguageServer {
367365
}
368366
self.publishDiagnostics(
369367
response: dict, for: snapshot, compileCommand: compileCmd)
370-
self.updateSyntacticTokens(response: dict, for: snapshot)
368+
self.updateLexicalAndSyntacticTokens(response: dict, for: snapshot)
371369
}
372370

373371
public func documentUpdatedBuildSettings(_ uri: DocumentURI, change: FileBuildSettingsChange) {
@@ -432,7 +430,7 @@ extension SwiftLanguageServer {
432430
return
433431
}
434432
self.publishDiagnostics(response: dict, for: snapshot, compileCommand: compileCommand)
435-
self.updateSyntacticTokens(response: dict, for: snapshot)
433+
self.updateLexicalAndSyntacticTokens(response: dict, for: snapshot)
436434
}
437435
}
438436

@@ -489,7 +487,7 @@ extension SwiftLanguageServer {
489487
if let dict = lastResponse, let snapshot = snapshot {
490488
let compileCommand = self.commandsByFile[note.textDocument.uri]
491489
self.publishDiagnostics(response: dict, for: snapshot, compileCommand: compileCommand)
492-
self.updateSyntacticTokens(response: dict, for: snapshot)
490+
self.updateLexicalAndSyntacticTokens(response: dict, for: snapshot)
493491
}
494492
}
495493
}
@@ -776,7 +774,7 @@ extension SwiftLanguageServer {
776774
return
777775
}
778776

779-
let tokens = snapshot.sortedTokens
777+
let tokens = snapshot.tokens.sorted
780778
let encodedTokens = encodeToIntArray(semanticTokens: tokens)
781779

782780
req.reply(DocumentSemanticTokensResponse(data: encodedTokens))
@@ -799,7 +797,7 @@ extension SwiftLanguageServer {
799797
return
800798
}
801799

802-
let tokens = snapshot.sortedTokens.filter { $0.range.overlaps(range) }
800+
let tokens = snapshot.tokens.sorted.filter { $0.range.overlaps(range) }
803801
let encodedTokens = encodeToIntArray(semanticTokens: tokens)
804802

805803
req.reply(DocumentSemanticTokensResponse(data: encodedTokens))

0 commit comments

Comments
 (0)