Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii committed Feb 3, 2025
1 parent e90b5a6 commit 6f060c0
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 74 deletions.
48 changes: 48 additions & 0 deletions Sources/StructTransactionMacros/TracingMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import SwiftCompilerPlugin
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct TracingMacro {
public enum Error: Swift.Error {
case foundNotStructType
}
}

extension TracingMacro: MemberAttributeMacro {

public static func expansion(
of node: SwiftSyntax.AttributeSyntax,
attachedTo declaration: some SwiftSyntax.DeclGroupSyntax,
providingAttributesFor member: some SwiftSyntax.DeclSyntaxProtocol,
in context: some SwiftSyntaxMacros.MacroExpansionContext
) throws -> [SwiftSyntax.AttributeSyntax] {

guard let structDecl = declaration.as(StructDeclSyntax.self) else {
context.addDiagnostics(from: TracingMacro.Error.foundNotStructType, node: node)
return []
}

// let collector = PropertyCollector(viewMode: .all)
// collector.onError = { syntax, error in
//
// }
// collector.walk(structDecl.memberBlock)

print(member)

return [""]
}

public static func expansion(
of node: AttributeSyntax,
attachedTo declaration: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [ExtensionDeclSyntax] {

return []
}

}
74 changes: 0 additions & 74 deletions Sources/StructTransactionMacros/WriterMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,77 +224,3 @@ final class MutatingGetterConverter: SyntaxRewriter {
}

}

final class PropertyCollector: SyntaxVisitor {

enum Property {
case storedConstant(PatternBindingListSyntax.Element)
case storedVaraiable(PatternBindingListSyntax.Element)
case computedGetOnly(PatternBindingListSyntax.Element, AccessorBlockSyntax)
case computed(PatternBindingListSyntax.Element, AccessorBlockSyntax)
}

var properties: [Property] = []

var onError: (any SyntaxProtocol, Error) -> Void = { _, _ in }

override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
// walk only toplevel variables
return .skipChildren
}

override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
return .skipChildren
}

override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {

guard node.bindings.count == 1 else {
// let a,b,c = 0
// it's stored
onError(node, WriterMacroError.foundMultiBindingsStoredProperty)
return .skipChildren
}

guard let binding: PatternBindingListSyntax.Element = node.bindings.first else {
fatalError()
}

guard let _ = binding.typeAnnotation else {
onError(node, MacroError(message: "Requires a type annotation, such as `identifier: Type`"))
return .skipChildren
}

let isConstant = node.bindingSpecifier == "let"

if isConstant {
properties.append(.storedConstant(binding))
return .skipChildren
}

guard let accessorBlock = binding.accessorBlock else {
properties.append(.storedVaraiable(binding))
return .skipChildren
}

// computed property

switch accessorBlock.accessors {
case .accessors(let x):
let hasSetter = x.contains {
$0.accessorSpecifier == "set" || $0.accessorSpecifier == "_modify"
}
if hasSetter {
properties.append(.computed(binding, accessorBlock))
} else {
properties.append(.computedGetOnly(binding, accessorBlock))
}
case .getter:
properties.append(.computedGetOnly(binding, accessorBlock))
return .skipChildren
}

return .skipChildren
}

}
75 changes: 75 additions & 0 deletions Sources/StructTransactionMacros/lib.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import SwiftSyntax

final class PropertyCollector: SyntaxVisitor {

enum Property {
case storedConstant(PatternBindingListSyntax.Element)
case storedVaraiable(PatternBindingListSyntax.Element)
case computedGetOnly(PatternBindingListSyntax.Element, AccessorBlockSyntax)
case computed(PatternBindingListSyntax.Element, AccessorBlockSyntax)
}

var properties: [Property] = []

var onError: (any SyntaxProtocol, Error) -> Void = { _, _ in }

override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
// walk only toplevel variables
return .skipChildren
}

override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
return .skipChildren
}

override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {

guard node.bindings.count == 1 else {
// let a,b,c = 0
// it's stored
onError(node, WriterMacroError.foundMultiBindingsStoredProperty)
return .skipChildren
}

guard let binding: PatternBindingListSyntax.Element = node.bindings.first else {
fatalError()
}

guard let _ = binding.typeAnnotation else {
onError(node, MacroError(message: "Requires a type annotation, such as `identifier: Type`"))
return .skipChildren
}

let isConstant = node.bindingSpecifier == "let"

if isConstant {
properties.append(.storedConstant(binding))
return .skipChildren
}

guard let accessorBlock = binding.accessorBlock else {
properties.append(.storedVaraiable(binding))
return .skipChildren
}

// computed property

switch accessorBlock.accessors {
case .accessors(let x):
let hasSetter = x.contains {
$0.accessorSpecifier == "set" || $0.accessorSpecifier == "_modify"
}
if hasSetter {
properties.append(.computed(binding, accessorBlock))
} else {
properties.append(.computedGetOnly(binding, accessorBlock))
}
case .getter:
properties.append(.computedGetOnly(binding, accessorBlock))
return .skipChildren
}

return .skipChildren
}

}
54 changes: 54 additions & 0 deletions Tests/StructTransactionMacroTests/TracingMacroTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import MacroTesting
import StructTransactionMacros
import SwiftSyntaxMacros
import SwiftSyntaxMacrosTestSupport
import XCTest

final class TracingMacroTests: XCTestCase {

override func invokeTest() {
withMacroTesting(
isRecording: false,
macros: ["Tracing": TracingMacro.self]
) {
super.invokeTest()
}
}

func test_macro() {

assertMacro {
"""
@Tracing
struct MyState {
var name: String
var age: Int { 0 }
@Clamp
var height: Int
func compute() {
}
}
"""
} expansion: {
"""
struct MyState {
var name: String
var age: Int { 0 }
@Clamp
var height: Int
func compute() {
}
}
"""
}

}
}

0 comments on commit 6f060c0

Please sign in to comment.