From a42da7dc3e15df2247f0ef569e516f9401f3491a Mon Sep 17 00:00:00 2001 From: JARMourato Date: Fri, 31 Jan 2025 16:57:16 +0000 Subject: [PATCH] update for swift 6.0 --- Package.swift | 4 +- Sources/Injection/Dependency.swift | 4 +- Sources/Injection/Macros.swift | 2 +- Sources/InjectionMacros/DependencyKey.swift | 45 +++++++++++++++-- Tests/DependencyTests.swift | 9 ++-- Tests/InjectionMacroTests.swift | 54 +++++++-------------- 6 files changed, 68 insertions(+), 50 deletions(-) diff --git a/Package.swift b/Package.swift index ec3fb7b..af68a6c 100755 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:6.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import CompilerPluginSupport @@ -11,7 +11,7 @@ let package = Package( .library(name: "Injection", targets: ["Injection"]), ], dependencies: [ - .package(url: "https://github.com/apple/swift-syntax", from: "510.0.0"), + .package(url: "https://github.com/apple/swift-syntax", from: "600.0.0-latest"), ], targets: [ .macro( diff --git a/Sources/Injection/Dependency.swift b/Sources/Injection/Dependency.swift index 3369d87..21ed606 100644 --- a/Sources/Injection/Dependency.swift +++ b/Sources/Injection/Dependency.swift @@ -4,12 +4,12 @@ import SwiftUI public typealias DependencyKey = EnvironmentKey -public struct DependencyValues { +@preconcurrency public struct DependencyValues { private var values: [ObjectIdentifier: Any] = [:] init() {} - @usableFromInline static var shared = DependencyValues() + @usableFromInline nonisolated(unsafe) static var shared = DependencyValues() public subscript(key: K.Type) -> K.Value where K: DependencyKey { get { values[ObjectIdentifier(key)] as? K.Value ?? key.defaultValue } diff --git a/Sources/Injection/Macros.swift b/Sources/Injection/Macros.swift index ed4ee4d..ef0b45b 100644 --- a/Sources/Injection/Macros.swift +++ b/Sources/Injection/Macros.swift @@ -4,7 +4,7 @@ /// Creates an unique `DependencyKey` for the variable and adds getters and setters. /// The initial value of the variable becomes the default value of the `DependencyKey`. -@attached(peer, names: prefixed(___)) +@attached(peer, names: prefixed(__Key_)) @attached(accessor, names: named(get), named(set)) public macro DependencyKey() = #externalMacro(module: "InjectionMacros", type: "DependencyKeyMacro") diff --git a/Sources/InjectionMacros/DependencyKey.swift b/Sources/InjectionMacros/DependencyKey.swift index 7153a19..bd45259 100644 --- a/Sources/InjectionMacros/DependencyKey.swift +++ b/Sources/InjectionMacros/DependencyKey.swift @@ -33,7 +33,44 @@ public struct InjectValuesMacro: MemberAttributeMacro { guard !isStatic else { return [] } - // Note: Implement usage of @Entry for EnvironmentValues for iOS 18 + if extensionName == "EnvironmentValues" { + #if os(iOS) + if #available(iOS 18.0, *) { + return [AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier("Entry")) + )] + } + #elseif os(macOS) + if #available(macOS 15.0, *) { + return [AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier("Entry")) + )] + } + #elseif os(tvOS) + if #available(tvOS 18.0, *) { + return [AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier("Entry")) + )] + } + #elseif os(watchOS) + if #available(watchOS 11.0, *) { + return [AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier("Entry")) + )] + } + #elseif os(visionOS) + if #available(visionOS 2.0, *) { + return [AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier("Entry")) + )] + } + #endif + } return [ AttributeSyntax( @@ -67,7 +104,7 @@ public struct DependencyKeyMacro: PeerMacro { return [ """ - private struct ___\(raw: identifier.trimmedDescription): DependencyKey { + private struct __Key_\(raw: identifier.trimmedDescription): DependencyKey { static let \(binding) \(raw: isOptionalType && !hasDefaultValue ? "= nil" : "") } """, @@ -88,12 +125,12 @@ extension DependencyKeyMacro: AccessorMacro { return [ """ get { - self[___\(raw: identifier.trimmedDescription).self] + self[__Key_\(raw: identifier.trimmedDescription).self] } """, """ set { - self[___\(raw: identifier.trimmedDescription).self] = newValue + self[__Key_\(raw: identifier.trimmedDescription).self] = newValue } """, ] diff --git a/Tests/DependencyTests.swift b/Tests/DependencyTests.swift index bafeaa7..7cfa71e 100644 --- a/Tests/DependencyTests.swift +++ b/Tests/DependencyTests.swift @@ -7,8 +7,7 @@ import XCTest final class DependencyTests: XCTestCase { func testReadDependency() { // Given - let assertionValue = 100 - DependencyValues.NumberKey.defaultValue = assertionValue + let assertionValue = 10 // When let readValue = DependencyValues.shared[keyPath: \.number] // Then @@ -37,7 +36,7 @@ final class DependencyTests: XCTestCase { XCTAssertEqual(value, DependencyValues.NumberKey.defaultValue) } - func testSwiftUIViewUtilityWriter() { + @MainActor func testSwiftUIViewUtilityWriter() { // Given let view = EmptyView() let assertionValue = 100 @@ -58,6 +57,8 @@ extension DependencyValues { } struct NumberKey: DependencyKey { - static var defaultValue: Int = 10 + static var defaultValue: Int { + 10 + } } } diff --git a/Tests/InjectionMacroTests.swift b/Tests/InjectionMacroTests.swift index 22a7da0..eb7408f 100644 --- a/Tests/InjectionMacroTests.swift +++ b/Tests/InjectionMacroTests.swift @@ -16,7 +16,7 @@ final class InjectionMacroTests: XCTestCase { expandedSource: """ extension EnvironmentValues { - @DependencyKey + @Entry var number: Int = 10 } """, @@ -36,14 +36,14 @@ final class InjectionMacroTests: XCTestCase { extension EnvironmentValues { var number: Int { get { - self [___number.self] + self[__Key_number.self] } set { - self [___number.self] = newValue + self[__Key_number.self] = newValue } } - private struct ___number: DependencyKey { + private struct __Key_number: DependencyKey { static let defaultValue: Int = 10 } } @@ -64,30 +64,10 @@ final class InjectionMacroTests: XCTestCase { expandedSource: """ extension EnvironmentValues { - var number: Int { - get { - self [___number.self] - } - set { - self [___number.self] = newValue - } - } - - private struct ___number: DependencyKey { - static let defaultValue: Int = 10 - } - var text: String { - get { - self [___text.self] - } - set { - self [___text.self] = newValue - } - } - - private struct ___text: DependencyKey { - static let defaultValue: String = "Hello" - } + @Entry + var number: Int = 10 + @Entry + var text: String = "Hello" } """, macros: [ @@ -128,14 +108,14 @@ final class InjectionMacroTests: XCTestCase { extension DependencyValues { var number: Int { get { - self [___number.self] + self[__Key_number.self] } set { - self [___number.self] = newValue + self[__Key_number.self] = newValue } } - private struct ___number: DependencyKey { + private struct __Key_number: DependencyKey { static let defaultValue: Int = 10 } } @@ -158,26 +138,26 @@ final class InjectionMacroTests: XCTestCase { extension DependencyValues { var number: Int { get { - self [___number.self] + self[__Key_number.self] } set { - self [___number.self] = newValue + self[__Key_number.self] = newValue } } - private struct ___number: DependencyKey { + private struct __Key_number: DependencyKey { static let defaultValue: Int = 10 } var text: String { get { - self [___text.self] + self[__Key_text.self] } set { - self [___text.self] = newValue + self[__Key_text.self] = newValue } } - private struct ___text: DependencyKey { + private struct __Key_text: DependencyKey { static let defaultValue: String = "Hello" } }