Skip to content

Commit

Permalink
Patch
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii committed Oct 31, 2023
1 parent 9033d04 commit 70576da
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 1 deletion.
10 changes: 10 additions & 0 deletions Sources/StructTransaction/Source.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

/**
Available only for structs
*/
@attached(
extension,
conformances: DetectingType,
Expand All @@ -9,6 +12,13 @@
)
public macro Detecting() = #externalMacro(module: "StructTransactionMacros", type: "WriterMacro")

/**
Available only for member functions.
Marker Macro that indicates if the function will be exported into Accessing struct.
*/
@attached(peer)
public macro Exporting() = #externalMacro(module: "StructTransactionMacros", type: "MarkerMacro")

/**
Use ``Detecting()`` macro to adapt struct
*/
Expand Down
14 changes: 14 additions & 0 deletions Sources/StructTransactionMacros/MarkerMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import SwiftCompilerPlugin
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct MarkerMacro: Macro {

}

extension MarkerMacro: PeerMacro {
public static func expansion(of node: SwiftSyntax.AttributeSyntax, providingPeersOf declaration: some SwiftSyntax.DeclSyntaxProtocol, in context: some SwiftSyntaxMacros.MacroExpansionContext) throws -> [SwiftSyntax.DeclSyntax] {
[]
}
}
3 changes: 2 additions & 1 deletion Sources/StructTransactionMacros/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import SwiftSyntaxMacros
@main
struct Plugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
WriterMacro.self
WriterMacro.self,
MarkerMacro.self,
]
}
17 changes: 17 additions & 0 deletions Sources/StructTransactionMacros/WriterMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ extension WriterMacro: ExtensionMacro {
return ""
}

let functions = declaration
.memberBlock
.members
.compactMap {
$0.as(MemberBlockItemSyntax.self)?.decl.as(FunctionDeclSyntax.self)
}
.filter {
$0.attributes.contains { $0.trimmed.description == "@Exporting" }
}

let c = PropertyCollector(viewMode: .all)
c.onError = { node, error in
context.addDiagnostics(from: error, node: node)
Expand Down Expand Up @@ -124,7 +134,13 @@ extension WriterMacro: ExtensionMacro {
self.pointer = pointer
}
// MARK: - Properties
\(raw: decls.joined(separator: "\n\n"))
// MARK: - Functions
\(raw: functions.map(\.description).joined(separator: "\n\n"))
}
""" as DeclSyntax

Expand Down Expand Up @@ -162,6 +178,7 @@ extension WriterMacro: ExtensionMacro {
}
\(modifyingStructDecl)
""" as CodeBlockItemListSyntax)

return modifyingDecl
Expand Down
88 changes: 88 additions & 0 deletions Tests/StructTransactionMacroTests/WriterMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,94 @@ final class WriterMacroTests: XCTestCase {
}
}

func test_copying_functions() {

assertMacro {
"""
@Detecting
struct MyState {
func hello() {
}
@Exporting
func hello2() {
}
}
"""
} expansion: {
"""
struct MyState {
func hello() {
}
@Exporting
func hello2() {
}
}
extension MyState: DetectingType {
// MARK: - Accessing
typealias AccessingTarget = Self
@discardableResult
public static func modify(source: inout Self, modifier: (inout Accessing) throws -> Void) rethrows -> AccessingResult {
try withUnsafeMutablePointer(to: &source) { pointer in
var modifying = Accessing(pointer: pointer)
try modifier(&modifying)
return AccessingResult(
readIdentifiers: modifying.$_readIdentifiers,
modifiedIdentifiers: modifying.$_modifiedIdentifiers
)
}
}
@discardableResult
public static func read(source: consuming Self, reader: (inout Accessing) throws -> Void) rethrows -> AccessingResult {
// TODO: check copying costs
var tmp = source
return try withUnsafeMutablePointer(to: &tmp) { pointer in
var modifying = Accessing(pointer: pointer)
try reader(&modifying)
return AccessingResult(
readIdentifiers: modifying.$_readIdentifiers,
modifiedIdentifiers: modifying.$_modifiedIdentifiers
)
}
}
public struct Accessing /* want to be ~Copyable */ {
public private (set) var $_readIdentifiers: Set<String> = .init()
public private (set) var $_modifiedIdentifiers: Set<String> = .init()
private let pointer: UnsafeMutablePointer<AccessingTarget>
init(pointer: UnsafeMutablePointer<AccessingTarget>) {
self.pointer = pointer
}
// MARK: - Properties
// MARK: - Functions
@Exporting
func hello2() {
}
}
}
"""
}
}

func test_() {

assertMacro {
Expand Down
5 changes: 5 additions & 0 deletions Tests/StructTransactionTests/MyState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ struct MyState {
var name: String = ""
}

@Exporting
mutating func updateName() {
self.name = "Hiroshi"
}

}

0 comments on commit 70576da

Please sign in to comment.