Skip to content

Commit fd8ee2b

Browse files
committed
[Macros] Factor more shared code into getMacroAttributes using AttributedSyntax.
1 parent 39e8e62 commit fd8ee2b

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

Sources/_SwiftSyntaxMacros/MacroSystem.swift

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -258,35 +258,36 @@ class MacroApplication: SyntaxRewriter {
258258
}
259259

260260
extension MacroApplication {
261-
private func getAttributes(attachedTo decl: DeclSyntax) -> AttributeListSyntax? {
262-
// Dig out the attribute list.
263-
// FIXME: We should have a better way to get the attributes from any
264-
// declaration.
265-
return (decl.children(viewMode: .sourceAccurate).compactMap {
266-
$0.as(AttributeListSyntax.self)
267-
}).first
261+
private func getMacroAttributes<MacroType>(
262+
attachedTo decl: DeclSyntax, ofType: MacroType.Type
263+
) -> [(CustomAttributeSyntax, MacroType)] {
264+
guard let attributedNode = decl.asProtocol(AttributedSyntax.self),
265+
let attributes = attributedNode.attributes else {
266+
return []
267+
}
268+
269+
return attributes.compactMap {
270+
guard case let .customAttribute(customAttr) = $0,
271+
let attributeName = customAttr.attributeName.as(SimpleTypeIdentifierSyntax.self)?.name.text,
272+
let macro = macroSystem.macros[attributeName],
273+
let macroType = macro as? MacroType
274+
else {
275+
return nil
276+
}
277+
278+
return (customAttr, macroType)
279+
}
268280
}
269281

270282
// If any of the custom attributes associated with the given declaration
271283
// refer to "peer" declaration macros, expand them and return the resulting
272284
// set of peer declarations.
273285
private func expandPeers(of decl: DeclSyntax) -> [DeclSyntax] {
274-
guard let attributes = getAttributes(attachedTo: decl) else {
275-
return []
276-
}
277-
278286
var peers: [DeclSyntax] = []
279-
for attribute in attributes {
280-
guard case let .customAttribute(customAttribute) = attribute,
281-
let attributeName = customAttribute.attributeName.as(SimpleTypeIdentifierSyntax.self)?.name.text,
282-
let macro = macroSystem.macros[attributeName],
283-
let peerMacro = macro as? PeerDeclarationMacro.Type
284-
else {
285-
continue
286-
}
287-
287+
let macroAttributes = getMacroAttributes(attachedTo: decl, ofType: PeerDeclarationMacro.Type.self)
288+
for (attribute, peerMacro) in macroAttributes {
288289
do {
289-
let newPeers = try peerMacro.expansion(of: customAttribute, attachedTo: decl, in: &context)
290+
let newPeers = try peerMacro.expansion(of: attribute, attachedTo: decl, in: &context)
290291
peers.append(contentsOf: newPeers)
291292
} catch {
292293
// Record the error
@@ -304,22 +305,14 @@ extension MacroApplication {
304305

305306
/// Expands any attached custom attributes that refer to member declaration macros,
306307
/// and returns result of adding those members to the given declaration.
307-
private func expandMembers<Decl: DeclGroupSyntax & DeclSyntaxProtocol>(of decl: Decl) -> Decl {
308-
guard let attributes = getAttributes(attachedTo: DeclSyntax(decl)) else {
309-
return decl
310-
}
311-
308+
private func expandMembers<Decl: DeclGroupSyntax & DeclSyntaxProtocol>(
309+
of decl: Decl
310+
) -> Decl {
312311
var newMembers: [DeclSyntax] = []
313-
for attribute in attributes {
314-
guard case let .customAttribute(customAttribute) = attribute,
315-
let attributeName = customAttribute.attributeName.as(SimpleTypeIdentifierSyntax.self)?.name.text,
316-
let macro = macroSystem.macros[attributeName],
317-
let memberMacro = macro as? MemberDeclarationMacro.Type else {
318-
continue
319-
}
320-
312+
let macroAttributes = getMacroAttributes(attachedTo: DeclSyntax(decl), ofType: MemberDeclarationMacro.Type.self)
313+
for (attribute, memberMacro) in macroAttributes {
321314
do {
322-
try newMembers.append(contentsOf: memberMacro.expansion(of: customAttribute,
315+
try newMembers.append(contentsOf: memberMacro.expansion(of: attribute,
323316
attachedTo: DeclSyntax(decl),
324317
in: &context))
325318
} catch {

0 commit comments

Comments
 (0)