Skip to content

Commit dc4b08c

Browse files
committed
[Macros] Ability to opt-out from auto-propagation of attrs/modifiers
`DeclarationMacro` now have two optional requirements that is defaulted to 'true': static var propagateFreestandingMacroAttributes: Bool { get } static var propagateFreestandingMacroModifiers: Bool { get } My implementing these and returning 'false', macro expansion systam won't copy attributes and/or modifiers to the expanded declarations. rdar://110364154
1 parent 6d65e39 commit dc4b08c

File tree

4 files changed

+62
-3
lines changed

4 files changed

+62
-3
lines changed

Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ public func expandFreestandingMacro(
4646
var rewritten = try declMacroDef.expansion(of: node, in: context)
4747
// Copy attributes and modifiers to the generated decls.
4848
if let expansionDecl = node.as(MacroExpansionDeclSyntax.self) {
49+
let attributes = declMacroDef.propagateFreestandingMacroAttributes ? expansionDecl.attributes : nil
50+
let modifiers = declMacroDef.propagateFreestandingMacroModifiers ? expansionDecl.modifiers : nil
4951
rewritten = rewritten.map {
50-
$0.applying(attributes: expansionDecl.attributes, modifiers: expansionDecl.modifiers)
52+
$0.applying(attributes: attributes, modifiers: modifiers)
5153
}
5254
}
5355
expandedSyntax = Syntax(

Sources/SwiftSyntaxMacros/MacroProtocols/DeclarationMacro.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,16 @@ public protocol DeclarationMacro: FreestandingMacro {
2020
of node: Node,
2121
in context: Context
2222
) throws -> [DeclSyntax]
23+
24+
/// Whether to copy attributes on the expansion syntax to expanded declarations,
25+
/// 'true' by default.
26+
static var propagateFreestandingMacroAttributes: Bool { get }
27+
/// Whether to copy modifiers on the expansion syntax to expanded declarations,
28+
/// 'true' by default.
29+
static var propagateFreestandingMacroModifiers: Bool { get }
30+
}
31+
32+
public extension DeclarationMacro {
33+
static var propagateFreestandingMacroAttributes: Bool { true }
34+
static var propagateFreestandingMacroModifiers: Bool { true }
2335
}

Sources/SwiftSyntaxMacros/MacroSystem.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
146146
in: context
147147
)
148148
if let declExpansion = expansion.as(MacroExpansionDeclSyntax.self) {
149+
let attributes = macro.propagateFreestandingMacroAttributes ? declExpansion.attributes : nil
150+
let modifiers = macro.propagateFreestandingMacroModifiers ? declExpansion.modifiers : nil
149151
expandedItemList = expandedItemList.map {
150-
$0.applying(attributes: declExpansion.attributes, modifiers: declExpansion.modifiers)
152+
$0.applying(attributes: attributes, modifiers: modifiers)
151153
}
152154
}
153155
newItems.append(
@@ -203,8 +205,10 @@ class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
203205
of: declExpansion,
204206
in: context
205207
)
208+
let attributes = freestandingMacro.propagateFreestandingMacroAttributes ? declExpansion.attributes : nil
209+
let modifiers = freestandingMacro.propagateFreestandingMacroModifiers ? declExpansion.modifiers : nil
206210
expandedList = expandedList.map {
207-
$0.applying(attributes: declExpansion.attributes, modifiers: declExpansion.modifiers)
211+
$0.applying(attributes: attributes, modifiers: modifiers)
208212
}
209213

210214
newItems.append(

Tests/SwiftSyntaxMacrosTest/MacroSystemTests.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,30 @@ public struct DeclsFromStringsMacro: DeclarationMacro {
672672
}
673673
}
674674

675+
public struct DeclsFromStringsMacroNoAttrs: DeclarationMacro {
676+
public static var propagateFreestandingMacroAttributes: Bool { false }
677+
public static var propagateFreestandingMacroModifiers: Bool { false }
678+
679+
public static func expansion(
680+
of node: some FreestandingMacroExpansionSyntax,
681+
in context: some MacroExpansionContext
682+
) throws -> [DeclSyntax] {
683+
var strings: [String] = []
684+
for arg in node.argumentList {
685+
guard
686+
let value = arg.expression.as(StringLiteralExprSyntax.self)?.representedLiteralValue
687+
else {
688+
continue
689+
}
690+
strings.append(value)
691+
}
692+
693+
return strings.map {
694+
"\(raw: $0)"
695+
}
696+
}
697+
}
698+
675699
// MARK: Tests
676700

677701
/// The set of test macros we use here.
@@ -1114,5 +1138,22 @@ final class MacroSystemTests: XCTestCase {
11141138
macros: ["decls": DeclsFromStringsMacro.self],
11151139
indentationWidth: indentationWidth
11161140
)
1141+
1142+
assertMacroExpansion(
1143+
#"""
1144+
@attribute
1145+
@otherAttribute(x: 1)
1146+
public #decls("@moreAttibute var global = 42",
1147+
"private func foo() {}")
1148+
"""#,
1149+
expandedSource: #"""
1150+
@moreAttibute var global = 42
1151+
private func foo() {
1152+
}
1153+
"""#,
1154+
macros: ["decls": DeclsFromStringsMacroNoAttrs.self],
1155+
indentationWidth: indentationWidth
1156+
)
1157+
11171158
}
11181159
}

0 commit comments

Comments
 (0)