Skip to content

Commit

Permalink
Merge pull request #13 from bibbi-team/feat/#12-WrapperView-매크로-구현
Browse files Browse the repository at this point in the history
feat: @WrapperView 매크로 구현
  • Loading branch information
rlarjsdn3 authored Jun 5, 2024
2 parents daeef2e + 847230b commit 1e2e662
Show file tree
Hide file tree
Showing 22 changed files with 421 additions and 48 deletions.
11 changes: 7 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ let package = Package(
.macro(
name: "MacrosImplementation",
dependencies: [
"MacrosHelper",
.product(name: "SwiftSyntax", package: "swift-syntax"),
"SwiftSyntaxHelper",
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
Expand All @@ -35,8 +34,11 @@ let package = Package(
),

.target(
name: "MacrosHelper",
path: "Sources/Macros/Helper"
name: "SwiftSyntaxHelper",
dependencies: [
.product(name: "SwiftSyntax", package: "swift-syntax"),
],
path: "Sources/Macros/SyntaxHelper"
),

.target(
Expand All @@ -60,6 +62,7 @@ let package = Package(
.testTarget(
name: "Bibbi-MacroTests",
dependencies: [
"SwiftSyntaxHelper",
"MacrosImplementation",
.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"),
],
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@

### Macros

- [v] [@Codable]()
- [v] [@CodableKey(_:)]()
- [v] [@Deprecated]()
- [v] [@DependencyValue(for:)]()
- [v] [@DependencyValues]()
- [v] [@Wrapper]()
- [x] ~~[#URL]()~~ _(Deprecated)_

- [x] [@Codable]()
- [x] [@CodableKey(_:)]()
- [x] ~~[@Deprecated]()~~ _(Deprecated)_
- [x] ~~[@DependencyValue(for:)]()~~ _(Deprecated)_
- [x] [@DependencyOrganizer]()
- [x] [@Reactor]()
- [x] [@Wrapper]()
- [x] (@WrapperView)

### Libraries

- [x] [DIContainer]()
- [x] [Dependencies]()
- [x] [ReactorKit]()

## Requirements

Expand All @@ -22,4 +32,4 @@

| 버전 | 내용 |
| :----: | :------------------: |
| - | - |
| v0.1.0 | `@Codable`, `@Wrapper` 매크로 구현 등 |
12 changes: 7 additions & 5 deletions Sources/Macros/Implementation/Complex/WrapperMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,29 @@ extension WrapperMacro: MemberMacro {
throw MacroError.message("매크로 선언으로 전달된 Generic 타입이 유효하지 않습니다.")
}

let scope = declaration.getAccessControl()

return [
"""
public typealias R = \(firstGenericType)
\(scope)typealias R = \(firstGenericType)
""",
"""
public typealias V = \(lastGenericType)
\(scope)typealias V = \(lastGenericType)
""",

"""
public func makeViewController() -> V {
\(scope)func makeViewController() -> V {
return \(lastGenericType)(reactor: makeReactor())
}
""",

"""
public var viewController: V {
\(scope)var viewController: V {
return makeViewController()
}
""",
"""
public var reactor: R {
\(scope)var reactor: R {
return makeReactor()
}
"""
Expand Down
88 changes: 88 additions & 0 deletions Sources/Macros/Implementation/Complex/WrapperViewMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//
// File.swift
//
//
// Created by 김건우 on 6/3/24.
//

import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct WrapperViewMacro { }

extension WrapperViewMacro: MemberMacro {

public static func expansion(
of node: AttributeSyntax,
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
guard
let _ = declaration.as(ClassDeclSyntax.self)
else {
throw MacroError.message("이 매크로는 Class에만 적용할 수 있습니다.")
}

guard
let genericArguments = node.attributeName
.as(IdentifierTypeSyntax.self)?
.genericArgumentClause?
.arguments,
let firstGenericType = genericArguments
.first?
.argument,
let lastGenericType = genericArguments
.last?
.argument
else {
throw MacroError.message("매크로 선언으로 전달된 Generic 타입이 유효하지 않습니다.")
}

let scope = declaration.getAccessControl()

return [
"""
\(scope)typealias R = \(firstGenericType)
""",
"""
\(scope)typealias V = \(lastGenericType)
""",

"""
\(scope)func makeView() -> V {
return \(lastGenericType)(reactor: makeReactor())
}
""",

"""
\(scope)var view: V {
return makeView()
}
""",
"""
\(scope)var reactor: R {
return makeReactor()
}
"""
]
}

}

extension WrapperViewMacro: 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 baseWrapperExtension = try ExtensionDeclSyntax("extension \(type.trimmed): BaseWrapper { }")

return [baseWrapperExtension]
}

}

26 changes: 26 additions & 0 deletions Sources/Macros/Implementation/Extension/ReactorMacro.swift
Original file line number Diff line number Diff line change
@@ -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]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
// Created by 김건우 on 6/1/24.
//

import MacrosHelper
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros
import SwiftSyntaxHelper

public struct DependencyValuesMacro: MemberAttributeMacro {
public struct DependencyOrganizerMacro: MemberAttributeMacro {

public static func expansion(
of node: AttributeSyntax,
Expand All @@ -36,7 +36,7 @@ public struct DependencyValuesMacro: MemberAttributeMacro {
}

if !varDecl.attributes.isAttributeApplied("DependencyValue") {
let capitalizedIdentifier = identifier.capitalizeFirstLetter()
let capitalizedIdentifier = identifier.makeFirstLetterLowercase()

return [
"""
Expand Down
4 changes: 3 additions & 1 deletion Sources/Macros/Implementation/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ struct Bibbi_MacroPlugin: CompilerPlugin {
CodableKeyMacro.self,
CodableMacro.self,
WrapperMacro.self,
WrapperViewMacro.self,
URLMacro.self,
DependencyValuesMacro.self,
ReactorMacro.self,
DependencyOrganizerMacro.self,
DeprecatedMacro.self
]
}
1 change: 1 addition & 0 deletions Sources/Macros/Interface/AccessorMacrosInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import Dependencies
///
/// Author: - 김소월
///
@available(*, deprecated)
@attached(accessor)
public macro DependencyValue(for: any DependencyKey.Type) = #externalMacro(
module: "MacrosImplementation",
Expand Down
63 changes: 63 additions & 0 deletions Sources/Macros/Interface/ComplexMacorsInterfae.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public macro CodableKey(name: String) = #externalMacro(
/// func makeReactor() -> R
/// }
/// ```
/// 이 매크로는 첨부된 선언의 접근 제어자에 따라 전개되는 멤버의 접근 제어자가 바뀝니다. 예를 들어, 첨부 Class가 public 접근 제어자를 가진다면 전개되는 멤버도 public 접근 제어자를 가집니다.
///
/// - Warning: 이 매크로는 Class에만 적용할 수 있습니다.
///
Expand All @@ -141,3 +142,65 @@ public protocol BaseWrapper {



// MARK: - Wrapper View Complex


/// 타입이 BaseWrapper 프로토콜을 준수하게 합니다.
///
/// 이 매크로를 적용한 타입에 BaseWrapper 프로토콜을 준수하게 하고 make() 메서드 및 view, reactor 계산 프로퍼티를 추가합니다.
///
/// 첫 번째 Generic 타입은 Reactor 프로토콜을 준수하는 타입이어야 하고, 두 번째 Generic 타입은 ReactorKit.View 프로토콜을 준수하는 타입이어야 합니다.
///
/// 아래는 전개되기 전과 후의 코드를 보여줍니다.
/// ```swift
/// @Wrapper<RankingReactor, RankingView>
/// public class HomeViewControllerWrapper {
/// public func makeReactor() -> R {
/// return HomeReactor()
/// }
///
/// // Begin expansion of "@WrapperView"
/// public typealias R = RankingReactor
/// public typealias V = RankingView
///
/// public func makeView() -> V {
/// return RankingView(reactor: makeReactor())
/// }
///
/// public var view: V {
/// return makeView()
/// }
///
/// public var reactor: R {
/// return makeReactor()
/// }
/// // End expansion of "@WrapperView"
/// }
/// // Begin expansion of "@WrapperView"
/// extension HomeViewControllerWrapper: BaseWrapper { }
/// // End expansion of "@WrapperView"
/// ```
///
/// - 참고: BaseWrapper 프로토콜은 아래와 같이 선언되어 있습니다.
/// ```swift
/// public protocol BaseWrapper {
/// associatedtype R: Reactor
/// associatedtype V: ReactorKit.View
///
/// func makeReactor() -> R
/// }
/// ```
/// 이 매크로는 첨부된 선언의 접근 제어자에 따라 전개되는 멤버의 접근 제어자가 바뀝니다. 예를 들어, 첨부 Class가 public 접근 제어자를 가진다면 전개되는 멤버도 public 접근 제어자를 가집니다.
///
/// - Warning: 이 매크로는 Class에만 적용할 수 있습니다.
///
/// - Author: 김소월
///
@attached(member, names: arbitrary)
@attached(extension, conformances: BaseWrapper)
public macro WrapperView<R, V>() = #externalMacro(
module: "MacrosImplementation",
type: "WrapperViewMacro"
)


1 change: 1 addition & 0 deletions Sources/Macros/Interface/ExpressionMacrosInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Foundation
/// - Note: 매크로가 전개되기 전에 전개 단계에서 매개변수로 넘겨진 문자열 리터럴이 유효한지 확인하기에 런타임 경고가 발생할 여지를 차단합니다.
/// - Author: 김소월
///
@available(*, deprecated)
@freestanding(expression)
public macro URL(_ s: String) -> URL = #externalMacro(
module: "MacrosImplementation",
Expand Down
18 changes: 18 additions & 0 deletions Sources/Macros/Interface/ExtensionMacrosInterface.swift
Original file line number Diff line number Diff line change
@@ -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"
)
7 changes: 4 additions & 3 deletions Sources/Macros/Interface/MemberAttributeMacrosInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public macro Deprecated() = #externalMacro(
)


// MARK: - Dependency Values Member Attribute
// MARK: - Dependency Organizer MemberAttribute


/// @DependencyValue 매크로를 프로퍼티에 전개합니다.
Expand Down Expand Up @@ -50,8 +50,9 @@ public macro Deprecated() = #externalMacro(
///
/// - Warning: 이 매크로는 Extension에만 적용할 수 있습니다.
///
@available(*, deprecated)
@attached(memberAttribute)
public macro DependencyVales() = #externalMacro(
public macro DependencyOrganizer() = #externalMacro(
module: "MacrosImplementation",
type: "DependencyValuesMacro"
type: "DependencyOrganizerMacro"
)
Loading

0 comments on commit 1e2e662

Please sign in to comment.