Skip to content

Commit b5dfffe

Browse files
committed
Add tests for semantic tokens after edits
- Factor out openDocument in SemanticTokensTests - Test tokens with empty edits - Test replace until middle of token - Test replace until end of token - Test inserting spaces with tokens - Test inserting a newline with tokens - Add test removing newline with tokens - Add test for semantic multi-edit (variable renaming)
1 parent 8938112 commit b5dfffe

File tree

4 files changed

+280
-29
lines changed

4 files changed

+280
-29
lines changed

Sources/SourceKitLSP/DocumentManager.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,10 @@ public final class DocumentManager {
177177
document.latestTokens.withMutableTokensOfEachKind { tokens in
178178
tokens = Array(tokens.lazy
179179
.filter {
180-
// Only keep tokens that don't overlap with the edit range
181-
$0.start >= range.upperBound || range.lowerBound >= $0.sameLineEnd
180+
// Only keep tokens that don't overlap or bound with the edit range
181+
$0.start >= range.upperBound
182+
|| range.lowerBound >= $0.sameLineEnd
183+
|| range.isEmpty
182184
}
183185
.map {
184186
// Shift tokens after the edit range
@@ -264,7 +266,9 @@ public final class DocumentManager {
264266
// Remove all tokens in `range` (or the entire document if `range` is `nil`)
265267
document.latestTokens.lexical.removeAll { token in
266268
range.map {
267-
token.start <= $0.upperBound && $0.lowerBound <= token.sameLineEnd
269+
token.start <= $0.upperBound
270+
&& $0.lowerBound <= token.sameLineEnd
271+
&& !$0.isEmpty
268272
} ?? true
269273
}
270274

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,11 @@ extension SwiftLanguageServer {
519519
lastResponse = try? self.sourcekitd.sendSync(req)
520520
}
521521

522-
if let dict = lastResponse, let snapshot = self.documentManager.latestSnapshot(uri) {
522+
// SourceKit seems to respond with an empty substructure after sending an
523+
// empty range for an edit, causing all syntactic tokens to get removed
524+
// therefore we only update them if the range is non-empty.
525+
526+
if !(edit.range?.isEmpty ?? false), let dict = lastResponse, let snapshot = self.documentManager.latestSnapshot(uri) {
523527
self.updateLexicalAndSyntacticTokens(response: dict, for: snapshot)
524528
}
525529
}

0 commit comments

Comments
 (0)