@@ -63,6 +63,7 @@ struct MacroSystem {
63
63
class MacroApplication : SyntaxRewriter {
64
64
let macroSystem : MacroSystem
65
65
var context : MacroExpansionContext
66
+ var skipNodes : Set < Syntax > = [ ]
66
67
67
68
init (
68
69
macroSystem: MacroSystem ,
@@ -73,14 +74,49 @@ class MacroApplication: SyntaxRewriter {
73
74
}
74
75
75
76
override func visitAny( _ node: Syntax ) -> Syntax ? {
76
- guard node . evaluatedMacroName != nil else {
77
+ if skipNodes . contains ( node ) {
77
78
return nil
78
79
}
79
80
80
- return node. evaluateMacro (
81
- with: macroSystem,
82
- context: & context
83
- )
81
+ if node. evaluatedMacroName != nil {
82
+ return node. evaluateMacro (
83
+ with: macroSystem,
84
+ context: & context
85
+ )
86
+ }
87
+
88
+ if let declSyntax = node. as ( DeclSyntax . self) ,
89
+ let attributedNode = node. asProtocol ( AttributedSyntax . self) ,
90
+ let attributes = attributedNode. attributes
91
+ {
92
+ // Visit the node.
93
+ skipNodes. insert ( node)
94
+ let visitedNode = self . visit ( declSyntax) . asProtocol ( AttributedSyntax . self) !
95
+ skipNodes. remove ( node)
96
+
97
+ // Remove any attached attributes.
98
+ let newAttributes = attributes. filter {
99
+ guard case let . customAttribute( customAttr) = $0 else {
100
+ return true
101
+ }
102
+
103
+ guard let attributeName = customAttr. attributeName. as ( SimpleTypeIdentifierSyntax . self) ? . name. text,
104
+ let macro = macroSystem. macros [ attributeName]
105
+ else {
106
+ return true
107
+ }
108
+
109
+ return !( macro is PeerDeclarationMacro . Type )
110
+ }
111
+
112
+ if newAttributes. isEmpty {
113
+ return Syntax ( visitedNode. withAttributes ( nil ) )
114
+ }
115
+
116
+ return Syntax ( visitedNode. withAttributes ( AttributeListSyntax ( newAttributes) ) )
117
+ }
118
+
119
+ return nil
84
120
}
85
121
86
122
override func visit( _ node: CodeBlockItemListSyntax ) -> CodeBlockItemListSyntax {
@@ -182,40 +218,6 @@ class MacroApplication: SyntaxRewriter {
182
218
183
219
return . init( newItems)
184
220
}
185
-
186
- override func visit( _ node: FunctionDeclSyntax ) -> DeclSyntax {
187
- let visitedNode = super. visit ( node)
188
-
189
- // FIXME: Generalize this to DeclSyntax, once we have attributes.
190
- // Visit the node first.
191
-
192
- guard let visitedFunc = visitedNode. as ( FunctionDeclSyntax . self) ,
193
- let attributes = visitedFunc. attributes
194
- else {
195
- return visitedNode
196
- }
197
-
198
- // Remove any attached attributes.
199
- let newAttributes = attributes. filter {
200
- guard case let . customAttribute( customAttr) = $0 else {
201
- return true
202
- }
203
-
204
- guard let attributeName = customAttr. attributeName. as ( SimpleTypeIdentifierSyntax . self) ? . name. text,
205
- let macro = macroSystem. macros [ attributeName]
206
- else {
207
- return true
208
- }
209
-
210
- return !( macro is PeerDeclarationMacro . Type )
211
- }
212
-
213
- if newAttributes. isEmpty {
214
- return DeclSyntax ( visitedFunc. withAttributes ( nil ) )
215
- }
216
-
217
- return DeclSyntax ( visitedFunc. withAttributes ( AttributeListSyntax ( newAttributes) ) )
218
- }
219
221
}
220
222
221
223
extension MacroApplication {
0 commit comments