diff --git a/Sources/DependenciesMacros/Macros.swift b/Sources/DependenciesMacros/Macros.swift index 510f18bd..7ffb3ad0 100644 --- a/Sources/DependenciesMacros/Macros.swift +++ b/Sources/DependenciesMacros/Macros.swift @@ -272,6 +272,76 @@ public macro _DependencyEntryDefaultValue() = type: "DependencyEntryDefaultValueMacro" ) +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(_: () -> Void) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryIsolationCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(_: @MainActor () -> Void) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryMainActorIsolationCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(keyPath: KeyPath) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryIsolationCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(keyPath: KeyPath) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntrySendableCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(client: () -> Void) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryIsolationCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro IsolationCheck(client: @MainActor () -> Void) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyClientMainActorCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro TypeCheck( + _: KeyPath, + liveValue: @autoclosure @MainActor () -> Value +) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryIsolationCheckMacro" + ) + +@_documentation(visibility: private) +@freestanding(declaration) +public macro TypeCheck( + _: KeyPath, + previewValue: @autoclosure @MainActor () -> Value +) = + #externalMacro( + module: "DependenciesMacrosPlugin", + type: "DependencyEntryIsolationCheckMacro" + ) + /// The error thrown by "unimplemented" closures produced by ``DependencyEndpoint(method:)`` public struct Unimplemented: Error { let endpoint: String diff --git a/Sources/DependenciesMacrosPlugin/DependencyClientMacro.swift b/Sources/DependenciesMacrosPlugin/DependencyClientMacro.swift index 28c0bbb6..ed3033f5 100644 --- a/Sources/DependenciesMacrosPlugin/DependencyClientMacro.swift +++ b/Sources/DependenciesMacrosPlugin/DependencyClientMacro.swift @@ -231,18 +231,48 @@ public enum DependencyClientMacro: MemberAttributeMacro, MemberMacro { guard hasEndpoints else { return [] } let access = accesses.min().flatMap { $0.token?.with(\.trailingTrivia, .space) } // TODO: Don't define initializers if any single endpoint is invalid - return [properties, properties.filter { !$0.isEndpoint }].map { - $0.isEmpty - ? "\(access)init() {}" + return [(properties, isolationCheck(for: node, in: context)), (properties.filter { !$0.isEndpoint }, "")].map { + (properties, check) in + properties.isEmpty + ? """ + \(access)init() {\(raw: check)} + """ : """ \(access)init( - \(raw: $0.map { $0.declaration.bindings.trimmedDescription }.joined(separator: ",\n")) - ) { - \(raw: $0.map { "self.\($0.identifier) = \($0.identifier)" }.joined(separator: "\n")) + \(raw: properties.map { $0.declaration.bindings.trimmedDescription }.joined(separator: ",\n")) + ) {\(raw: check) + \(raw: properties.map { "self.\($0.identifier) = \($0.identifier)" }.joined(separator: "\n")) } """ } } + + private static func isolationCheck( + for node: AttributeSyntax, + in context: some MacroExpansionContext + ) -> String { + let probeName = "__dependencyClientIsolationProbe" + guard + let location = context.location(of: node, at: .afterLeadingTrivia, filePathMode: .filePath) + else { + return """ + + #if DEBUG + func \(probeName)() {} + #IsolationCheck(client: \(probeName)) + #endif + """ + } + return """ + + #if DEBUG + func \(probeName)() {} + #sourceLocation(file: \(location.file), line: \(location.line)) + #IsolationCheck(client: \(probeName)) + #sourceLocation() + #endif + """ + } } private enum Access: Comparable { diff --git a/Sources/DependenciesMacrosPlugin/DependencyEntryMacro.swift b/Sources/DependenciesMacrosPlugin/DependencyEntryMacro.swift index 2db39d67..4de7ee43 100644 --- a/Sources/DependenciesMacrosPlugin/DependencyEntryMacro.swift +++ b/Sources/DependenciesMacrosPlugin/DependencyEntryMacro.swift @@ -23,7 +23,10 @@ extension DependencyEntryMacro: AccessorMacro { let keyName = keyTypeName(for: node, property: property, identifier: identifier) return [ """ - get { self[\(keyName).self] } + get { + \(entryChecks(for: node, identifier: identifier, in: context)) + return self[\(keyName).self] + } """, """ set { self[\(keyName).self] = newValue } @@ -136,7 +139,7 @@ extension DependencyEntryMacro: PeerMacro { \(raw: body) } """ - return [keyDecl] + return sendableCheck(for: node, identifier: identifier, in: context) + [keyDecl] } } @@ -258,6 +261,171 @@ private func isInDependencyValuesExtension( return name == "DependencyValues" } +private let isolationProbeName = "__dependencyEntryIsolationProbe" + +private func entryValueArguments( + from node: AttributeSyntax +) -> (liveValue: ExprSyntax?, previewValue: ExprSyntax?) { + var liveValueExpr: ExprSyntax? + var previewValueExpr: ExprSyntax? + if let arguments = node.arguments?.as(LabeledExprListSyntax.self) { + for argument in arguments { + switch argument.label?.text { + case "liveValue": + liveValueExpr = argument.expression + case "previewValue": + previewValueExpr = argument.expression + default: + break + } + } + } + return (liveValueExpr, previewValueExpr) +} + +private func extendedType(in context: some MacroExpansionContext) -> TypeSyntax? { + context.lexicalContext.first?.as(ExtensionDeclSyntax.self)?.extendedType.trimmed +} + +private func entryChecks( + for node: AttributeSyntax, + identifier: TokenSyntax, + in context: some MacroExpansionContext +) -> CodeBlockItemListSyntax { + var checks = ["#IsolationCheck(\(isolationProbeName))"] + if let extendedType = extendedType(in: context) { + let (liveValueExpr, previewValueExpr) = entryValueArguments(from: node) + if let liveValueExpr { + checks.append( + "#TypeCheck(\\\(extendedType).\(identifier), liveValue: \(liveValueExpr.trimmed))" + ) + } + if let previewValueExpr { + checks.append( + "#TypeCheck(\\\(extendedType).\(identifier), previewValue: \(previewValueExpr.trimmed))" + ) + } + } + guard + let location = context.location(of: node, at: .afterLeadingTrivia, filePathMode: .filePath) + else { + return """ + #if DEBUG + func \(raw: isolationProbeName)() {} + \(raw: checks.joined(separator: "\n")) + #endif + """ + } + let directive = "#sourceLocation(file: \(location.file), line: \(location.line))" + return """ + #if DEBUG + func \(raw: isolationProbeName)() {} + \(raw: checks.map { "\(directive)\n\($0)" }.joined(separator: "\n")) + #sourceLocation() + #endif + """ +} + +private func sendableCheck( + for node: AttributeSyntax, + identifier: TokenSyntax, + in context: some MacroExpansionContext +) -> [DeclSyntax] { + guard let extendedType = extendedType(in: context) + else { + return [] + } + let check = "#IsolationCheck(keyPath: \\\(extendedType).\(identifier))" + guard + let location = context.location(of: node, at: .afterLeadingTrivia, filePathMode: .filePath) + else { + return [ + """ + #if DEBUG + \(raw: check) + #endif + """ + ] + } + return [ + """ + #if DEBUG + #sourceLocation(file: \(location.file), line: \(location.line)) + \(raw: check) + #sourceLocation() + #endif + """ + ] +} + +public enum DependencyEntryIsolationCheckMacro {} + +extension DependencyEntryIsolationCheckMacro: DeclarationMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + [] + } +} + +public enum DependencyEntryMainActorIsolationCheckMacro {} + +extension DependencyEntryMainActorIsolationCheckMacro: DeclarationMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + context.diagnose( + Diagnostic( + node: node, + message: MacroExpansionErrorMessage( + "entry must be 'nonisolated var' when default isolation is '@MainActor'" + ) + ) + ) + return [] + } +} + +public enum DependencyClientMainActorCheckMacro {} + +extension DependencyClientMainActorCheckMacro: DeclarationMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + context.diagnose( + Diagnostic( + node: node, + message: MacroExpansionErrorMessage( + "client must be 'nonisolated struct' when default isolation is '@MainActor'" + ) + ) + ) + return [] + } +} + +public enum DependencyEntrySendableCheckMacro {} + +extension DependencyEntrySendableCheckMacro: DeclarationMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + context.diagnose( + Diagnostic( + node: node, + message: MacroExpansionErrorMessage( + "entry value must be 'Sendable'" + ) + ) + ) + return [] + } +} + public enum DependencyEntryDefaultValueMacro {} extension DependencyEntryDefaultValueMacro: AccessorMacro { diff --git a/Sources/DependenciesMacrosPlugin/Plugins.swift b/Sources/DependenciesMacrosPlugin/Plugins.swift index 7db35d98..2ea89bfb 100644 --- a/Sources/DependenciesMacrosPlugin/Plugins.swift +++ b/Sources/DependenciesMacrosPlugin/Plugins.swift @@ -9,5 +9,9 @@ struct MacrosPlugin: CompilerPlugin { DependencyEndpointIgnoredMacro.self, DependencyEntryMacro.self, DependencyEntryDefaultValueMacro.self, + DependencyEntryIsolationCheckMacro.self, + DependencyEntryMainActorIsolationCheckMacro.self, + DependencyEntrySendableCheckMacro.self, + DependencyClientMainActorCheckMacro.self, ] } diff --git a/Tests/DependenciesMacrosPluginTests/DependencyClientMacroTests.swift b/Tests/DependenciesMacrosPluginTests/DependencyClientMacroTests.swift index 624a5381..91a1ba88 100644 --- a/Tests/DependenciesMacrosPluginTests/DependencyClientMacroTests.swift +++ b/Tests/DependenciesMacrosPluginTests/DependencyClientMacroTests.swift @@ -33,6 +33,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Bool = false, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -63,6 +70,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -93,6 +107,13 @@ final class DependencyClientMacroTests: BaseTestCase { endpoint: @escaping () -> Void, config: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint self.config = config } @@ -127,6 +148,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Swift.Bool = false, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -161,6 +189,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Swift.Double = 1.0, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -195,6 +230,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Swift.Int = 1, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -229,6 +271,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Swift.String = "Blob", endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -263,6 +312,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Bool, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } @@ -296,6 +352,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( config: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config } @@ -323,6 +386,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @escaping () -> Int ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -352,6 +422,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -381,6 +458,13 @@ final class DependencyClientMacroTests: BaseTestCase { public init( endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -410,6 +494,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -437,6 +528,13 @@ final class DependencyClientMacroTests: BaseTestCase { package init( endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -464,6 +562,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -494,6 +599,13 @@ final class DependencyClientMacroTests: BaseTestCase { name: String? = nil, endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.name = name self.endpoint = endpoint } @@ -533,6 +645,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -572,6 +691,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -607,6 +733,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () throws -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -644,6 +777,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -683,6 +823,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -712,6 +859,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -742,6 +896,13 @@ final class DependencyClientMacroTests: BaseTestCase { id: UUID, endpoint: @Sendable @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.id = id self.endpoint = endpoint } @@ -794,6 +955,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( endpoint: @Sendable @escaping () -> Int ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint } @@ -837,6 +1005,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( fetch: @escaping (_ id: Int) throws -> String ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.fetch = fetch } @@ -881,6 +1056,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( fetch: @escaping (_ id: Int) throws -> String ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.fetch = fetch } @@ -919,6 +1101,13 @@ final class DependencyClientMacroTests: BaseTestCase { init( fetch: @escaping (Int) throws -> String ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.fetch = fetch } @@ -968,6 +1157,13 @@ final class DependencyClientMacroTests: BaseTestCase { endpoint: @escaping () -> Void, value: <#Type#> = Value() ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.endpoint = endpoint self.value = value } @@ -1050,6 +1246,13 @@ final class DependencyClientMacroTests: BaseTestCase { foo: @escaping () -> String, bar: @escaping () -> String ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.foo = foo self.bar = bar } @@ -1081,6 +1284,13 @@ final class DependencyClientMacroTests: BaseTestCase { config: Bool = false, endpoint: @escaping () -> Void ) { + #if DEBUG + func __dependencyClientIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 1) + #IsolationCheck(client: __dependencyClientIsolationProbe) + #sourceLocation() + #endif self.config = config self.endpoint = endpoint } diff --git a/Tests/DependenciesMacrosPluginTests/DependencyEntryMacroTests.swift b/Tests/DependenciesMacrosPluginTests/DependencyEntryMacroTests.swift index d9ec3460..ff75aec1 100644 --- a/Tests/DependenciesMacrosPluginTests/DependencyEntryMacroTests.swift +++ b/Tests/DependenciesMacrosPluginTests/DependencyEntryMacroTests.swift @@ -22,11 +22,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -36,12 +45,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.DependencyKey { @DependenciesMacros._DependencyEntryDefaultValue static var liveValue = Client.live @DependenciesMacros._DependencyEntryDefaultValue static var testValue = Client.test } } - """ + """# } } @@ -54,11 +69,22 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, previewValue: Client.preview) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -68,13 +94,19 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.DependencyKey { @DependenciesMacros._DependencyEntryDefaultValue static var liveValue = Client.live @DependenciesMacros._DependencyEntryDefaultValue static var previewValue = Client.preview @DependenciesMacros._DependencyEntryDefaultValue static var testValue = Client.test } } - """ + """# } } @@ -87,11 +119,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, previewValue: Client.preview) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -101,12 +142,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.TestDependencyKey { @DependenciesMacros._DependencyEntryDefaultValue static var previewValue = Client.preview @DependenciesMacros._DependencyEntryDefaultValue static var testValue = Client.test } } - """ + """# } } @@ -119,11 +166,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -133,11 +187,17 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.TestDependencyKey { @DependenciesMacros._DependencyEntryDefaultValue static var testValue = Client.test } } - """ + """# } } @@ -150,11 +210,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client: Client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -164,6 +233,12 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.DependencyKey { typealias Value = Client static var liveValue: Value { @@ -174,7 +249,7 @@ final class DependencyEntryMacroTests: BaseTestCase { } } } - """ + """# } } @@ -246,11 +321,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { var client: Client { get { - self[__Key_client.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation() + #endif + return self[__Key_client.self] } set { self[__Key_client.self] = newValue @@ -260,6 +344,12 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + private nonisolated enum __Key_client: Dependencies.DependencyKey { typealias Value = Client static var liveValue: Value { @@ -267,7 +357,7 @@ final class DependencyEntryMacroTests: BaseTestCase { } } } - """ + """# } } @@ -280,11 +370,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { public var client { get { - self[APIClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation() + #endif + return self[APIClientKey.self] } set { self[APIClientKey.self] = newValue @@ -294,12 +393,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + public nonisolated enum APIClientKey: Dependencies.DependencyKey { @DependenciesMacros._DependencyEntryDefaultValue public static var liveValue = Client.live @DependenciesMacros._DependencyEntryDefaultValue public static var testValue = Client.test } } - """ + """# } } @@ -312,11 +417,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { package var client { get { - self[ClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation() + #endif + return self[ClientKey.self] } set { self[ClientKey.self] = newValue @@ -326,11 +438,17 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + package nonisolated enum ClientKey: Dependencies.TestDependencyKey { @DependenciesMacros._DependencyEntryDefaultValue package static var testValue = Client.test } } - """ + """# } } @@ -343,11 +461,20 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { public var client { get { - self[ClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation(file: "Test.swift", line: 2) + #TypeCheck(\DependencyValues.client, liveValue: Client.live) + #sourceLocation() + #endif + return self[ClientKey.self] } set { self[ClientKey.self] = newValue @@ -357,12 +484,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + public nonisolated enum ClientKey: Dependencies.DependencyKey { @DependenciesMacros._DependencyEntryDefaultValue public static var liveValue = Client.live @DependenciesMacros._DependencyEntryDefaultValue public static var testValue = Client.test } } - """ + """# } } @@ -375,11 +508,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { public var client: any APIClient { get { - self[ExplicitAPIClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation() + #endif + return self[ExplicitAPIClientKey.self] } set { self[ExplicitAPIClientKey.self] = newValue @@ -389,6 +529,12 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + public nonisolated enum ExplicitAPIClientKey: Dependencies.TestDependencyKey { public typealias Value = any APIClient public static var testValue: Value { @@ -396,7 +542,7 @@ final class DependencyEntryMacroTests: BaseTestCase { } } } - """ + """# } } @@ -409,11 +555,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { public var client: MockAPIClient { get { - self[MockAPIClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation() + #endif + return self[MockAPIClientKey.self] } set { self[MockAPIClientKey.self] = newValue @@ -423,6 +576,12 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + public nonisolated enum MockAPIClientKey: Dependencies.TestDependencyKey { public typealias Value = MockAPIClient public static var testValue: Value { @@ -430,7 +589,7 @@ final class DependencyEntryMacroTests: BaseTestCase { } } } - """ + """# } } @@ -443,11 +602,18 @@ final class DependencyEntryMacroTests: BaseTestCase { } """ } expansion: { - """ + #""" extension DependencyValues { public var client: any APIClient { get { - self[APIClientKey.self] + #if DEBUG + func __dependencyEntryIsolationProbe() { + } + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(__dependencyEntryIsolationProbe) + #sourceLocation() + #endif + return self[APIClientKey.self] } set { self[APIClientKey.self] = newValue @@ -457,6 +623,12 @@ final class DependencyEntryMacroTests: BaseTestCase { } } + #if DEBUG + #sourceLocation(file: "Test.swift", line: 2) + #IsolationCheck(keyPath: \DependencyValues.client) + #sourceLocation() + #endif + public nonisolated enum APIClientKey: Dependencies.TestDependencyKey { public typealias Value = any APIClient public static var testValue: Value { @@ -464,7 +636,7 @@ final class DependencyEntryMacroTests: BaseTestCase { } } } - """ + """# } } }