@@ -159,6 +159,12 @@ package actor SwiftLanguageService: LanguageService, Sendable {
159
159
}
160
160
}
161
161
162
+ /// The build settings that were used to open the given files.
163
+ ///
164
+ /// - Note: Not all documents open in `SwiftLanguageService` are necessarily in this dictionary because files where
165
+ /// `buildSettings(for:)` returns `nil` are not included.
166
+ private var buildSettingsForOpenFiles : [ DocumentURI : SwiftCompileCommand ] = [ : ]
167
+
162
168
/// Calling `scheduleCall` on `refreshDiagnosticsDebouncer` schedules a `DiagnosticsRefreshRequest` to be sent to
163
169
/// to the client.
164
170
///
@@ -400,10 +406,12 @@ extension SwiftLanguageService {
400
406
try await self . sendSourcekitdRequest ( closeReq, fileContents: nil )
401
407
}
402
408
409
+ let buildSettings = await buildSettings ( for: snapshot. uri)
403
410
let openReq = openDocumentSourcekitdRequest (
404
411
snapshot: snapshot,
405
- compileCommand: await buildSettings ( for : snapshot . uri )
412
+ compileCommand: buildSettings
406
413
)
414
+ self . buildSettingsForOpenFiles [ snapshot. uri] = buildSettings
407
415
_ = await orLog ( " Re-opening document " ) {
408
416
try await self . sendSourcekitdRequest ( openReq, fileContents: snapshot. text)
409
417
}
@@ -420,11 +428,14 @@ extension SwiftLanguageService {
420
428
guard ( try ? documentManager. openDocuments. contains ( uri) ) ?? false else {
421
429
return
422
430
}
423
- // Close and re-open the document internally to inform sourcekitd to update the compile command. At the moment
424
- // there's no better way to do this.
425
- // Schedule the document re-open in the SourceKit-LSP server. This ensures that the re-open happens exclusively with
426
- // no other request running at the same time.
427
- sourceKitLSPServer? . handle ( ReopenTextDocumentNotification ( textDocument: TextDocumentIdentifier ( uri) ) )
431
+ let newBuildSettings = await self . buildSettings ( for: uri)
432
+ if newBuildSettings != buildSettingsForOpenFiles [ uri] {
433
+ // Close and re-open the document internally to inform sourcekitd to update the compile command. At the moment
434
+ // there's no better way to do this.
435
+ // Schedule the document re-open in the SourceKit-LSP server. This ensures that the re-open happens exclusively with
436
+ // no other request running at the same time.
437
+ sourceKitLSPServer? . handle ( ReopenTextDocumentNotification ( textDocument: TextDocumentIdentifier ( uri) ) )
438
+ }
428
439
}
429
440
430
441
package func documentDependenciesUpdated( _ uris: Set < DocumentURI > ) async {
@@ -445,8 +456,7 @@ extension SwiftLanguageService {
445
456
446
457
for uri in uris {
447
458
await macroExpansionManager. purge ( primaryFile: uri)
448
- // `documentUpdatedBuildSettings` already handles reopening the document, so we do that here as well.
449
- await self . documentUpdatedBuildSettings ( uri)
459
+ sourceKitLSPServer? . handle ( ReopenTextDocumentNotification ( textDocument: TextDocumentIdentifier ( uri) ) )
450
460
}
451
461
}
452
462
@@ -485,6 +495,7 @@ extension SwiftLanguageService {
485
495
await diagnosticReportManager. removeItemsFromCache ( with: notification. textDocument. uri)
486
496
487
497
let buildSettings = await self . buildSettings ( for: snapshot. uri)
498
+ buildSettingsForOpenFiles [ snapshot. uri] = buildSettings
488
499
489
500
let req = openDocumentSourcekitdRequest ( snapshot: snapshot, compileCommand: buildSettings)
490
501
_ = try ? await self . sendSourcekitdRequest ( req, fileContents: snapshot. text)
@@ -500,6 +511,7 @@ extension SwiftLanguageService {
500
511
cancelInFlightPublishDiagnosticsTask ( for: notification. textDocument. uri)
501
512
inFlightPublishDiagnosticsTasks [ notification. textDocument. uri] = nil
502
513
await diagnosticReportManager. removeItemsFromCache ( with: notification. textDocument. uri)
514
+ buildSettingsForOpenFiles [ notification. textDocument. uri] = nil
503
515
504
516
let req = closeDocumentSourcekitdRequest ( uri: notification. textDocument. uri)
505
517
_ = try ? await self . sendSourcekitdRequest ( req, fileContents: nil )
0 commit comments