Skip to content

Commit

Permalink
Swift Language Support: Drop <5.9, Add 6.0 (#26)
Browse files Browse the repository at this point in the history
* Swift Language Support: Drop <5.9, Add 6.0

* wip

* wip

* wip
  • Loading branch information
stephencelis authored Jun 18, 2024
1 parent 550def1 commit ccb410b
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 160 deletions.
48 changes: 24 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,45 @@ concurrency:
jobs:
library:
name: macOS
runs-on: macos-14
strategy:
matrix:
xcode: ['14.3.1']
xcode: ['15.4']
config: ['debug', 'release']
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Select Xcode ${{ matrix.xcode }}
run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
- name: Run ${{ matrix.config }} tests
run: CONFIG=${{ matrix.config }} make test

linux:
name: Linux
name: Linux (Swift ${{ matrix.swift }})
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-20.04]
config: ['debug', 'release']
runs-on: ${{ matrix.os }}
swift:
- '5.10'
container: swift:${{ matrix.swift }}
steps:
- uses: actions/checkout@v3
- name: Build
run: swift build
- uses: actions/checkout@v4
- name: Run tests
run: swift test -c ${{ matrix.config }}

wasm:
name: Wasm
runs-on: ubuntu-latest
strategy:
matrix:
include:
- { toolchain: wasm-5.7.1-RELEASE }
steps:
- uses: actions/checkout@v3
- run: echo "${{ matrix.toolchain }}" > .swift-version
- uses: swiftwasm/[email protected]
with:
shell-action: carton test --environment node
name: Wasm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: bytecodealliance/actions/wasmtime/setup@v1
- uses: swiftwasm/setup-swiftwasm@v1
with:
swift-version: "wasm-5.9.2-RELEASE"
- name: Build tests
run: swift build --triple wasm32-unknown-wasi --build-tests
- name: Run tests
run: wasmtime --dir . .build/debug/swift-concurrency-extrasPackageTests.wasm

windows:
name: Windows
Expand All @@ -66,9 +66,9 @@ jobs:
steps:
- uses: compnerd/gha-setup-swift@main
with:
branch: swift-5.8-release
tag: 5.8-RELEASE
branch: swift-5.10-release
tag: 5.10-RELEASE

- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Run tests
run: swift build -c ${{ matrix.config }}
19 changes: 7 additions & 12 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.6
// swift-tools-version: 5.9

import PackageDescription

Expand Down Expand Up @@ -36,14 +36,9 @@ let package = Package(
)
#endif

//for target in package.targets {
// target.swiftSettings = target.swiftSettings ?? []
// target.swiftSettings?.append(
// .unsafeFlags([
// "-c", "release",
// "-emit-module-interface", "-enable-library-evolution",
// "-Xfrontend", "-warn-concurrency",
// "-Xfrontend", "-enable-actor-data-race-checks",
// ])
// )
//}
for target in package.targets {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings!.append(contentsOf: [
.enableExperimentalFeature("StrictConcurrency")
])
}
37 changes: 37 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// swift-tools-version: 6.0

import PackageDescription

let package = Package(
name: "swift-concurrency-extras",
platforms: [
.iOS(.v13),
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v6),
],
products: [
.library(
name: "ConcurrencyExtras",
targets: ["ConcurrencyExtras"]
)
],
targets: [
.target(
name: "ConcurrencyExtras"
),
.testTarget(
name: "ConcurrencyExtrasTests",
dependencies: [
"ConcurrencyExtras"
]
),
]
)

#if !os(Windows)
// Add the documentation compiler plugin if possible
package.dependencies.append(
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
)
#endif
60 changes: 0 additions & 60 deletions Sources/ConcurrencyExtras/AsyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,66 +65,6 @@ extension AsyncStream {
}
}

#if swift(<5.9)
/// Constructs and returns a stream along with its backing continuation.
///
/// A back-port of [SE-0388: Convenience Async[Throwing]Stream.makeStream methods][se-0388].
///
/// This is handy for immediately escaping the continuation from an async stream, which
/// typically requires multiple steps:
///
/// ```swift
/// var _continuation: AsyncStream<Int>.Continuation!
/// let stream = AsyncStream<Int> { continuation = $0 }
/// let continuation = _continuation!
///
/// // vs.
///
/// let (stream, continuation) = AsyncStream.makeStream(of: Int.self)
/// ```
///
/// This tool is usually used for tests where we need to supply an async sequence to a
/// dependency endpoint and get access to its continuation so that we can emulate the dependency
/// emitting data. For example, suppose you have a dependency exposing an async sequence for
/// listening to notifications. To test this you can use `makeStream`:
///
/// ```swift
/// func testScreenshots() {
/// let screenshots = AsyncStream.makeStream(of: Void.self)
///
/// let model = withDependencies {
/// $0.screenshots = { screenshots.stream }
/// } operation: {
/// FeatureModel()
/// }
///
/// XCTAssertEqual(model.screenshotCount, 0)
/// screenshots.continuation.yield() // Simulate a screenshot being taken.
/// XCTAssertEqual(model.screenshotCount, 1)
/// }
/// ```
///
/// > Warning: ⚠️ `AsyncStream` does not support multiple subscribers, therefore you can only
/// > use this helper to test features that do not subscribe multiple times to the dependency
/// > endpoint.
///
/// [se-0388]: https://github.com/apple/swift-evolution/blob/main/proposals/0388-async-stream-factory.md
///
/// - Parameters:
/// - elementType: The type of element the `AsyncStream` produces.
/// - limit: A Continuation.BufferingPolicy value to set the stream’s buffering behavior. By
/// default, the stream buffers an unlimited number of elements. You can also set the policy
/// to buffer a specified number of oldest or newest elements.
/// - Returns: An `AsyncStream`.
public static func makeStream(
of elementType: Element.Type = Element.self,
bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded
) -> (stream: Self, continuation: Continuation) {
var continuation: Continuation!
return (Self(elementType, bufferingPolicy: limit) { continuation = $0 }, continuation)
}
#endif

/// An `AsyncStream` that never emits and never completes unless cancelled.
public static var never: Self {
Self { _ in }
Expand Down
62 changes: 0 additions & 62 deletions Sources/ConcurrencyExtras/AsyncThrowingStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,68 +18,6 @@ extension AsyncThrowingStream where Failure == Error {
}
}

#if swift(<5.9)
/// Constructs and returns a stream along with its backing continuation.
///
/// A back-port of [SE-0388: Convenience Async[Throwing]Stream.makeStream methods][se-0388].
///
/// This is handy for immediately escaping the continuation from an async stream, which
/// typically requires multiple steps:
///
/// ```swift
/// var _continuation: AsyncThrowingStream<Int, Error>.Continuation!
/// let stream = AsyncThrowingStream<Int, Error> { continuation = $0 }
/// let continuation = _continuation!
///
/// // vs.
///
/// let (stream, continuation) = AsyncThrowingStream.makeStream(of: Int.self)
/// ```
///
/// This tool is usually used for tests where we need to supply an async sequence to a
/// dependency endpoint and get access to its continuation so that we can emulate the dependency
/// emitting data. For example, suppose you have a dependency exposing an async sequence for
/// listening to notifications. To test this you can use `makeStream`:
///
/// ```swift
/// func testScreenshots() {
/// let screenshots = AsyncThrowingStream.makeStream(of: Void.self)
///
/// let model = withDependencies {
/// $0.screenshots = { screenshots.stream }
/// } operation: {
/// FeatureModel()
/// }
///
/// XCTAssertEqual(model.screenshotCount, 0)
/// screenshots.continuation.yield() // Simulate a screenshot being taken.
/// XCTAssertEqual(model.screenshotCount, 1)
/// }
/// ```
///
/// > Warning: ⚠️ `AsyncThrowingStream` does not support multiple subscribers, therefore you can
/// > only use this helper to test features that do not subscribe multiple times to the
/// > dependency endpoint.
///
/// [se-0388]: https://github.com/apple/swift-evolution/blob/main/proposals/0388-async-stream-factory.md
///
/// - Parameters:
/// - elementType: The type of element the `AsyncThrowingStream` produces.
/// - failureType: The type of failure the `AsyncThrowingStream` throws.
/// - limit: A Continuation.BufferingPolicy value to set the stream’s buffering behavior. By
/// default, the stream buffers an unlimited number of elements. You can also set the policy
/// to buffer a specified number of oldest or newest elements.
/// - Returns: An `AsyncThrowingStream`.
public static func makeStream(
of elementType: Element.Type = Element.self,
throwing failureType: Failure.Type = Failure.self,
bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded
) -> (stream: Self, continuation: Continuation) {
var continuation: Continuation!
return (Self(elementType, bufferingPolicy: limit) { continuation = $0 }, continuation)
}
#endif

/// An `AsyncThrowingStream` that never emits and never completes unless cancelled.
public static var never: Self {
Self { _ in }
Expand Down
4 changes: 2 additions & 2 deletions Tests/ConcurrencyExtrasTests/AsyncStreamTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@available(iOS 15, *)
private let sendable: @Sendable () async -> AsyncStream<Void> = {
await NotificationCenter.default
NotificationCenter.default
.notifications(named: UIApplication.userDidTakeScreenshotNotification)
.map { _ in }
.eraseToStream()
Expand All @@ -20,7 +20,7 @@

@available(iOS 15, *)
private let sendableThrowing: @Sendable () async -> AsyncThrowingStream<Void, Error> = {
await NotificationCenter.default
NotificationCenter.default
.notifications(named: UIApplication.userDidTakeScreenshotNotification)
.map { _ in }
.eraseToThrowingStream()
Expand Down

0 comments on commit ccb410b

Please sign in to comment.