Skip to content

Commit 9c410ef

Browse files
committed
Make buildSettings as part of the key to the cache
1 parent 86a0f34 commit 9c410ef

File tree

2 files changed

+42
-19
lines changed

2 files changed

+42
-19
lines changed

Sources/SourceKitLSP/Swift/DiagnosticReportManager.swift

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ actor DiagnosticReportManager {
2424
private nonisolated var keys: sourcekitd_keys { return sourcekitd.keys }
2525
private nonisolated var requests: sourcekitd_requests { return sourcekitd.requests }
2626

27-
/// The cache that stores reports for snapshot ids
27+
/// The cache that stores reports for snapshot id and buildSettings
2828
///
2929
/// Conceptually, this is a dictionary. To prevent excessive memory usage we
3030
/// only keep `cacheSize` entries within the array. Older entries are at the
3131
/// end of the list, newer entries at the front.
3232
private var reportCache:
3333
[(
3434
snapshotID: DocumentSnapshot.ID,
35+
buildSettings: SwiftCompileCommand?,
3536
report: RelatedFullDocumentDiagnosticReport
3637
)] = []
3738

@@ -55,30 +56,41 @@ actor DiagnosticReportManager {
5556
func diagnosticReport(for snapshot: DocumentSnapshot, buildSettings: SwiftCompileCommand?, useCache: Bool = false)
5657
async throws -> RelatedFullDocumentDiagnosticReport
5758
{
58-
if useCache, let report = report(for: snapshot.id) {
59+
if useCache, let report = report(for: snapshot.id, buildSettings: buildSettings) {
5960
return report
6061
}
61-
guard let buildSettings = buildSettings, !buildSettings.isFallback else {
62+
guard let buildSettings = buildSettings else {
63+
logger.log(
64+
"Producing syntactic diagnostics from the built-in swift-syntax because we don't have buildSettings"
65+
)
66+
// If we don't have build settings,
67+
// sourcekitd won't be able to give us accurate semantic diagnostics.
68+
// Fall back to providing syntactic diagnostics from the built-in
69+
// swift-syntax. That's the best we can do for now.
70+
let report = try await requestFallbackReport(with: snapshot)
71+
setReport(for: snapshot.id, buildSettings: nil, report: report)
72+
return report
73+
}
74+
guard !buildSettings.isFallback else {
6275
logger.log(
6376
"Producing syntactic diagnostics from the built-in swift-syntax because we have fallback arguments"
6477
)
65-
// If we don't have build settings or we only have fallback build settings,
78+
// If we only have fallback build settings,
6679
// sourcekitd won't be able to give us accurate semantic diagnostics.
6780
// Fall back to providing syntactic diagnostics from the built-in
6881
// swift-syntax. That's the best we can do for now.
69-
let report = try await fallbackReport(with: snapshot)
70-
setReport(for: snapshot.id, report: report)
82+
let report = try await requestFallbackReport(with: snapshot)
83+
setReport(for: snapshot.id, buildSettings: buildSettings, report: report)
7184
return report
7285
}
73-
74-
let report = try await report(with: snapshot, compilerArgs: buildSettings.compilerArgs)
75-
setReport(for: snapshot.id, report: report)
86+
let report = try await requestReport(with: snapshot, compilerArgs: buildSettings.compilerArgs)
87+
setReport(for: snapshot.id, buildSettings: buildSettings, report: report)
7688
return report
7789
}
7890
}
7991

8092
private extension DiagnosticReportManager {
81-
func report(with snapshot: DocumentSnapshot, compilerArgs: [String]) async throws
93+
func requestReport(with snapshot: DocumentSnapshot, compilerArgs: [String]) async throws
8294
-> LanguageServerProtocol.RelatedFullDocumentDiagnosticReport
8395
{
8496
try Task.checkCancellation()
@@ -114,7 +126,7 @@ private extension DiagnosticReportManager {
114126
return RelatedFullDocumentDiagnosticReport(items: diagnostics)
115127
}
116128

117-
func fallbackReport(with snapshot: DocumentSnapshot) async throws
129+
func requestFallbackReport(with snapshot: DocumentSnapshot) async throws
118130
-> LanguageServerProtocol.RelatedFullDocumentDiagnosticReport
119131
{
120132
// If we don't have build settings or we only have fallback build settings,
@@ -133,17 +145,23 @@ private extension DiagnosticReportManager {
133145
return RelatedFullDocumentDiagnosticReport(items: diagnostics)
134146
}
135147

136-
/// The report for the given document snapshot.
137-
func report(for snapshotID: DocumentSnapshot.ID) -> RelatedFullDocumentDiagnosticReport? {
138-
return reportCache.first(where: { $0.snapshotID == snapshotID })?.report
148+
/// The report for the given document snapshot and buildSettings.
149+
func report(for snapshotID: DocumentSnapshot.ID, buildSettings: SwiftCompileCommand?)
150+
-> RelatedFullDocumentDiagnosticReport?
151+
{
152+
return reportCache.first(where: { $0.snapshotID == snapshotID && $0.buildSettings == buildSettings })?.report
139153
}
140154

141-
/// Set the report for the given document snapshot.
155+
/// Set the report for the given document snapshot and buildSettings.
142156
///
143157
/// If we are already storing `cacheSize` many reports, the oldest one
144158
/// will get discarded.
145-
func setReport(for snapshotID: DocumentSnapshot.ID, report: RelatedFullDocumentDiagnosticReport) {
146-
reportCache.insert((snapshotID, report), at: 0)
159+
func setReport(
160+
for snapshotID: DocumentSnapshot.ID,
161+
buildSettings: SwiftCompileCommand?,
162+
report: RelatedFullDocumentDiagnosticReport
163+
) {
164+
reportCache.insert((snapshotID, buildSettings, report), at: 0)
147165

148166
// Remove any reports for old versions of this document.
149167
reportCache.removeAll(where: { $0.snapshotID < snapshotID })

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,12 @@ public actor SwiftLanguageServer: ToolchainLanguageServer {
159159
self.state = .connected
160160
self.generatedInterfacesPath = options.generatedInterfacesPath.asURL
161161
try FileManager.default.createDirectory(at: generatedInterfacesPath, withIntermediateDirectories: true)
162-
self.diagnosticReportManager = DiagnosticReportManager(sourcekitd: self.sourcekitd, syntaxTreeManager: syntaxTreeManager, documentManager: documentManager, clientHasDiagnosticsCodeDescriptionSupport: capabilityRegistry.clientHasDiagnosticsCodeDescriptionSupport)
162+
self.diagnosticReportManager = DiagnosticReportManager(
163+
sourcekitd: self.sourcekitd,
164+
syntaxTreeManager: syntaxTreeManager,
165+
documentManager: documentManager,
166+
clientHasDiagnosticsCodeDescriptionSupport: capabilityRegistry.clientHasDiagnosticsCodeDescriptionSupport
167+
)
163168
}
164169

165170
/// - Important: For testing only
@@ -1280,4 +1285,4 @@ extension sourcekitd_uid_t {
12801285
return nil
12811286
}
12821287
}
1283-
}
1288+
}

0 commit comments

Comments
 (0)