From 5ff03e2ed230346a1879150e3021aef5f42bb6e7 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 4 Aug 2023 16:30:56 -0700 Subject: [PATCH] [SE-0407] Add missingConformancesTo argument to MemberMacro expansion operation Stage in an entrypoint for member macros that allows them to learn about which conformances that they've asked about are "missing", meaning that they are not present on the type (ignoring those that would be generated by an extension macro). This information is equivalent to the information provided to extension macros, although the member macro itself cannot create the conformance. --- .../MacroExpansion.swift | 1 + .../MacroProtocols/MemberMacro.swift | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift b/Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift index 25050c4b912..c7dc7d23375 100644 --- a/Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift +++ b/Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift @@ -236,6 +236,7 @@ public func expandAttachedMacroWithoutCollapsing let members = try attachedMacro.expansion( of: attributeNode, providingMembersOf: declGroup, + conformingTo: conformanceList?.map(\.type) ?? [], in: context ) diff --git a/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift b/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift index 78942e3123e..e5673bacc35 100644 --- a/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift +++ b/Sources/SwiftSyntaxMacros/MacroProtocols/MemberMacro.swift @@ -23,9 +23,54 @@ public protocol MemberMacro: AttachedMacro { /// /// - Returns: the set of member declarations introduced by this macro, which /// are nested inside the `attachedTo` declaration. + @available(*, deprecated, message: "Use expansion(of:providingMembersOf:conformingTo:in:") static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] + + /// Expand an attached declaration macro to produce a set of members. + /// + /// - Parameters: + /// - node: The custom attribute describing the attached macro. + /// - declaration: The declaration the macro attribute is attached to. + /// - conformingTo: The set of protocols that were declared + /// in the set of conformances for the macro and to which the declaration + /// does not explicitly conform. The member macro itself cannot declare + /// conformances to these protocols (only an extension macro can do that), + /// but can provide supporting declarations, such as a required + /// initializer or stored property, that cannot be written in an + /// extension. + /// - context: The context in which to perform the macro expansion. + /// + /// - Returns: the set of member declarations introduced by this macro, which + /// are nested inside the `attachedTo` declaration. + static func expansion( + of node: AttributeSyntax, + providingMembersOf declaration: some DeclGroupSyntax, + conformingTo protocols: [TypeSyntax], + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] +} + +public extension MemberMacro { + /// Default implementation supplies no conformances. + static func expansion( + of node: AttributeSyntax, + providingMembersOf declaration: some DeclGroupSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + return try expansion(of: node, providingMembersOf: declaration, conformingTo: [], in: context) + } + + /// Default implementation that ignores the unhandled conformances. + static func expansion( + of node: AttributeSyntax, + providingMembersOf declaration: some DeclGroupSyntax, + conformingTo protocols: [TypeSyntax], + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + return try expansion(of: node, providingMembersOf: declaration, in: context) + } }