From 13671496e4c8e6d5ac1727a7327bace5148aa20c Mon Sep 17 00:00:00 2001 From: vijaysharm Date: Wed, 13 Nov 2024 10:47:39 -0500 Subject: [PATCH 1/3] Allows for parameterizing entities to be marked as sendable --- CodeGen/Sources/LucidCodeGen/Meta/MetaEntity.swift | 1 + .../Sources/LucidCodeGen/Meta/MetaEntityIdentifier.swift | 1 + CodeGen/Sources/LucidCodeGenCore/Codable.swift | 3 +++ CodeGen/Sources/LucidCodeGenCore/Descriptions.swift | 6 +++++- CodeGen/Sources/LucidCodeGenCore/MetaUtils.swift | 4 ++++ Lucid/Core/Payload.swift | 2 ++ Lucid/Utils/AnySequence.swift | 2 ++ Lucid/Utils/PropertyBox.swift | 2 +- 8 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CodeGen/Sources/LucidCodeGen/Meta/MetaEntity.swift b/CodeGen/Sources/LucidCodeGen/Meta/MetaEntity.swift index 46a025e8..1a0d9046 100644 --- a/CodeGen/Sources/LucidCodeGen/Meta/MetaEntity.swift +++ b/CodeGen/Sources/LucidCodeGen/Meta/MetaEntity.swift @@ -68,6 +68,7 @@ struct MetaEntity { return Type(identifier: entity.typeID()) .adding(inheritedType: .codable) + .adding(inheritedType: entity.senable ? .sendable : nil) .with(kind: .class(final: true)) .with(accessLevel: .public) .with(body: [ diff --git a/CodeGen/Sources/LucidCodeGen/Meta/MetaEntityIdentifier.swift b/CodeGen/Sources/LucidCodeGen/Meta/MetaEntityIdentifier.swift index 5f7db6a2..466f74b8 100644 --- a/CodeGen/Sources/LucidCodeGen/Meta/MetaEntityIdentifier.swift +++ b/CodeGen/Sources/LucidCodeGen/Meta/MetaEntityIdentifier.swift @@ -44,6 +44,7 @@ struct MetaEntityIdentifier { return Type(identifier: entity.identifierTypeID()) .adding(inheritedType: .codable) + .adding(inheritedType: entity.senable ? .sendable : nil) .with(kind: .class(final: true)) .with(accessLevel: .public) .adding(inheritedType: .coreDataIdentifier) diff --git a/CodeGen/Sources/LucidCodeGenCore/Codable.swift b/CodeGen/Sources/LucidCodeGenCore/Codable.swift index 0f4cc7e0..26c0e11b 100644 --- a/CodeGen/Sources/LucidCodeGenCore/Codable.swift +++ b/CodeGen/Sources/LucidCodeGenCore/Codable.swift @@ -40,6 +40,7 @@ public enum DescriptionDefaults { public static let ignorePropertyMigrationChecksOn = [String]() public static let httpMethod: EndpointPayloadTest.HTTPMethod = .get public static let cacheSize: EntityCacheSize = .group(.medium) + public static let sendable = false } public extension Entity { @@ -322,6 +323,7 @@ extension Entity: Codable { case queryContext case clientQueueName case cacheSize + case sendable } public init(from decoder: Decoder) throws { @@ -348,6 +350,7 @@ extension Entity: Codable { queryContext = try container.decodeIfPresent(Bool.self, forKey: .queryContext) ?? DescriptionDefaults.queryContext clientQueueName = try container.decodeIfPresent(String.self, forKey: .clientQueueName) ?? DescriptionDefaults.clientQueueName cacheSize = try container.decodeIfPresent(EntityCacheSize.self, forKey: .cacheSize) ?? DescriptionDefaults.cacheSize + senable = try container.decodeIfPresent(Bool.self, forKey: .sendable) ?? DescriptionDefaults.sendable let systemPropertiesSet = Set(SystemPropertyName.allCases.map { $0.rawValue }) for property in properties where systemPropertiesSet.contains(property.name) { diff --git a/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift b/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift index 2dd20ce4..5bf44379 100644 --- a/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift +++ b/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift @@ -368,6 +368,8 @@ public struct Entity: Equatable { public let clientQueueName: String public let cacheSize: EntityCacheSize + + public let senable: Bool public init(name: String, persistedName: String? = nil, @@ -382,7 +384,8 @@ public struct Entity: Equatable { versionHistory: [VersionHistoryItem] = [], queryContext: Bool = DescriptionDefaults.queryContext, clientQueueName: String = DescriptionDefaults.clientQueueName, - cacheSize: EntityCacheSize = DescriptionDefaults.cacheSize) { + cacheSize: EntityCacheSize = DescriptionDefaults.cacheSize, + sendable: Bool = DescriptionDefaults.sendable) { self.name = name self.persistedName = persistedName @@ -400,6 +403,7 @@ public struct Entity: Equatable { self.queryContext = queryContext self.clientQueueName = clientQueueName self.cacheSize = cacheSize + self.senable = sendable } } diff --git a/CodeGen/Sources/LucidCodeGenCore/MetaUtils.swift b/CodeGen/Sources/LucidCodeGenCore/MetaUtils.swift index dfa69e26..a41aa132 100644 --- a/CodeGen/Sources/LucidCodeGenCore/MetaUtils.swift +++ b/CodeGen/Sources/LucidCodeGenCore/MetaUtils.swift @@ -206,6 +206,10 @@ public extension TypeIdentifier { return TypeIdentifier(name: "CoreDataConversionError") } + static var sendable: TypeIdentifier { + return TypeIdentifier(name: "Sendable") + } + static var equatable: TypeIdentifier { return TypeIdentifier(name: "Equatable") } diff --git a/Lucid/Core/Payload.swift b/Lucid/Core/Payload.swift index ee49d126..0331cbc7 100644 --- a/Lucid/Core/Payload.swift +++ b/Lucid/Core/Payload.swift @@ -85,6 +85,8 @@ public enum Lazy { case unrequested } +extension Lazy: Sendable where T: Sendable {} + public extension Lazy where T: PayloadIdentifiable { func identifier() -> Lazy { diff --git a/Lucid/Utils/AnySequence.swift b/Lucid/Utils/AnySequence.swift index ae71267b..90aa005c 100644 --- a/Lucid/Utils/AnySequence.swift +++ b/Lucid/Utils/AnySequence.swift @@ -61,6 +61,8 @@ extension AnySequence: Equatable where Element: Equatable { } } +extension AnySequence: Sendable where Element: Sendable {} + public extension Result where Success: Sequence { @inlinable var any: Result, Failure> { diff --git a/Lucid/Utils/PropertyBox.swift b/Lucid/Utils/PropertyBox.swift index 8694c8cc..cc82be6a 100644 --- a/Lucid/Utils/PropertyBox.swift +++ b/Lucid/Utils/PropertyBox.swift @@ -9,7 +9,7 @@ import Foundation /// A mutable property which can either ensure atomicity or not. -public final class PropertyBox { +public final class PropertyBox: @unchecked Sendable { private let valueQueue: DispatchQueue? From ebc927a782cb8e6ff9cff5c0f7f0882c9eb37e6b Mon Sep 17 00:00:00 2001 From: vijaysharm Date: Wed, 13 Nov 2024 11:03:13 -0500 Subject: [PATCH 2/3] Allow for subtypes to be sendable --- CodeGen/Sources/LucidCodeGen/Meta/MetaSubtype.swift | 1 + CodeGen/Sources/LucidCodeGenCore/Codable.swift | 2 ++ CodeGen/Sources/LucidCodeGenCore/Descriptions.swift | 2 ++ 3 files changed, 5 insertions(+) diff --git a/CodeGen/Sources/LucidCodeGen/Meta/MetaSubtype.swift b/CodeGen/Sources/LucidCodeGen/Meta/MetaSubtype.swift index a7be3a24..2d0a476f 100644 --- a/CodeGen/Sources/LucidCodeGen/Meta/MetaSubtype.swift +++ b/CodeGen/Sources/LucidCodeGen/Meta/MetaSubtype.swift @@ -50,6 +50,7 @@ struct MetaSubtype { let type = Type(identifier: subtype.typeID()) .with(accessLevel: .public) .adding(inheritedType: .codable) + .adding(inheritedType: subtype.sendable ? .sendable : nil) .adding(inheritedType: .hashable) switch subtype.items { diff --git a/CodeGen/Sources/LucidCodeGenCore/Codable.swift b/CodeGen/Sources/LucidCodeGenCore/Codable.swift index 26c0e11b..edd82af9 100644 --- a/CodeGen/Sources/LucidCodeGenCore/Codable.swift +++ b/CodeGen/Sources/LucidCodeGenCore/Codable.swift @@ -757,6 +757,7 @@ extension Subtype: Codable { case objc case objcNoneCase case platforms + case sendable } public init(from decoder: Decoder) throws { @@ -765,6 +766,7 @@ extension Subtype: Codable { name = try container.decode(String.self, forKey: .name) manualImplementations = Set(try container.decodeIfPresent([`Protocol`].self, forKey: .manualImplementations) ?? []) platforms = try container.decodeIfPresent(Set.self, forKey: .platforms) ?? DescriptionDefaults.platforms + sendable = try container.decodeIfPresent(Bool.self, forKey: .sendable) ?? DescriptionDefaults.sendable if let usedCases = try container.decodeIfPresent([String].self, forKey: .cases) { let unusedCases = try container.decodeIfPresent([String].self, forKey: .unusedCases) ?? [] diff --git a/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift b/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift index 5bf44379..654336bd 100644 --- a/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift +++ b/CodeGen/Sources/LucidCodeGenCore/Descriptions.swift @@ -645,6 +645,8 @@ public struct Subtype: Equatable { public let objc: Bool public let platforms: Set + + public let sendable: Bool } // MARK: - Conversions From f00e18399aa99a8aa11bcfbb44c3640d517c9cfd Mon Sep 17 00:00:00 2001 From: Vijay Sharma Date: Fri, 15 Nov 2024 09:01:59 -0500 Subject: [PATCH 3/3] Update Lucid/Utils/AnySequence.swift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Stanisław Kożuchowicz --- Lucid/Utils/AnySequence.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lucid/Utils/AnySequence.swift b/Lucid/Utils/AnySequence.swift index 90aa005c..20df6a0c 100644 --- a/Lucid/Utils/AnySequence.swift +++ b/Lucid/Utils/AnySequence.swift @@ -61,7 +61,7 @@ extension AnySequence: Equatable where Element: Equatable { } } -extension AnySequence: Sendable where Element: Sendable {} +extension AnySequence: @unchecked Sendable where Element: Sendable {} public extension Result where Success: Sequence {