Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
rlarjsdn3 committed Jun 5, 2024
2 parents d733ddd + 1e2e662 commit 76e5d52
Show file tree
Hide file tree
Showing 36 changed files with 1,894 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 86 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"pins" : [
{
"identity" : "combine-schedulers",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/combine-schedulers",
"state" : {
"revision" : "9dc9cbe4bc45c65164fa653a563d8d8db61b09bb",
"version" : "1.0.0"
}
},
{
"identity" : "reactorkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ReactorKit/ReactorKit.git",
"state" : {
"revision" : "8fa33f09c6f6621a2aa536d739956d53b84dd139",
"version" : "3.2.0"
}
},
{
"identity" : "rxswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ReactiveX/RxSwift.git",
"state" : {
"revision" : "b06a8c8596e4c3e8e7788e08e720e3248563ce6a",
"version" : "6.7.1"
}
},
{
"identity" : "swift-clocks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-clocks",
"state" : {
"revision" : "a8421d68068d8f45fbceb418fbf22c5dad4afd33",
"version" : "1.0.2"
}
},
{
"identity" : "swift-concurrency-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-concurrency-extras",
"state" : {
"revision" : "bb5059bde9022d69ac516803f4f227d8ac967f71",
"version" : "1.1.0"
}
},
{
"identity" : "swift-dependencies",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-dependencies",
"state" : {
"revision" : "350e1e119babe8525f9bd155b76640a5de270184",
"version" : "1.3.0"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
"version" : "509.1.1"
}
},
{
"identity" : "weakmaptable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ReactorKit/WeakMapTable.git",
"state" : {
"revision" : "cb05d64cef2bbf51e85c53adee937df46540a74e",
"version" : "1.2.1"
}
},
{
"identity" : "xctest-dynamic-overlay",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state" : {
"revision" : "6f30bdba373bbd7fbfe241dddd732651f2fbd1e2",
"version" : "1.1.2"
}
}
],
"version" : 2
}
72 changes: 72 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
import CompilerPluginSupport

let package = Package(
name: "Bibbi-Package",
platforms: [
.iOS(.v15),
.macOS(.v10_15)
],
products: [
.library(
name: "Macros",
targets: ["MacrosInterface"]
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
.package(url: "https://github.com/ReactorKit/ReactorKit.git", from: "3.2.0"),
.package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.3.0")
],
targets: [
.macro(
name: "MacrosImplementation",
dependencies: [
"SwiftSyntaxHelper",
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
],
path: "Sources/Macros/Implementation"
),

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

.target(
name: "MacrosInterface",
dependencies: [
"MacrosImplementation",
.product(name: "ReactorKit", package: "ReactorKit"),
.product(name: "Dependencies", package: "swift-dependencies")
],
path: "Sources/Macros/Interface"
),

.executableTarget(
name: "MacrosPlayground",
dependencies: [
"MacrosInterface"
],
path: "Sources/Macros/Playground"
),

.testTarget(
name: "Bibbi-MacroTests",
dependencies: [
"SwiftSyntaxHelper",
"MacrosImplementation",
.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"),
],
path: "Tests/Macros"
),
]
)
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# bibbi-macro
삐삐 iOS-Macro 패키지 🛠️
<img src="https://github.com/rlarjsdn3/swift-macro-playground/assets/21079970/03ea4a38-951a-450f-9f38-36520b994e18" align="center" width="150" height="150"> </br>

**Bibbi Package**는 삐삐(Bibbi)를 개발하는 데 유용한 `라이브러리``매크로`가 포함되어 있습니다. 이 리포지토리는 구현된 매크로의 기본 지식과 활용 방법을 설명하고 있습니다. </br>

## Featrues

### Macros

- [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

* iOS 15.0+ / macOS 10.15+
* Swift 5.0+

## ChangeLog

| 버전 | 내용 |
| :----: | :------------------: |
| v0.1.0 | `@Codable`, `@Wrapper` 매크로 구현 등 |
38 changes: 38 additions & 0 deletions Sources/Macros/Implementation/Accessor/DependencyValueMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// File.swift
//
//
// Created by 김건우 on 5/31/24.
//

import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct DependencyValueMacro: AccessorMacro {

public static func expansion(
of node: AttributeSyntax,
providingAccessorsOf declaration: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) throws -> [AccessorDeclSyntax] {
guard
case let .argumentList(arguments) = node.arguments,
let expression = arguments.first?
.expression
else {
throw MacroError.message("유효하지 않은 인자입니다.")
}

return [
"""
get { self[\(expression)] }
""",
"""
set { self[\(expression)] = newValue }
"""
]
}

}

35 changes: 35 additions & 0 deletions Sources/Macros/Implementation/Complex/CodableKeyMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// File.swift
//
//
// Created by 김건우 on 5/25/24.
//

import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct CodableKeyMacro: PeerMacro {

public static func expansion(
of node: AttributeSyntax,
providingPeersOf declaration: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
guard
let segments = node.arguments?
.as(LabeledExprListSyntax.self)?
.first?.expression
.as(StringLiteralExprSyntax.self)?
.segments,
segments.count == 1
else {
throw MacroError.message("유효하지 않은 문자열 리터럴입니다.")
}

return []
}

}


92 changes: 92 additions & 0 deletions Sources/Macros/Implementation/Complex/CodableMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// File.swift
//
//
// Created by 김건우 on 5/25/24.
//

import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct CodableMacro { }

extension CodableMacro: MemberMacro {

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

let memberList = structDecl.memberBlock.members

let cases = memberList.compactMap { member -> String? in
guard
let varDecl = member.decl.as(VariableDeclSyntax.self)
else {
return nil
}

guard
let propertyName = varDecl
.bindings.first?
.pattern
.as(IdentifierPatternSyntax.self)?
.identifier
else {
return nil
}

if let codableKey = varDecl
.attributes.first(where: { element in
element
.as(AttributeSyntax.self)?
.attributeName
.as(IdentifierTypeSyntax.self)?
.description == "CodableKey"
}),
let keyValue = codableKey
.as(AttributeSyntax.self)?
.arguments?
.as(LabeledExprListSyntax.self)?.first?
.expression
{
return "case \(propertyName) = \(keyValue)"
} else {
return "case \(propertyName)"
}
}

return [
"""
private enum CodingKeys: String, CodingKey {
\(raw: cases.joined(separator: "\n"))
}
"""
]
}

}

extension CodableMacro: 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 codableExtension = try ExtensionDeclSyntax("extension \(type.trimmed): Codable { }")

return [codableExtension]
}

}

Loading

0 comments on commit 76e5d52

Please sign in to comment.