diff --git a/Package.swift b/Package.swift index 0d084bf..4a12760 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( .macro( name: "MacrosImplementation", dependencies: [ - "SyntaxHelper", + "SwiftSyntaxHelper", .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), .product(name: "SwiftDiagnostics", package: "swift-syntax"), @@ -34,7 +34,7 @@ let package = Package( ), .target( - name: "SyntaxHelper", + name: "SwiftSyntaxHelper", dependencies: [ .product(name: "SwiftSyntax", package: "swift-syntax"), ], @@ -62,6 +62,7 @@ let package = Package( .testTarget( name: "Bibbi-MacroTests", dependencies: [ + "SwiftSyntaxHelper", "MacrosImplementation", .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), ], diff --git a/README.md b/README.md index d7d67f8..6ada9dc 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,16 @@ - [x] [@Codable]() - [x] [@CodableKey(_:)]() -- [x] [@Deprecated]() -- [x] [@DependencyValue(for:)]() +- [x] ~~[@Deprecated]()~~ _(Deprecated)_ +- [x] ~~[@DependencyValue(for:)]()~~ _(Deprecated)_ - [x] [@DependencyOrganizer]() +- [x] [@Reactor]() - [x] [@Wrapper]() - [x] (@WrapperView) ### Libraries +- [x] [DIContainer]() - [x] [Dependencies]() - [x] [ReactorKit]() @@ -30,4 +32,4 @@ | 버전 | 내용 | | :----: | :------------------: | -| - | - | +| v0.1.0 | `@Codable`, `@Wrapper` 매크로 구현 등 | diff --git a/Sources/Macros/Implementation/Extension/ReactorMacro.swift b/Sources/Macros/Implementation/Extension/ReactorMacro.swift new file mode 100644 index 0000000..4183f0f --- /dev/null +++ b/Sources/Macros/Implementation/Extension/ReactorMacro.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by 김건우 on 6/5/24. +// + +import SwiftSyntax +import SwiftSyntaxBuilder +import SwiftSyntaxMacros + +public struct ReactorMacro: ExtensionMacro { + + public static func expansion( + of node: AttributeSyntax, + attachedTo declaration: some DeclGroupSyntax, + providingExtensionsOf type: some TypeSyntaxProtocol, + conformingTo protocols: [TypeSyntax], + in context: some MacroExpansionContext + ) throws -> [ExtensionDeclSyntax] { + let reactorExtension = try ExtensionDeclSyntax("extension \(type.trimmed): Reactor { }") + + return [reactorExtension] + } + +} diff --git a/Sources/Macros/Implementation/MemberAttribute/DependencyValuesMacro.swift b/Sources/Macros/Implementation/MemberAttribute/DependencyOrganizerMacro.swift similarity index 98% rename from Sources/Macros/Implementation/MemberAttribute/DependencyValuesMacro.swift rename to Sources/Macros/Implementation/MemberAttribute/DependencyOrganizerMacro.swift index 161c343..55d07d0 100644 --- a/Sources/Macros/Implementation/MemberAttribute/DependencyValuesMacro.swift +++ b/Sources/Macros/Implementation/MemberAttribute/DependencyOrganizerMacro.swift @@ -8,7 +8,7 @@ import SwiftSyntax import SwiftSyntaxBuilder import SwiftSyntaxMacros -import SyntaxHelper +import SwiftSyntaxHelper public struct DependencyOrganizerMacro: MemberAttributeMacro { diff --git a/Sources/Macros/Implementation/Plugin.swift b/Sources/Macros/Implementation/Plugin.swift index 2a9ad2d..779ceca 100644 --- a/Sources/Macros/Implementation/Plugin.swift +++ b/Sources/Macros/Implementation/Plugin.swift @@ -17,6 +17,7 @@ struct Bibbi_MacroPlugin: CompilerPlugin { WrapperMacro.self, WrapperViewMacro.self, URLMacro.self, + ReactorMacro.self, DependencyOrganizerMacro.self, DeprecatedMacro.self ] diff --git a/Sources/Macros/Interface/AccessorMacrosInterface.swift b/Sources/Macros/Interface/AccessorMacrosInterface.swift index a2bd482..8027fbc 100644 --- a/Sources/Macros/Interface/AccessorMacrosInterface.swift +++ b/Sources/Macros/Interface/AccessorMacrosInterface.swift @@ -32,6 +32,7 @@ import Dependencies /// /// Author: - 김소월 /// +@available(*, deprecated) @attached(accessor) public macro DependencyValue(for: any DependencyKey.Type) = #externalMacro( module: "MacrosImplementation", diff --git a/Sources/Macros/Interface/ExtensionMacrosInterface.swift b/Sources/Macros/Interface/ExtensionMacrosInterface.swift new file mode 100644 index 0000000..8a30334 --- /dev/null +++ b/Sources/Macros/Interface/ExtensionMacrosInterface.swift @@ -0,0 +1,18 @@ +// +// File.swift +// +// +// Created by 김건우 on 6/5/24. +// + +import ReactorKit + +// MARK: - Reactor Extension + +/// 타입이 Reactor 프로토콜을 준수하게 합니다. +/// - Author: 김소월 +@attached(extension, conformances: Reactor) +public macro Reactor() = #externalMacro( + module: "MacrosImplementation", + type: "ReactorMacro" +) diff --git a/Sources/Macros/Interface/MemberAttributeMacrosInterface.swift b/Sources/Macros/Interface/MemberAttributeMacrosInterface.swift index 11b1e8d..407478a 100644 --- a/Sources/Macros/Interface/MemberAttributeMacrosInterface.swift +++ b/Sources/Macros/Interface/MemberAttributeMacrosInterface.swift @@ -50,6 +50,7 @@ public macro Deprecated() = #externalMacro( /// /// - Warning: 이 매크로는 Extension에만 적용할 수 있습니다. /// +@available(*, deprecated) @attached(memberAttribute) public macro DependencyOrganizer() = #externalMacro( module: "MacrosImplementation", diff --git a/Sources/Macros/Playground/AccessorMacrosPlayground.swift b/Sources/Macros/Playground/AccessorMacrosPlayground.swift index c10637f..55cdbc3 100644 --- a/Sources/Macros/Playground/AccessorMacrosPlayground.swift +++ b/Sources/Macros/Playground/AccessorMacrosPlayground.swift @@ -46,7 +46,7 @@ struct MemberRepoKey: DependencyKey { static let liveValue: MemberRepositoryProtocol = MemberRepository() } -// DependencyValues +// DependencyOrganizer @DependencyOrganizer extension DependencyValues { var meRepository: MeRepositoryProtocol diff --git a/Sources/Macros/Playground/ExtensionMacrosPlayground.swift b/Sources/Macros/Playground/ExtensionMacrosPlayground.swift new file mode 100644 index 0000000..41273c6 --- /dev/null +++ b/Sources/Macros/Playground/ExtensionMacrosPlayground.swift @@ -0,0 +1,28 @@ +// +// File.swift +// +// +// Created by 김건우 on 6/5/24. +// + +import ReactorKit +import MacrosInterface + +// MARK: - Reactor Extension + +@Reactor +public class CommentReactor { + public typealias Action = NoAction + public struct State { } + public var initialState = State() +} + + + + +func runExtensionMacrosPlayground() { + + let reactor = CommentReactor() + print("CommentReactor: \(reactor)") + +} diff --git a/Sources/Macros/Playground/main.swift b/Sources/Macros/Playground/main.swift index 09ea0e6..6fd914e 100644 --- a/Sources/Macros/Playground/main.swift +++ b/Sources/Macros/Playground/main.swift @@ -22,6 +22,11 @@ runComplexMacorsPlayground() runExressionMacrosPlayground() +// MARK: - Extension Macros + +runExtensionMacrosPlayground() + + // MARK: - MemberAttribute Macros runMemberAttributeMacrosPlayground() diff --git a/Tests/Macros/Extension/ReactorMacroTests.swift b/Tests/Macros/Extension/ReactorMacroTests.swift new file mode 100644 index 0000000..a8f9443 --- /dev/null +++ b/Tests/Macros/Extension/ReactorMacroTests.swift @@ -0,0 +1,39 @@ +// +// File.swift +// +// +// Created by 김건우 on 6/5/24. +// + +import SwiftSyntaxMacros +import SwiftSyntaxMacrosTestSupport +import MacrosImplementation +import XCTest +import SyntaxHelper + +fileprivate let testMacros: [String: Macro.Type] = [ + "Reactor": ReactorMacro.self +] + +final class ReactorMacroTests: XCTestCase { + + func testReactorMacro() throws { + + assertMacroExpansion( + """ + @Reactor + class testReactor { } + """, + expandedSource: + """ + class testReactor { } + + extension testReactor: Reactor { + } + """, + macros: testMacros + ) + + } + +}