Skip to content

Commit 2943f64

Browse files
committed
Generalize application of macro attributes to all nodes.
Make use of AttributedSyntax to handle all declarations with macro attributes.
1 parent 750a080 commit 2943f64

File tree

1 file changed

+41
-39
lines changed

1 file changed

+41
-39
lines changed

Sources/_SwiftSyntaxMacros/MacroSystem.swift

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct MacroSystem {
6363
class MacroApplication: SyntaxRewriter {
6464
let macroSystem: MacroSystem
6565
var context: MacroExpansionContext
66+
var skipNodes: Set<Syntax> = []
6667

6768
init(
6869
macroSystem: MacroSystem,
@@ -73,14 +74,49 @@ class MacroApplication: SyntaxRewriter {
7374
}
7475

7576
override func visitAny(_ node: Syntax) -> Syntax? {
76-
guard node.evaluatedMacroName != nil else {
77+
if skipNodes.contains(node) {
7778
return nil
7879
}
7980

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
84120
}
85121

86122
override func visit(_ node: CodeBlockItemListSyntax) -> CodeBlockItemListSyntax {
@@ -182,40 +218,6 @@ class MacroApplication: SyntaxRewriter {
182218

183219
return .init(newItems)
184220
}
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-
}
219221
}
220222

221223
extension MacroApplication {

0 commit comments

Comments
 (0)