Skip to content

Commit 6f060c0

Browse files
committed
Update
1 parent e90b5a6 commit 6f060c0

File tree

4 files changed

+177
-74
lines changed

4 files changed

+177
-74
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import SwiftCompilerPlugin
2+
import SwiftSyntax
3+
import SwiftSyntaxBuilder
4+
import SwiftSyntaxMacros
5+
6+
public struct TracingMacro {
7+
public enum Error: Swift.Error {
8+
case foundNotStructType
9+
}
10+
}
11+
12+
extension TracingMacro: MemberAttributeMacro {
13+
14+
public static func expansion(
15+
of node: SwiftSyntax.AttributeSyntax,
16+
attachedTo declaration: some SwiftSyntax.DeclGroupSyntax,
17+
providingAttributesFor member: some SwiftSyntax.DeclSyntaxProtocol,
18+
in context: some SwiftSyntaxMacros.MacroExpansionContext
19+
) throws -> [SwiftSyntax.AttributeSyntax] {
20+
21+
guard let structDecl = declaration.as(StructDeclSyntax.self) else {
22+
context.addDiagnostics(from: TracingMacro.Error.foundNotStructType, node: node)
23+
return []
24+
}
25+
26+
// let collector = PropertyCollector(viewMode: .all)
27+
// collector.onError = { syntax, error in
28+
//
29+
// }
30+
// collector.walk(structDecl.memberBlock)
31+
32+
print(member)
33+
34+
return [""]
35+
}
36+
37+
public static func expansion(
38+
of node: AttributeSyntax,
39+
attachedTo declaration: some DeclGroupSyntax,
40+
providingExtensionsOf type: some TypeSyntaxProtocol,
41+
conformingTo protocols: [TypeSyntax],
42+
in context: some MacroExpansionContext
43+
) throws -> [ExtensionDeclSyntax] {
44+
45+
return []
46+
}
47+
48+
}

Sources/StructTransactionMacros/WriterMacro.swift

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -224,77 +224,3 @@ final class MutatingGetterConverter: SyntaxRewriter {
224224
}
225225

