@@ -5,9 +5,9 @@ import SwiftSyntaxMacros
5
5
6
6
extension FunctionDeclSyntax {
7
7
struct BodyComponents {
8
- let stateDeclarations : [ String ]
9
- let bindingDeclarations : [ String ]
10
- let temporaryDeclarations : [ String ]
8
+ let stateDeclarations : [ VariableDeclSyntax ]
9
+ let bindingDeclarations : [ VariableDeclSyntax ]
10
+ let temporaryDeclarations : [ VariableDeclSyntax ]
11
11
let viewBody : [ String ]
12
12
}
13
13
@@ -22,24 +22,27 @@ extension FunctionDeclSyntax {
22
22
fatalError ( " Function body is required " )
23
23
}
24
24
25
- var stateDeclarations : [ String ] = [ ]
26
- var bindingDeclarations : [ String ] = [ ]
27
- var temporaryDeclarations : [ String ] = [ ]
25
+ var stateDeclarations : [ VariableDeclSyntax ] = [ ]
26
+ var bindingDeclarations : [ VariableDeclSyntax ] = [ ]
27
+ var temporaryDeclarations : [ VariableDeclSyntax ] = [ ]
28
28
var viewBody : [ String ] = [ ]
29
29
30
30
for statement in body. statements {
31
- let statementText = statement. trimmed. description
32
-
33
- if statementText. contains ( " @State " ) {
34
- stateDeclarations. append ( statementText)
35
- } else if statementText. contains ( " @Binding " ) {
36
- bindingDeclarations. append ( statementText)
37
- } else if statementText. contains ( " var " ) || statementText. contains ( " let " )
38
- || statementText. contains ( " unowned let " ) || statementText. contains ( " weak var " )
39
- {
40
- temporaryDeclarations. append ( statementText)
31
+
32
+ if let variableDecl = statement. item. as ( VariableDeclSyntax . self) {
33
+
34
+ for attribute in variableDecl. attributes {
35
+ if attribute. as ( AttributeSyntax . self) ? . kind == AttributeSyntax . init ( stringLiteral: " @State " ) . kind {
36
+ stateDeclarations. append ( variableDecl)
37
+ } else if attribute. as ( AttributeSyntax . self) ? . attributeName. description == " Binding " {
38
+ bindingDeclarations. append ( variableDecl)
39
+ } else {
40
+ temporaryDeclarations. append ( variableDecl)
41
+ }
42
+ }
43
+
41
44
} else {
42
- viewBody. append ( statementText )
45
+ viewBody. append ( statement . trimmed . description )
43
46
}
44
47
}
45
48
@@ -51,7 +54,7 @@ extension FunctionDeclSyntax {
51
54
)
52
55
}
53
56
54
- var initializerComponents : [ InitializerComponent ] {
57
+ func initializerComponents( ) -> [ InitializerComponent ] {
55
58
let parameters = self . signature. parameterClause. parameters
56
59
return parameters. map { param in
57
60
let name = param. secondName? . text ?? param. firstName. text
@@ -81,11 +84,9 @@ public struct ViewComponentMacro: BodyMacro {
81
84
fatalError ( " ViewComponentMacro can only be applied to function declarations. " )
82
85
}
83
86
84
- // イニシャライザのコンポーネントを取得
85
- let initComponents = functionDecl. initializerComponents
87
+ let initComponents = functionDecl. initializerComponents ( )
86
88
87
- // ボディのコンポーネントを取得
88
- let components = functionDecl. extractBodyComponents ( )
89
+ let bodyComponents = functionDecl. extractBodyComponents ( )
89
90
90
91
let initBlock = """
91
92
init( \( initComponents. map { " \( $0. name) : \( $0. type) " } . joined ( separator: " , " ) ) ) {
@@ -95,22 +96,23 @@ public struct ViewComponentMacro: BodyMacro {
95
96
96
97
let bodyBlock = """
97
98
var body: some View {
98
- \( components . viewBody. joined ( separator: " \n " ) . indented ( 1 ) )
99
+ \( bodyComponents . viewBody. joined ( separator: " \n " ) . indented ( 1 ) )
99
100
}
100
101
"""
101
-
102
+
102
103
let component = """
103
104
struct Component: View {
104
105
105
- \( initComponents . map { " let \( $0. name ) : \( $0 . type . replacingOccurrences ( of : " @escaping " , with : " " ) . trimmingCharacters ( in : . whitespaces ) ) " } . joined ( separator: " \n " ) . indented ( 1 ) )
106
+ \( bodyComponents . temporaryDeclarations . map { $0. trimmed . description } . joined ( separator: " \n " ) )
106
107
107
- \( components . stateDeclarations . joined ( separator: " \n " ) . indented ( 1 ) )
108
+ \( initComponents . filter { c in bodyComponents . temporaryDeclarations . contains { $0 . bindings . contains { $0 . pattern == c . name } } } . map { " let \( $0 . name ) : \( $0 . type . replacingOccurrences ( of : " @escaping " , with : " " ) . trimmingCharacters ( in : . whitespaces ) ) " } . joined ( separator: " \n " ) . indented ( 1 ) )
108
109
109
- \( components. bindingDeclarations. joined ( separator: " \n " ) . indented ( 1 ) )
110
+ \( bodyComponents. stateDeclarations. map { $0. trimmed. description } . joined ( separator: " \n " ) . indented ( 1 ) )
111
+
112
+ \( bodyComponents. bindingDeclarations. map { $0. trimmed. description } . joined ( separator: " \n " ) . indented ( 1 ) )
110
113
111
114
\( initBlock. indented ( 1 ) )
112
115
113
- \( components. temporaryDeclarations. joined ( separator: " \n " ) )
114
116
115
117
\( bodyBlock. indented ( 1 ) )
116
118
@@ -152,3 +154,7 @@ struct FunctionalViewComponentPlugin: CompilerPlugin {
152
154
ViewComponentMacro . self
153
155
]
154
156
}
157
+
158
+ extension VariableDeclSyntax {
159
+
160
+ }
0 commit comments