mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
We were mixing the up-to-date status and in-progress status of an index task in `SemanticIndexManager`. This meant that a single `QueuedTask` in the task scheduler could be needed for eg. both preparation for editor functionality in a file of that target and to re-index a file in that target. This dual ownership made it unclear, which caller would be entitled to cancel the task. Furthermore, we needed to duplicate some logic from the preparation task dependencies in `SemanticIndexManager.prepare`. To simplify things: - Split the up-to-date status and the in-progress status into two different data structures - Make the caller of `prepare` and `scheduleIndex` responsible for cancellation of the task it has scheduled. `TaskScheduler` might receive more scheduled tasks this way but the additional tasks should all be no-ops because the status is known to be up-to-date when they execute.
58 lines
1.7 KiB
Swift
58 lines
1.7 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
extension Sequence {
|
|
/// Just like `Sequence.map` but allows an `async` transform function.
|
|
public func asyncMap<T>(
|
|
@_inheritActorContext _ transform: @Sendable (Element) async throws -> T
|
|
) async rethrows -> [T] {
|
|
var result: [T] = []
|
|
result.reserveCapacity(self.underestimatedCount)
|
|
|
|
for element in self {
|
|
try await result.append(transform(element))
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Just like `Sequence.compactMap` but allows an `async` transform function.
|
|
public func asyncCompactMap<T>(
|
|
@_inheritActorContext _ transform: @Sendable (Element) async throws -> T?
|
|
) async rethrows -> [T] {
|
|
var result: [T] = []
|
|
|
|
for element in self {
|
|
if let transformed = try await transform(element) {
|
|
result.append(transformed)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/// Just like `Sequence.map` but allows an `async` transform function.
|
|
public func asyncFilter(
|
|
@_inheritActorContext _ predicate: @Sendable (Element) async throws -> Bool
|
|
) async rethrows -> [Element] {
|
|
var result: [Element] = []
|
|
|
|
for element in self {
|
|
if try await predicate(element) {
|
|
result.append(element)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
}
|