226226
}
227-
228-
final class PropertyCollector: SyntaxVisitor {
229-
230-
enum Property {
231-
case storedConstant(PatternBindingListSyntax.Element)
232-
case storedVaraiable(PatternBindingListSyntax.Element)
233-
case computedGetOnly(PatternBindingListSyntax.Element, AccessorBlockSyntax)
234-
case computed(PatternBindingListSyntax.Element, AccessorBlockSyntax)
235-
}
236-
237-
var properties: [Property] = []
238-
239-
var onError: (any SyntaxProtocol, Error) -> Void = { _, _ in }
240-
241-
override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
242-
// walk only toplevel variables
243-
return .skipChildren
244-
}
245-
246-
override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
247-
return .skipChildren
248-
}
249-
250-
override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
251-
252-
guard node.bindings.count == 1 else {
253-
// let a,b,c = 0
254-
// it's stored
255-
onError(node, WriterMacroError.foundMultiBindingsStoredProperty)
256-
return .skipChildren
257-
}
258-
259-
guard let binding: PatternBindingListSyntax.Element = node.bindings.first else {
260-
fatalError()
261-
}
262-
263-
guard let _ = binding.typeAnnotation else {
264-
onError(node, MacroError(message: "Requires a type annotation, such as `identifier: Type`"))
265-
return .skipChildren
266-
}
267-
268-
let isConstant = node.bindingSpecifier == "let"
269-
270-
if isConstant {
271-
properties.append(.storedConstant(binding))
272-
return .skipChildren
273-
}
274-
275-
guard let accessorBlock = binding.accessorBlock else {
276-
properties.append(.storedVaraiable(binding))
277-
return .skipChildren
278-
}
279-
280-
// computed property
281-
282-
switch accessorBlock.accessors {
283-
case .accessors(let x):
284-
let hasSetter = x.contains {
285-
$0.accessorSpecifier == "set" || $0.accessorSpecifier == "_modify"
286-
}
287-
if hasSetter {
288-
properties.append(.computed(binding, accessorBlock))
289-
} else {
290-
properties.append(.computedGetOnly(binding, accessorBlock))
291-
}
292-
case .getter:
293-
properties.append(.computedGetOnly(binding, accessorBlock))
294-
return .skipChildren
295-
}
296-
297-
return .skipChildren
298-
}
299-
300-
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import SwiftSyntax
2+
3+
final class PropertyCollector: SyntaxVisitor {
4+
5+
enum Property {
6+
case storedConstant(PatternBindingListSyntax.Element)
7+
case storedVaraiable(PatternBindingListSyntax.Element)
8+
case computedGetOnly(PatternBindingListSyntax.Element, AccessorBlockSyntax)
9+
case computed(PatternBindingListSyntax.Element, AccessorBlockSyntax)
10+
}
11+
12+
var properties: [Property] = []
13+
14+
var onError: (any SyntaxProtocol, Error) -> Void = { _, _ in }
15+
16+
override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
17+
// walk only toplevel variables
18+
return .skipChildren
19+
}
20+
21+
override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
22+
return .skipChildren
23+
}
24+
25+
override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
26+
27+
guard node.bindings.count == 1 else {
28+
// let a,b,c = 0
29+
// it's stored
30+
onError(node, WriterMacroError.foundMultiBindingsStoredProperty)
31+
return .skipChildren
32+
}
33+
34+
guard let binding: PatternBindingListSyntax.Element = node.bindings.first else {
35+
fatalError()
36+
}
37+
38+
guard let _ = binding.typeAnnotation else {
39+
onError(node, MacroError(message: "Requires a type annotation, such as `identifier: Type`"))
40+
return .skipChildren
41+
}
42+
43+
let isConstant = node.bindingSpecifier == "let"
44+
45+
if isConstant {
46+
properties.append(.storedConstant(binding))
47+
return .skipChildren
48+
}
49+
50+
guard let accessorBlock = binding.accessorBlock else {
51+
properties.append(.storedVaraiable(binding))
52+
return .skipChildren
53+
}
54+
55+
// computed property
56+
57+
switch accessorBlock.accessors {
58+
case .accessors(let x):
59+
let hasSetter = x.contains {
60+
$0.accessorSpecifier == "set" || $0.accessorSpecifier == "_modify"
61+
}
62+
if hasSetter {
63+
properties.append(.computed(binding, accessorBlock))
64+
} else {
65+
properties.append(.computedGetOnly(binding, accessorBlock))
66+
}
67+
case .getter:
68+
properties.append(.computedGetOnly(binding, accessorBlock))
69+
return .skipChildren
70+
}
71+
72+
return .skipChildren
73+
}
74+
75+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import MacroTesting
2+
import StructTransactionMacros
3+
import SwiftSyntaxMacros
4+
import SwiftSyntaxMacrosTestSupport
5+
import XCTest
6+
7+
final class TracingMacroTests: XCTestCase {
8+
9+
override func invokeTest() {
10+
withMacroTesting(
11+
isRecording: false,
12+
macros: ["Tracing": TracingMacro.self]
13+
) {
14+
super.invokeTest()
15+
}
16+
}
17+
18+
func test_macro() {
19+
20+
assertMacro {
21+
"""
22+
@Tracing
23+
struct MyState {
24+
25+
var name: String
26+
27+
var age: Int { 0 }
28+
29+
@Clamp
30+
var height: Int
31+
32+
func compute() {
33+
}
34+
}
35+
"""
36+
} expansion: {
37+
"""
38+
struct MyState {
39+
40+
var name: String
41+
42+
var age: Int { 0 }
43+
44+
@Clamp
45+
var height: Int
46+
47+
func compute() {
48+
}
49+
}
50+
"""
51+
}
52+
53+
}
54+
}

0 commit comments

Comments
 (0)