From 4be2231320de22e7233243c10dbbbb5a0e483283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolaj=20Pogne=CC=8Crebko?= Date: Thu, 20 Mar 2025 12:01:07 +0100 Subject: [PATCH] Added support of ViewAction for preprocessor macros --- .../ViewActionMacro.swift | 22 +++++++++--- .../ViewActionMacroTests.swift | 34 +++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Sources/ComposableArchitectureMacros/ViewActionMacro.swift b/Sources/ComposableArchitectureMacros/ViewActionMacro.swift index 69e444978739..42595296a71e 100644 --- a/Sources/ComposableArchitectureMacros/ViewActionMacro.swift +++ b/Sources/ComposableArchitectureMacros/ViewActionMacro.swift @@ -121,10 +121,24 @@ extension SyntaxProtocol { } } -extension DeclGroupSyntax { - fileprivate var hasStoreVariable: Bool { - self.memberBlock.members.contains(where: { member in - if let variableDecl = member.decl.as(VariableDeclSyntax.self), +private extension DeclGroupSyntax { + var hasStoreVariable: Bool { + let members = memberBlock.members + return members.contains(where: { member in + + let variableDecl: VariableDeclSyntax? = + if + let ifConfigDecl = member.decl.as(IfConfigDeclSyntax.self), + let firstClause = ifConfigDecl.clauses.first, + let member = firstClause.elements?.as(MemberBlockItemListSyntax.self)?.first + { + member.decl.as(VariableDeclSyntax.self) + } else { + member.decl.as(VariableDeclSyntax.self) + } + + if + let variableDecl, let firstBinding = variableDecl.bindings.first, let identifierPattern = firstBinding.pattern.as(IdentifierPatternSyntax.self), identifierPattern.identifier.text == "store" diff --git a/Tests/ComposableArchitectureMacrosTests/ViewActionMacroTests.swift b/Tests/ComposableArchitectureMacrosTests/ViewActionMacroTests.swift index b4f404626038..f49686beba51 100644 --- a/Tests/ComposableArchitectureMacrosTests/ViewActionMacroTests.swift +++ b/Tests/ComposableArchitectureMacrosTests/ViewActionMacroTests.swift @@ -120,6 +120,40 @@ """ } } + + func testBindableStore_WithPreprocessorMacro() { + assertMacro { + """ + @ViewAction(for: Feature.self) + struct FeatureView: View { + #if canImport(AppKit) + @Perception.Bindable var store: StoreOf + #else + @Bindable var store: StoreOf + #endif + var body: some View { + EmptyView() + } + } + """ + } expansion: { + """ + struct FeatureView: View { + #if canImport(AppKit) + @Perception.Bindable var store: StoreOf + #else + @Bindable var store: StoreOf + #endif + var body: some View { + EmptyView() + } + } + + extension FeatureView: ComposableArchitecture.ViewActionSending { + } + """ + } + } func testNoStore() { assertMacro {