Summary: As part of supporting function body macros on closure expressions, I've added a new requirement to the BodyMacro
protocol to accept a value of ClosureExprSyntax
, and I generalized the public expandAttachedMacro
APIs to accept some SyntaxProtocol
instead of DeclSyntax
to allow passing a value of ClosureExprSyntax
as the node that the macro is attached to.
Swift Interface
My PR adds the following public API in SwiftSyntaxMacroExpansion:
/// Expand `@attached(XXX)` macros.
///
/// - Parameters:
/// - definition: a type that conforms to one or more attached `Macro` protocols.
/// - macroRole: indicates which `Macro` protocol expansion should be performed
/// - attributeNode: attribute syntax node (e.g. `@macroName(argument)`).
/// - node: target syntax node to apply the expansion. This is either a declaration
/// or a closure syntax node.
/// - parentDeclNode: Only used for `MacroRole.memberAttribute`. The parent
/// context node of `declarationNode`.
/// - context: context of the expansion.
/// - indentationWidth: The indentation that should be added for each additional
/// nesting level
/// - Returns: A list of expanded source text. Upon failure (i.e.
/// `definition.expansion()` throws) returns `nil`, and the diagnostics
/// representing the `Error` are guaranteed to be added to context.
public func expandAttachedMacroWithoutCollapsing<Context: MacroExpansionContext>(
definition: Macro.Type,
macroRole: MacroRole,
attributeNode: AttributeSyntax,
node: some SyntaxProtocol,
parentDeclNode: DeclSyntax?,
extendedType: TypeSyntax?,
conformanceList: InheritedTypeListSyntax?,
in context: Context,
indentationWidth: Trivia? = nil
) -> [String]?
/// Expand `@attached(XXX)` macros.
///
/// - Parameters:
/// - definition: a type that conforms to one or more attached `Macro` protocols.
/// - macroRole: indicates which `Macro` protocol expansion should be performed
/// - attributeNode: attribute syntax node (e.g. `@macroName(argument)`).
/// - node: target declaration syntax node to apply the expansion. This is either
/// a declaration or a closure syntax node.
/// - parentDeclNode: Only used for `MacroRole.memberAttribute`. The parent
/// context node of `declarationNode`.
/// - context: context of the expansion.
/// - indentationWidth: The indentation that should be added for each additional
/// nesting level
/// - Returns: expanded source text. Upon failure (i.e. `defintion.expansion()`
/// throws) returns `nil`, and the diagnostics representing the `Error` are
/// guaranteed to be added to context.
public func expandAttachedMacro<Context: MacroExpansionContext>(
definition: Macro.Type,
macroRole: MacroRole,
attributeNode: AttributeSyntax,
node: some SyntaxProtocol,
parentDeclNode: DeclSyntax?,
extendedType: TypeSyntax?,
conformanceList: InheritedTypeListSyntax?,
in context: Context,
indentationWidth: Trivia? = nil
) -> String? {
I also deprecated the overloads that accept declarationNode: DeclSyntax
, with a message to rename the declarationNode:
argument label to node:
. Because the new overloads accept some SyntaxProtocol
, direct only require changing the argument label; an argument type of DeclSyntax
is still valid.
I also added the following requirement to the BodyMacro
protocol in SwiftSyntaxMacros:
/// Expand a macro described by the given custom attribute and
/// attached to the given closure and evaluated within a
/// particular expansion context.
///
/// The macro expansion can replace the body of the given closure.
static func expansion(
of node: AttributeSyntax,
providingBodyFor closure: ClosureExprSyntax,
in context: some MacroExpansionContext
) throws -> [CodeBlockItemSyntax]
For existing API: This change will cause warnings in existing callers of the expandAttachedMacro
APIs and existing conformances to BodyMacro
.
- Migration: To facilitate migration, the old overloads of the
expandAttachedMacro
APIs are deprecated, and the default implementation of the newBodyMacro
protocol requirement is deprecated. This will cause warnings in existing clients of these APIs. Existing callers ofexpandAttachedMacro{WithoutCollapsing}
will get a warning to change thedeclarationNode
argument label tonode
. Existing conformances ofBodyMacro
will get a warning to implement the new protocol requirement.