@@ -21,12 +21,14 @@ import SwiftSyntaxBuilder
2121
2222extension SyntaxProtocol {
2323 /// Expand all uses of the given set of macros within this syntax node.
24+ /// - SeeAlso: ``expand(macroSpecs:in:indentationWidth:)`` to also specify
25+ /// the list of conformances passed to the macro expansion.
2426 public func expand(
2527 macros: [ String : Macro . Type ] ,
2628 in context: some MacroExpansionContext ,
2729 indentationWidth: Trivia ? = nil
2830 ) -> Syntax {
29- let specs = Dictionary ( uniqueKeysWithValues : macros. map { ( $0 . key , MacroSpec ( type: $0. value ) ) } )
31+ let specs = macros. mapValues { MacroSpec ( type: $0) }
3032 return self . expand ( macroSpecs: specs, in: context, indentationWidth: indentationWidth)
3133 }
3234
@@ -39,9 +41,7 @@ extension SyntaxProtocol {
3941 // Build the macro system.
4042 var system = MacroSystem ( )
4143 for (macroName, macroSpec) in macroSpecs {
42- try ! system. add ( macroSpec. type, name: macroName)
43- let conformedTypes = InheritedTypeListSyntax ( macroSpec. conformances. map { InheritedTypeSyntax ( type: $0) } )
44- try ! system. add ( conformedTypes, name: macroName)
44+ try ! system. add ( macroSpec, name: macroName)
4545 }
4646
4747 let applier = MacroApplication (
@@ -140,6 +140,7 @@ private func expandMemberMacro(
140140 definition: MemberMacro . Type ,
141141 attributeNode: AttributeSyntax ,
142142 attachedTo: DeclSyntax ,
143+ conformanceList: InheritedTypeListSyntax ,
143144 in context: some MacroExpansionContext ,
144145 indentationWidth: Trivia
145146) throws -> MemberBlockItemListSyntax ? {
@@ -151,7 +152,7 @@ private func expandMemberMacro(
151152 declarationNode: attachedTo. detach ( in: context) ,
152153 parentDeclNode: nil ,
153154 extendedType: nil ,
154- conformanceList: nil ,
155+ conformanceList: conformanceList ,
155156 in: context,
156157 indentationWidth: indentationWidth
157158 )
@@ -328,7 +329,7 @@ private func expandExtensionMacro(
328329 definition: ExtensionMacro . Type ,
329330 attributeNode: AttributeSyntax ,
330331 attachedTo: DeclSyntax ,
331- conformanceList: InheritedTypeListSyntax ? ,
332+ conformanceList: InheritedTypeListSyntax ,
332333 in context: some MacroExpansionContext ,
333334 indentationWidth: Trivia
334335) throws -> CodeBlockItemListSyntax ? {
@@ -349,7 +350,7 @@ private func expandExtensionMacro(
349350 declarationNode: attachedTo. detach ( in: context) ,
350351 parentDeclNode: nil ,
351352 extendedType: extendedType. detach ( in: context) ,
352- conformanceList: conformanceList ?? [ ] ,
353+ conformanceList: conformanceList,
353354 in: context,
354355 indentationWidth: indentationWidth
355356 )
@@ -438,49 +439,30 @@ private func expandBodyMacro(
438439enum MacroSystemError : Error {
439440 /// Indicates that a macro with the given name has already been defined.
440441 case alreadyDefined( new: Macro . Type , existing: Macro . Type )
441- /// Indicates that protocol conformances for a macro with the given name has already been defined.
442- case alreadyConforming( new: InheritedTypeListSyntax , existing: InheritedTypeListSyntax )
443442}
444443
445444/// A system of known macros that can be expanded syntactically
446445struct MacroSystem {
447- var macros : [ String : Macro . Type ] = [ : ]
448- var conformanceMap : [ String : InheritedTypeListSyntax ] = [ : ]
446+ var macros : [ String : MacroSpec ] = [ : ]
449447
450448 /// Create an empty macro system.
451449 init ( ) { }
452450
453- /// Add a macro to the system.
451+ /// Add a macro specification to the system.
454452 ///
455453 /// Throws an error if there is already a macro with this name.
456- mutating func add( _ macro : Macro . Type , name: String ) throws {
457- if let knownMacro = macros [ name] {
458- throw MacroSystemError . alreadyDefined ( new: macro , existing: knownMacro )
454+ mutating func add( _ macroSpec : MacroSpec , name: String ) throws {
455+ if let knownMacroSpec = macros [ name] {
456+ throw MacroSystemError . alreadyDefined ( new: macroSpec . type , existing: knownMacroSpec . type )
459457 }
460458
461- macros [ name] = macro
459+ macros [ name] = macroSpec
462460 }
463461
464- /// Add protocol conformances for a macro to the system.
465- ///
466- /// Throws an error if there is already conformances for a macro with this name.
467- mutating func add( _ conformanceList: InheritedTypeListSyntax , name: String ) throws {
468- if let knownConformanceList = conformanceMap [ name] {
469- throw MacroSystemError . alreadyConforming ( new: conformanceList, existing: knownConformanceList)
470- }
471-
472- conformanceMap [ name] = conformanceList
473- }
474-
475- /// Look for a macro with the given name.
476- func lookup( _ macroName: String ) -> Macro . Type ? {
462+ /// Look for a macro specification with the given name.
463+ func lookup( _ macroName: String ) -> MacroSpec ? {
477464 return macros [ macroName]
478465 }
479-
480- /// Look for protocol conformances of a macro with the given name.
481- func conformaces( forMacro macroName: String ) -> InheritedTypeListSyntax ? {
482- return conformanceMap [ macroName]
483- }
484466}
485467
486468// MARK: - MacroApplication
@@ -898,41 +880,40 @@ private class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
898880// MARK: Attached macro expansions.
899881
900882extension MacroApplication {
901- /// Get macro attribute, the macro definition and optional
902- /// conformance protocols list attached to `decl`.
883+ /// Get macro attribute, the macro specification attached to `decl`.
903884 ///
904885 /// The macros must be registered in `macroSystem`.
905886 private func macroAttributes(
906887 attachedTo decl: DeclSyntax
907- ) -> [ ( attributeNode: AttributeSyntax , definition : Macro . Type , conformanceList : InheritedTypeListSyntax ? ) ] {
888+ ) -> [ ( attributeNode: AttributeSyntax , spec : MacroSpec ) ] {
908889 guard let attributedNode = decl. asProtocol ( WithAttributesSyntax . self) else {
909890 return [ ]
910891 }
911892
912893 return attributedNode. attributes. compactMap {
913894 guard case let . attribute( attribute) = $0,
914895 let attributeName = attribute. attributeName. as ( IdentifierTypeSyntax . self) ? . name. text,
915- let macro = macroSystem. lookup ( attributeName)
896+ let macroSpec = macroSystem. lookup ( attributeName)
916897 else {
917898 return nil
918899 }
919900
920- return ( attribute, macro , macroSystem . conformaces ( forMacro : attributeName ) )
901+ return ( attribute, macroSpec )
921902 }
922903 }
923904
924- /// Get macro attribute, the macro definition and optional conformance
905+ /// Get macro attribute, the macro definition and conformance
925906 /// protocols list attached to `decl` matching `ofType` macro type.
926907 ///
927908 /// The macros must be registered in `macroSystem`.
928909 private func macroAttributes< MacroType> (
929910 attachedTo decl: DeclSyntax ,
930911 ofType: MacroType . Type
931- ) -> [ ( attributeNode: AttributeSyntax , definition: MacroType , conformanceList: InheritedTypeListSyntax ? ) ] {
912+ ) -> [ ( attributeNode: AttributeSyntax , definition: MacroType , conformanceList: InheritedTypeListSyntax ) ] {
932913 return macroAttributes ( attachedTo: decl)
933- . compactMap { ( attributeNode: AttributeSyntax , definition : Macro . Type , conformanceList : InheritedTypeListSyntax ? ) in
934- if let macroType = definition as? MacroType {
935- return ( attributeNode, macroType, conformanceList )
914+ . compactMap { ( attributeNode: AttributeSyntax , spec : MacroSpec ) in
915+ if let macroType = spec . type as? MacroType {
916+ return ( attributeNode, macroType, spec . inheritedTypeList )
936917 } else {
937918 return nil
938919 }
@@ -948,7 +929,7 @@ extension MacroApplication {
948929 > (
949930 attachedTo decl: DeclSyntax ,
950931 ofType: MacroType . Type ,
951- expandMacro: ( _ attributeNode: AttributeSyntax , _ definition: MacroType , _ conformanceList: InheritedTypeListSyntax ? ) throws -> ExpanedNodeCollection ?
932+ expandMacro: ( _ attributeNode: AttributeSyntax , _ definition: MacroType , _ conformanceList: InheritedTypeListSyntax ) throws -> ExpanedNodeCollection ?
952933 ) -> [ ExpandedNode ] {
953934 var result : [ ExpandedNode ] = [ ]
954935
@@ -1026,6 +1007,7 @@ extension MacroApplication {
10261007 definition: definition,
10271008 attributeNode: attributeNode,
10281009 attachedTo: decl,
1010+ conformanceList: conformanceList,
10291011 in: context,
10301012 indentationWidth: indentationWidth
10311013 )
@@ -1147,7 +1129,7 @@ extension MacroApplication {
11471129 expandMacro: ( _ macro: Macro . Type , _ node: any FreestandingMacroExpansionSyntax ) throws -> ExpandedMacroType ?
11481130 ) -> MacroExpansionResult < ExpandedMacroType > {
11491131 guard let node,
1150- let macro = macroSystem. lookup ( node. macroName. text)
1132+ let macro = macroSystem. lookup ( node. macroName. text) ? . type
11511133 else {
11521134 return . notAMacro
11531135 }
0 commit comments