12
12
13
13
import LSPLogging
14
14
import LanguageServerProtocol
15
+ import SKSupport
15
16
import SourceKitD
16
17
import SwiftParserDiagnostics
17
18
18
19
actor DiagnosticReportManager {
19
20
/// A task to produce diagnostics, either from a diagnostics request to `sourcektid` or by using the built-in swift-syntax.
20
- private typealias ReportTask = Task < RelatedFullDocumentDiagnosticReport , Error >
21
+ private typealias ReportTask = RefCountedCancellableTask < RelatedFullDocumentDiagnosticReport >
21
22
22
23
private let sourcekitd : SourceKitD
23
24
private let syntaxTreeManager : SyntaxTreeManager
@@ -60,13 +61,13 @@ actor DiagnosticReportManager {
60
61
for snapshot: DocumentSnapshot ,
61
62
buildSettings: SwiftCompileCommand ?
62
63
) async throws -> RelatedFullDocumentDiagnosticReport {
63
- if let reportTask = reportTask ( for: snapshot. id, buildSettings: buildSettings) {
64
+ if let reportTask = reportTask ( for: snapshot. id, buildSettings: buildSettings) , await !reportTask . isCancelled {
64
65
return try await reportTask. value
65
66
}
66
- let reportTask : Task < RelatedFullDocumentDiagnosticReport , Error >
67
+ let reportTask: ReportTask
67
68
if let buildSettings, !buildSettings. isFallback {
68
- reportTask = Task {
69
- return try await requestReport ( with: snapshot, compilerArgs: buildSettings. compilerArgs)
69
+ reportTask = ReportTask {
70
+ return try await self . requestReport ( with: snapshot, compilerArgs: buildSettings. compilerArgs)
70
71
}
71
72
} else {
72
73
logger. log (
@@ -76,21 +77,20 @@ actor DiagnosticReportManager {
76
77
// sourcekitd won't be able to give us accurate semantic diagnostics.
77
78
// Fall back to providing syntactic diagnostics from the built-in
78
79
// swift-syntax. That's the best we can do for now.
79
- reportTask = Task {
80
- return try await requestFallbackReport ( with: snapshot)
80
+ reportTask = ReportTask {
81
+ return try await self . requestFallbackReport ( with: snapshot)
81
82
}
82
83
}
83
84
setReportTask( for: snapshot. id, buildSettings: buildSettings, reportTask: reportTask)
84
85
return try await reportTask. value
85
86
}
86
87
87
88
func removeItemsFromCache( with uri: DocumentURI) async {
88
- for item in reportTaskCache {
89
- if item. snapshotID. uri == uri {
90
- item. reportTask. cancel ( )
91
- }
92
- }
89
+ let tasksToCancel = reportTaskCache. filter { $0. snapshotID. uri == uri }
93
90
reportTaskCache. removeAll ( where: { $0. snapshotID. uri == uri } )
91
+ for task in tasksToCancel {
92
+ await task. reportTask. cancel ( )
93
+ }
94
94
}
95
95
96
96
private func requestReport(
0 commit comments