From 7270607e7c0874c1dd83be2f1f8c24d2336f2e75 Mon Sep 17 00:00:00 2001 From: Muukii Date: Fri, 1 Sep 2023 01:21:54 +0900 Subject: [PATCH] Patch --- Sources/Verge/macros.swift | 40 +++++++++---------- .../VergeMacrosPlugin/IfChangedMacro.swift | 36 +++++++++-------- Tests/VergeTests/MacroTests.swift | 7 ++-- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/Sources/Verge/macros.swift b/Sources/Verge/macros.swift index c49e77d5a7..b1a1855de4 100644 --- a/Sources/Verge/macros.swift +++ b/Sources/Verge/macros.swift @@ -1,29 +1,29 @@ -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, onChanged: (U0) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, onChanged: (U0) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, onChanged: (U0, U1) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, onChanged: (U0, U1) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, onChanged: (U0, U1, U2) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, onChanged: (U0, U1, U2) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, onChanged: (U0, U1, U2, U3) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, onChanged: (U0, U1, U2, U3) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, onChanged: (U0, U1, U2, U3, U4) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, onChanged: (U0, U1, U2, U3, U4) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, _ keyPath_8: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7, U8) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, _ keyPath_8: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7, U8) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") -@freestanding(expression) -public macro ifChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, _ keyPath_8: KeyPath, _ keyPath_9: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7, U8, U9) -> Void) -> Void = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") +@freestanding(declaration) +public macro IfChanged(_ state: Changes, _ keyPath_0: KeyPath, _ keyPath_1: KeyPath, _ keyPath_2: KeyPath, _ keyPath_3: KeyPath, _ keyPath_4: KeyPath, _ keyPath_5: KeyPath, _ keyPath_6: KeyPath, _ keyPath_7: KeyPath, _ keyPath_8: KeyPath, _ keyPath_9: KeyPath, onChanged: (U0, U1, U2, U3, U4, U5, U6, U7, U8, U9) -> Void) = #externalMacro(module: "VergeMacrosPlugin", type: "IfChangedMacro") diff --git a/Sources/VergeMacrosPlugin/IfChangedMacro.swift b/Sources/VergeMacrosPlugin/IfChangedMacro.swift index fe371a84e1..facee57912 100644 --- a/Sources/VergeMacrosPlugin/IfChangedMacro.swift +++ b/Sources/VergeMacrosPlugin/IfChangedMacro.swift @@ -2,18 +2,21 @@ import SwiftSyntax import SwiftSyntaxBuilder import SwiftSyntaxMacros -public struct IfChangedMacro: ExpressionMacro { +public struct IfChangedMacro: Macro { public enum Error: Swift.Error { case foundNotKeyPathLiteral case faildToExpand - } +} + +extension IfChangedMacro: DeclarationMacro { + public static func expansion( of node: some SwiftSyntax.FreestandingMacroExpansionSyntax, in context: some SwiftSyntaxMacros.MacroExpansionContext - ) throws -> SwiftSyntax.ExprSyntax { + ) throws -> [SwiftSyntax.DeclSyntax] { let onChangedClosure: ClosureExprSyntax @@ -42,7 +45,7 @@ public struct IfChangedMacro: ExpressionMacro { ).components let name = - components + components .map { $0.cast(KeyPathComponentSyntax.self).component.cast( KeyPathPropertyComponentSyntax.self @@ -56,21 +59,20 @@ public struct IfChangedMacro: ExpressionMacro { let conditions = names.map { arg in - return - ( - condition: """ + return ( + condition: """ primitiveState\(arg.1) != previousState?\(arg.1) """, - property: """ + property: """ let \(arg.0) = primitiveState\(arg.1) """, - accessor: "primitiveState\(arg.1)" - ) + accessor: "primitiveState\(arg.1)" + ) } - return """ - - { () -> Void in + return [ + (""" + do { let primitiveState = \(stateExpr).primitive let previousState = \(stateExpr).previous?.primitive @@ -79,10 +81,10 @@ public struct IfChangedMacro: ExpressionMacro { return } - let _: Void = \(onChangedClosure)(\(raw: conditions.map { $0.accessor }.joined(separator: ","))) - }() - """ - + let _: Void = \(onChangedClosure)(\(raw: conditions.map { $0.accessor }.joined(separator: ", "))) + } + """ as DeclSyntax) + ] } } diff --git a/Tests/VergeTests/MacroTests.swift b/Tests/VergeTests/MacroTests.swift index 3c4afc8a6d..7eee45fd50 100644 --- a/Tests/VergeTests/MacroTests.swift +++ b/Tests/VergeTests/MacroTests.swift @@ -1,5 +1,6 @@ import Verge import XCTest +import SwiftUI final class MacroTests: XCTestCase { @@ -7,15 +8,15 @@ final class MacroTests: XCTestCase { let state: Changes = .init(old: nil, new: .init(name: "hello")) - #ifChanged(state, \.name) { name in + #IfChanged(state, \.name) { name in print(name) } - #ifChanged(state, \.name, \.count) { name, count in + #IfChanged(state, \.name, \.count) { name, count in print(name, count) } - #ifChanged(state, \.name, \.count, onChanged: { name, count in + #IfChanged(state, \.name, \.count, onChanged: { name, count in print(name, count) })