Skip to content

Commit 1d32512

Browse files
committed
Fix issue that caused code completion request to not be cancellable
1 parent 1c3e5bb commit 1d32512

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

Sources/SwiftSourceKitPlugin/CodeCompletion/Connection.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@ final class Connection {
113113
sourcekitd.ideApi.connection_dispose(impl)
114114
}
115115

116+
//// A function that can be called to cancel a request with a request.
117+
///
118+
/// This is not a member function on `Connection` so that `CompletionProvider` can store
119+
/// this closure in a member and call it even while the `CompletionProvider` actor is busy
120+
/// fulfilling a completion request and thus can't access `connection`.
121+
var cancellationFunc: @Sendable (RequestHandle) -> Void {
122+
nonisolated(unsafe) let impl = self.impl
123+
return { [sourcekitd] handle in
124+
sourcekitd.ideApi.cancel_request(impl, handle.handle)
125+
}
126+
}
127+
116128
func openDocument(path: String, contents: String, compilerArguments: [String]? = nil) {
117129
if documents[path] != nil {
118130
logger.error("Document at '\(path)' is already open")
@@ -219,10 +231,6 @@ final class Connection {
219231
)
220232
}
221233

222-
func cancel(handle: RequestHandle) {
223-
sourcekitd.ideApi.cancel_request(impl, handle.handle)
224-
}
225-
226234
func markCachedCompilerInstanceShouldBeInvalidated() {
227235
sourcekitd.ideApi.connection_mark_cached_compiler_instance_should_be_invalidated(impl, nil)
228236
}

Sources/SwiftSourceKitPlugin/CompletionProvider.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ actor CompletionProvider {
8686

8787
private let connection: Connection
8888

89+
/// See `Connection.cancellationFunc`
90+
private nonisolated let cancel: @Sendable (RequestHandle) -> Void
91+
8992
/// The XPC custom buffer kind for `CompletionResultsArray`
9093
private let completionResultsBufferKind: UInt64
9194

@@ -101,17 +104,12 @@ actor CompletionProvider {
101104
opaqueIDEInspectionInstance: opaqueIDEInspectionInstance?.value,
102105
sourcekitd: sourcekitd
103106
)
107+
self.cancel = connection.cancellationFunc
104108
self.completionResultsBufferKind = completionResultsBufferKind
105109
}
106110

107111
nonisolated func cancel(handle: RequestHandle) {
108-
Task {
109-
await self.cancelImpl(handle: handle)
110-
}
111-
}
112-
113-
private func cancelImpl(handle: RequestHandle) {
114-
connection.cancel(handle: handle)
112+
self.cancel(handle)
115113
}
116114

117115
func handleDocumentOpen(_ request: SKDRequestDictionaryReader) {

0 commit comments

Comments
 (0)