@@ -119,6 +119,10 @@ public final class SwiftLanguageServer: ToolchainLanguageServer {
119
119
120
120
var commandsByFile : [ DocumentURI : SwiftCompileCommand ] = [ : ]
121
121
122
+ var documentParseTransition : [ DocumentURI : ( SourceFileSyntax , IncrementalParseNodeAffectRangeCollector ) ] = [ : ]
123
+
124
+ public var documentReusedNodeCollector : [ DocumentURI : IncrementalParseReusedNodeCollector ] = [ : ]
125
+
122
126
var keys : sourcekitd_keys { return sourcekitd. keys }
123
127
var requests : sourcekitd_requests { return sourcekitd. requests }
124
128
var values : sourcekitd_values { return sourcekitd. values }
@@ -198,13 +202,31 @@ public final class SwiftLanguageServer: ToolchainLanguageServer {
198
202
199
203
/// Returns the updated lexical tokens for the given `snapshot`.
200
204
private func updateSyntaxTree(
201
- for snapshot: DocumentSnapshot
205
+ for snapshot: DocumentSnapshot ,
206
+ with edits: [ IncrementalEdit ] ? = nil
202
207
) -> DocumentTokens {
203
208
logExecutionTime ( level: . debug) {
204
209
var docTokens = snapshot. tokens
210
+ let documentURI = snapshot. document. uri
211
+
212
+ var reusedNodeCollector = documentReusedNodeCollector [ documentURI]
213
+ if reusedNodeCollector == nil {
214
+ documentReusedNodeCollector [ documentURI] = IncrementalParseReusedNodeCollector ( )
215
+ reusedNodeCollector = documentReusedNodeCollector [ documentURI]
216
+ }
217
+
218
+ var parseTransition : IncrementalParseTransition ? = nil
219
+ if let previousTree = documentParseTransition [ documentURI] ? . 0 ,
220
+ let nodeAffectRange = documentParseTransition [ documentURI] ? . 1 {
221
+ parseTransition = IncrementalParseTransition ( previousTree: previousTree, edits: ConcurrentEdits ( fromSequential: edits ?? [ ] ) , nodeAffectRangeCollector: nodeAffectRange, reusedNodeDelegate: reusedNodeCollector)
222
+ }
223
+ let ( tree, nodeAffectRangeCollector) = Parser . parse (
224
+ source: snapshot. text, parseTransition: parseTransition)
205
225
206
- docTokens. syntaxTree = Parser . parse ( source : snapshot . text )
226
+ docTokens. syntaxTree = tree
207
227
228
+ documentParseTransition [ documentURI] = ( tree, nodeAffectRangeCollector)
229
+
208
230
return docTokens
209
231
}
210
232
}
@@ -527,27 +549,37 @@ extension SwiftLanguageServer {
527
549
528
550
public func changeDocument( _ note: DidChangeTextDocumentNotification ) {
529
551
let keys = self . keys
552
+ var edits : [ IncrementalEdit ] = [ ]
530
553
531
554
self . queue. async {
532
555
var lastResponse : SKDResponseDictionary ? = nil
533
556
534
- let snapshot = self . documentManager. edit ( note) { ( before: DocumentSnapshot , edit: TextDocumentContentChangeEvent ) in
557
+ let snapshot = self . documentManager. edit ( note) {
558
+ ( before: DocumentSnapshot , edit: TextDocumentContentChangeEvent ) in
535
559
let req = SKDRequestDictionary ( sourcekitd: self . sourcekitd)
536
560
req [ keys. request] = self . requests. editor_replacetext
537
561
req [ keys. name] = note. textDocument. uri. pseudoPath
538
562
539
563
if let range = edit. range {
540
- guard let offset = before. utf8Offset ( of: range. lowerBound) , let end = before. utf8Offset ( of: range. upperBound) else {
564
+ guard let offset = before. utf8Offset ( of: range. lowerBound) ,
565
+ let end = before. utf8Offset ( of: range. upperBound)
566
+ else {
541
567
fatalError ( " invalid edit \( range) " )
542
568
}
543
569
570
+ let length = end - offset
544
571
req [ keys. offset] = offset
545
- req [ keys. length] = end - offset
572
+ req [ keys. length] = length
546
573
574
+ edits. append ( IncrementalEdit ( offset: offset, length: length, replacementLength: edit. text. utf8. count)
575
+ )
547
576
} else {
548
577
// Full text
578
+ let length = before. text. utf8. count
549
579
req [ keys. offset] = 0
550
- req [ keys. length] = before. text. utf8. count
580
+ req [ keys. length] = length
581
+
582
+ edits. append ( IncrementalEdit ( offset: 0 , length: length, replacementLength: edit. text. utf8. count) )
551
583
}
552
584
553
585
req [ keys. sourcetext] = edit. text
@@ -556,7 +588,7 @@ extension SwiftLanguageServer {
556
588
self . adjustDiagnosticRanges ( of: note. textDocument. uri, for: edit)
557
589
} updateDocumentTokens: { ( after: DocumentSnapshot ) in
558
590
if lastResponse != nil {
559
- return self . updateSyntaxTree ( for: after)
591
+ return self . updateSyntaxTree ( for: after, with : edits )
560
592
} else {
561
593
return DocumentTokens ( )
562
594
}
0 commit comments