diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c6d127..74b9718a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ ##### Enhancements -* None. +* Add `Request.sendAsync()` function. + [JP Simard](https://github.com/jpsim) + [#759](https://github.com/jpsim/SourceKitten/issues/759) ##### Bug Fixes diff --git a/Source/SourceKittenFramework/Request.swift b/Source/SourceKittenFramework/Request.swift index 4cd9c2b0..65e1aac7 100644 --- a/Source/SourceKittenFramework/Request.swift +++ b/Source/SourceKittenFramework/Request.swift @@ -333,6 +333,19 @@ public enum Request { /** Sends the request to SourceKit and return the response as an [String: SourceKitRepresentable]. + - returns: SourceKit output as a dictionary. + - throws: Request.Error on fail () + */ + public func asyncSend() async throws -> [String: SourceKitRepresentable] { + initializeSourceKitFailable + let response = try await sourcekitObject.sendAsync() + defer { sourcekitd_response_dispose(response) } + return fromSourceKit(sourcekitd_response_get_value(response)) as! [String: SourceKitRepresentable] + } + + /** + Sends the request to SourceKit and return the response as an [String: SourceKitRepresentable]. + - returns: SourceKit output as a dictionary. - throws: Request.Error on fail () */ diff --git a/Source/SourceKittenFramework/SourceKitObject.swift b/Source/SourceKittenFramework/SourceKitObject.swift index 098a1e64..0af9f3f7 100644 --- a/Source/SourceKittenFramework/SourceKitObject.swift +++ b/Source/SourceKittenFramework/SourceKitObject.swift @@ -100,6 +100,31 @@ public final class SourceKitObject { func sendSync() -> sourcekitd_response_t? { return sourcekitd_send_request_sync(sourcekitdObject) } + + func sendAsync() async throws -> sourcekitd_response_t { + let handle = UnsafeMutablePointer.allocate(capacity: 1) + + return try await withTaskCancellationHandler { + try await withUnsafeThrowingContinuation { continuation in + sourcekitd_send_request(sourcekitdObject, handle) { response in + enum SourceKitSendError: Error { case error, noResponse } + + guard let response else { + continuation.resume(throwing: SourceKitSendError.noResponse) + return + } + + if sourcekitd_response_is_error(response) { + continuation.resume(throwing: SourceKitSendError.error) + } else { + continuation.resume(returning: response) + } + } + } + } onCancel: { + sourcekitd_cancel_request(handle) + } + } } extension SourceKitObject: SourceKitObjectConvertible { diff --git a/SourceKittenFramework.podspec b/SourceKittenFramework.podspec index 8e59adf4..b6632ac4 100644 --- a/SourceKittenFramework.podspec +++ b/SourceKittenFramework.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |s| s.source = { git: s.homepage + '.git', tag: s.version } s.license = { type: 'MIT', file: 'LICENSE' } s.author = { 'JP Simard' => 'jp@jpsim.com' } - s.platform = :osx, '10.9' + s.platform = :osx, '12' s.source_files = 'Source/Clang_C/include/*.h', 'Source/SourceKit/include/*.h', 'Source/SourceKittenFramework/*.swift' s.swift_versions = ['5.3', '5.4', '5.5', '5.6', '5.7'] s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }