Skip to content

Commit

Permalink
Enable strict concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
Supereg committed Jul 10, 2024
1 parent 51da340 commit d599759
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 17 deletions.
4 changes: 0 additions & 4 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ only_rules:
- implicitly_unwrapped_optional
# Identifiers should use inclusive language that avoids discrimination against groups of people based on race, gender, or socioeconomic status
- inclusive_language
# If defer is at the end of its parent scope, it will be executed right where it is anyway.
- inert_defer
# Prefer using Set.isDisjoint(with:) over Set.intersection(_:).isEmpty.
- is_disjoint
# Discouraged explicit usage of the default separator.
Expand Down Expand Up @@ -329,8 +327,6 @@ only_rules:
- unowned_variable_capture
# Catch statements should not declare error variables without type casting.
- untyped_error_in_catch
# Unused reference in a capture list should be removed.
- unused_capture_list
# Unused parameter in a closure should be replaced with _.
- unused_closure_parameter
# Unused control flow label should be removed.
Expand Down
37 changes: 35 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@
// SPDX-License-Identifier: MIT
//

import class Foundation.ProcessInfo
import PackageDescription

#if swift(<6)
let swiftConcurrency: SwiftSetting = .enableExperimentalFeature("StrictConcurrency")
#else
let swiftConcurrency: SwiftSetting = .enableUpcomingFeature("StrictConcurrency")
#endif


let package = Package(
name: "XCTRuntimeAssertions",
Expand All @@ -23,15 +30,41 @@ let package = Package(
products: [
.library(name: "XCTRuntimeAssertions", targets: ["XCTRuntimeAssertions"])
],
dependencies: swiftLintPackage(),
targets: [
.target(
name: "XCTRuntimeAssertions"
name: "XCTRuntimeAssertions",
swiftSettings: [
swiftConcurrency
],
plugins: [] + swiftLintPlugin()
),
.testTarget(
name: "XCTRuntimeAssertionsTests",
dependencies: [
.target(name: "XCTRuntimeAssertions")
]
],
swiftSettings: [
swiftConcurrency
],
plugins: [] + swiftLintPlugin()
)
]
)

func swiftLintPlugin() -> [Target.PluginUsage] {
// Fully quit Xcode and open again with `open --env SPEZI_DEVELOPMENT_SWIFTLINT /Applications/Xcode.app`
if ProcessInfo.processInfo.environment["SPEZI_DEVELOPMENT_SWIFTLINT"] != nil {
[.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")]
} else {
[]
}
}

func swiftLintPackage() -> [PackageDescription.Package.Dependency] {
if ProcessInfo.processInfo.environment["SPEZI_DEVELOPMENT_SWIFTLINT"] != nil {
[.package(url: "https://github.com/realm/SwiftLint.git", .upToNextMinor(from: "0.55.1"))]
} else {
[]
}
}
51 changes: 41 additions & 10 deletions Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,39 @@
#if DEBUG || TEST
import Foundation

private final class RuntimeInjections: Sendable {
private nonisolated(unsafe) var injected: [XCTRuntimeAssertionInjector] = []

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package iOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package iOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package macOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package macOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package visionOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package visionOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package tvOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package tvOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package watchOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable

Check warning on line 13 in Sources/XCTRuntimeAssertions/XCTRuntimeAssertionInjector.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package watchOS / Test using xcodebuild or run fastlane

stored property 'injected' of 'Sendable'-conforming class 'RuntimeInjections' is mutable
private let lock = NSLock()

@inlinable var isEmpty: Bool {
injected.isEmpty
}

var injections: [XCTRuntimeAssertionInjector] {
lock.withLock {
injected
}
}

init() {}

func append(_ element: XCTRuntimeAssertionInjector) {
lock.withLock {
injected.append(element)
}
}

func removeAll(for id: UUID) {
lock.withLock {
injected.removeAll(where: { $0.id == id })
}
}
}


class XCTRuntimeAssertionInjector {
private static var injected: [XCTRuntimeAssertionInjector] = []
private static let injection = RuntimeInjections()


let id: UUID
private let _assert: (UUID, () -> Bool, () -> String, StaticString, UInt) -> Void
Expand Down Expand Up @@ -65,30 +94,32 @@ class XCTRuntimeAssertionInjector {


static func inject(runtimeAssertionInjector: XCTRuntimeAssertionInjector) {
injected.append(runtimeAssertionInjector)
injection.append(runtimeAssertionInjector)
}

static func removeRuntimeAssertionInjector(withId id: UUID) {
injected.removeAll(where: { $0.id == id })
injection.removeAll(for: id)
}



@inlinable
static func assert(_ condition: () -> Bool, message: () -> String, file: StaticString, line: UInt) {
if injected.isEmpty {
if injection.isEmpty {
Swift.assert(condition(), message(), file: file, line: line)
}

for runtimeAssertionInjector in injected {
for runtimeAssertionInjector in injection.injections {
runtimeAssertionInjector._assert(runtimeAssertionInjector.id, condition, message, file, line)
}
}


@inlinable
static func precondition(_ condition: () -> Bool, message: () -> String, file: StaticString, line: UInt) {
if injected.isEmpty {
if injection.isEmpty {
Swift.precondition(condition(), message(), file: file, line: line)
}

for runtimeAssertionInjector in injected {
for runtimeAssertionInjector in injection.injections {
runtimeAssertionInjector._precondition(runtimeAssertionInjector.id, condition, message, file, line)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XCTRuntimeAssertions/XCTRuntimePrecondition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public func XCTRuntimePrecondition(
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
_ expression: @escaping () async -> Void
_ expression: @escaping @Sendable () async -> Void
) throws {
let fulfillmentCount = Counter()
let xctRuntimeAssertionId = setupXCTRuntimeAssertionInjector(
Expand Down

0 comments on commit d599759

Please sign in to comment.