diff --git a/Sources/LanguageServerProtocolTransport/JSONRPCConnection.swift b/Sources/LanguageServerProtocolTransport/JSONRPCConnection.swift index cd0cb5232..919b1536b 100644 --- a/Sources/LanguageServerProtocolTransport/JSONRPCConnection.swift +++ b/Sources/LanguageServerProtocolTransport/JSONRPCConnection.swift @@ -284,9 +284,11 @@ public final class JSONRPCConnection: Connection { /// - parameter receiveHandler: The message handler to invoke for requests received on the `inFD`. /// /// - Important: `start` must be called before sending any data over the `JSONRPCConnection`. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore public func start( receiveHandler: MessageHandler, - closeHandler: @escaping @Sendable () async -> Void = {} + closeHandler: nonisolated(nonsending) @escaping @Sendable () async -> Void = {} ) { queue.sync { precondition(state == .created) diff --git a/Sources/ToolsProtocolsSwiftExtensions/AsyncQueue.swift b/Sources/ToolsProtocolsSwiftExtensions/AsyncQueue.swift index b06dfb607..163420e87 100644 --- a/Sources/ToolsProtocolsSwiftExtensions/AsyncQueue.swift +++ b/Sources/ToolsProtocolsSwiftExtensions/AsyncQueue.swift @@ -89,11 +89,13 @@ public final class AsyncQueue: Sendable { /// If this is a barrier, all previously scheduled tasks are guaranteed to /// finish execution before the barrier is executed and all tasks that are /// added later will wait until the barrier finishes execution. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore @discardableResult public func async( priority: TaskPriority? = nil, metadata: TaskMetadata, - @_inheritActorContext operation: @escaping @Sendable () async -> Success + @_inheritActorContext operation: nonisolated(nonsending) @escaping @Sendable () async -> Success ) -> Task { let throwingTask = asyncThrowing(priority: priority, metadata: metadata, operation: operation) return Task(priority: priority) { @@ -111,10 +113,12 @@ public final class AsyncQueue: Sendable { /// /// - Important: The caller is responsible for handling any errors thrown from /// the operation by awaiting the result of the returned task. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore public func asyncThrowing( priority: TaskPriority? = nil, metadata: TaskMetadata, - @_inheritActorContext operation: @escaping @Sendable () async throws -> Success + @_inheritActorContext operation: nonisolated(nonsending) @escaping @Sendable () async throws -> Success ) -> Task { let id = UUID() @@ -175,19 +179,23 @@ public final class AsyncQueue: Sendable { extension AsyncQueue where TaskMetadata == Serial { /// Same as ``async(priority:operation:)`` but specialized for serial queues /// that don't specify any metadata. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore @discardableResult public func async( priority: TaskPriority? = nil, - @_inheritActorContext operation: @escaping @Sendable () async -> Success + @_inheritActorContext operation: nonisolated(nonsending) @escaping @Sendable () async -> Success ) -> Task { return self.async(priority: priority, metadata: Serial(), operation: operation) } /// Same as ``asyncThrowing(priority:metadata:operation:)`` but specialized /// for serial queues that don't specify any metadata. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore public func asyncThrowing( priority: TaskPriority? = nil, - @_inheritActorContext operation: @escaping @Sendable () async throws -> Success + @_inheritActorContext operation: nonisolated(nonsending) @escaping @Sendable () async throws -> Success ) -> Task { return self.asyncThrowing(priority: priority, metadata: Serial(), operation: operation) } diff --git a/Sources/ToolsProtocolsSwiftExtensions/AsyncUtils.swift b/Sources/ToolsProtocolsSwiftExtensions/AsyncUtils.swift index 640474c46..aecfbafe7 100644 --- a/Sources/ToolsProtocolsSwiftExtensions/AsyncUtils.swift +++ b/Sources/ToolsProtocolsSwiftExtensions/AsyncUtils.swift @@ -137,9 +137,11 @@ extension Task where Failure == Never { extension Collection where Self: Sendable, Element: Sendable { /// Transforms all elements in the collection concurrently and returns the transformed collection. + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore @_spi(SourceKitLSP) public func concurrentMap( maxConcurrentTasks: Int = ProcessInfo.processInfo.activeProcessorCount, - _ transform: @escaping @Sendable (Element) async -> TransformedElement + _ transform: nonisolated(nonsending) @escaping @Sendable (Element) async -> TransformedElement ) async -> [TransformedElement] { let indexedResults = await withTaskGroup(of: (index: Int, element: TransformedElement).self) { taskGroup in var indexedResults: [(index: Int, element: TransformedElement)] = [] @@ -170,7 +172,9 @@ extension Collection where Self: Sendable, Element: Sendable { } /// Invoke `body` for every element in the collection and wait for all calls of `body` to finish - @_spi(SourceKitLSP) public func concurrentForEach(_ body: @escaping @Sendable (Element) async -> Void) async { + // Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 + // swift-format-ignore + @_spi(SourceKitLSP) public func concurrentForEach(_ body: nonisolated(nonsending) @escaping @Sendable (Element) async -> Void) async { await withTaskGroup(of: Void.self) { taskGroup in for element in self { taskGroup.addTask { diff --git a/Sources/ToolsProtocolsSwiftExtensions/Task+WithPriorityChangedHandler.swift b/Sources/ToolsProtocolsSwiftExtensions/Task+WithPriorityChangedHandler.swift index 931d1fe82..ad974a0d4 100644 --- a/Sources/ToolsProtocolsSwiftExtensions/Task+WithPriorityChangedHandler.swift +++ b/Sources/ToolsProtocolsSwiftExtensions/Task+WithPriorityChangedHandler.swift @@ -16,10 +16,12 @@ /// `pollingInterval`. /// The function assumes that the original priority of the task is `initialPriority`. If the task priority changed /// compared to `initialPriority`, the `taskPriorityChanged` will be called. +// Workaround formatter issue: https://github.com/swiftlang/swift-format/issues/1081 +// swift-format-ignore @_spi(SourceKitLSP) public func withTaskPriorityChangedHandler( initialPriority: TaskPriority = Task.currentPriority, pollingInterval: Duration = .seconds(0.1), - @_inheritActorContext operation: @escaping @Sendable () async throws -> T, + @_inheritActorContext operation: nonisolated(nonsending) @escaping @Sendable () async throws -> T, taskPriorityChanged: @escaping @Sendable () -> Void ) async throws -> T { let lastPriority = ThreadSafeBox(initialValue: initialPriority)