@@ -21,12 +21,14 @@ import SwiftSyntaxBuilder
21
21
22
22
extension SyntaxProtocol {
23
23
/// 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.
24
26
public func expand(
25
27
macros: [ String : Macro . Type ] ,
26
28
in context: some MacroExpansionContext ,
27
29
indentationWidth: Trivia ? = nil
28
30
) -> Syntax {
29
- let specs = Dictionary ( uniqueKeysWithValues : macros. map { ( $0 . key , MacroSpec ( type: $0. value ) ) } )
31
+ let specs = macros. mapValues { MacroSpec ( type: $0) }
30
32
return self . expand ( macroSpecs: specs, in: context, indentationWidth: indentationWidth)
31
33
}
32
34
@@ -39,9 +41,7 @@ extension SyntaxProtocol {
39
41
// Build the macro system.
40
42
var system = MacroSystem ( )
41
43
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)
45
45
}
46
46
47
47
let applier = MacroApplication (
@@ -140,6 +140,7 @@ private func expandMemberMacro(
140
140
definition: MemberMacro . Type ,
141
141
attributeNode: AttributeSyntax ,
142
142
attachedTo: DeclSyntax ,
143
+ conformanceList: InheritedTypeListSyntax ,
143
144
in context: some MacroExpansionContext ,
144
145
indentationWidth: Trivia
145
146
) throws -> MemberBlockItemListSyntax ? {
@@ -151,7 +152,7 @@ private func expandMemberMacro(
151
152
declarationNode: attachedTo. detach ( in: context) ,
152
153
parentDeclNode: nil ,
153
154
extendedType: nil ,
154
- conformanceList: nil ,
155
+ conformanceList: conformanceList ,
155
156
in: context,
156
157
indentationWidth: indentationWidth
157
158
)
@@ -328,7 +329,7 @@ private func expandExtensionMacro(
328
329
definition: ExtensionMacro . Type ,
329
330
attributeNode: AttributeSyntax ,
330
331
attachedTo: DeclSyntax ,
331
- conformanceList: InheritedTypeListSyntax ? ,
332
+ conformanceList: InheritedTypeListSyntax ,
332
333
in context: some MacroExpansionContext ,
333
334
indentationWidth: Trivia
334
335
) throws -> CodeBlockItemListSyntax ? {
@@ -349,7 +350,7 @@ private func expandExtensionMacro(
349
350
declarationNode: attachedTo. detach ( in: context) ,
350
351
parentDeclNode: nil ,
351
352
extendedType: extendedType. detach ( in: context) ,
352
- conformanceList: conformanceList ?? [ ] ,
353
+ conformanceList: conformanceList,
353
354
in: context,
354
355
indentationWidth: indentationWidth
355
356
)
@@ -438,49 +439,30 @@ private func expandBodyMacro(
438
439
enum MacroSystemError : Error {
439
440
/// Indicates that a macro with the given name has already been defined.
440
441
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 )
443
442
}
444
443
445
444
/// A system of known macros that can be expanded syntactically
446
445
struct MacroSystem {
447
- var macros : [ String : Macro . Type ] = [ : ]
448
- var conformanceMap : [ String : InheritedTypeListSyntax ] = [ : ]
446
+ var macros : [ String : MacroSpec ] = [ : ]
449
447
450
448
/// Create an empty macro system.
451
449
init ( ) { }
452
450
453
- /// Add a macro to the system.
451
+ /// Add a macro specification to the system.
454
452
///
455
453
/// 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 )
459
457
}
460
458
461
- macros [ name] = macro
459
+ macros [ name] = macroSpec
462
460
}
463
461
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 ? {
477
464
return macros [ macroName]
478
465
}
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
- }
484
466
}
485
467
486
468
// MARK: - MacroApplication
@@ -898,41 +880,40 @@ private class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
898
880
// MARK: Attached macro expansions.
899
881
900
882
extension 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`.
903
884
///
904
885
/// The macros must be registered in `macroSystem`.
905
886
private func macroAttributes(
906
887
attachedTo decl: DeclSyntax
907
- ) -> [ ( attributeNode: AttributeSyntax , definition : Macro . Type , conformanceList : InheritedTypeListSyntax ? ) ] {
888
+ ) -> [ ( attributeNode: AttributeSyntax , spec : MacroSpec ) ] {
908
889
guard let attributedNode = decl. asProtocol ( WithAttributesSyntax . self) else {
909
890
return [ ]
910
891
}
911
892
912
893
return attributedNode. attributes. compactMap {
913
894
guard case let . attribute( attribute) = $0,
914
895
let attributeName = attribute. attributeName. as ( IdentifierTypeSyntax . self) ? . name. text,
915
- let macro = macroSystem. lookup ( attributeName)
896
+ let macroSpec = macroSystem. lookup ( attributeName)
916
897
else {
917
898
return nil
918
899
}
919
900
920
- return ( attribute, macro , macroSystem . conformaces ( forMacro : attributeName ) )
901
+ return ( attribute, macroSpec )
921
902
}
922
903
}
923
904
924
- /// Get macro attribute, the macro definition and optional conformance
905
+ /// Get macro attribute, the macro definition and conformance
925
906
/// protocols list attached to `decl` matching `ofType` macro type.
926
907
///
927
908
/// The macros must be registered in `macroSystem`.
928
909
private func macroAttributes< MacroType> (
929
910
attachedTo decl: DeclSyntax ,
930
911
ofType: MacroType . Type
931
- ) -> [ ( attributeNode: AttributeSyntax , definition: MacroType , conformanceList: InheritedTypeListSyntax ? ) ] {
912
+ ) -> [ ( attributeNode: AttributeSyntax , definition: MacroType , conformanceList: InheritedTypeListSyntax ) ] {
932
913
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 )
936
917
} else {
937
918
return nil
938
919
}
@@ -948,7 +929,7 @@ extension MacroApplication {
948
929
> (
949
930
attachedTo decl: DeclSyntax ,
950
931
ofType: MacroType . Type ,
951
- expandMacro: ( _ attributeNode: AttributeSyntax , _ definition: MacroType , _ conformanceList: InheritedTypeListSyntax ? ) throws -> ExpanedNodeCollection ?
932
+ expandMacro: ( _ attributeNode: AttributeSyntax , _ definition: MacroType , _ conformanceList: InheritedTypeListSyntax ) throws -> ExpanedNodeCollection ?
952
933
) -> [ ExpandedNode ] {
953
934
var result : [ ExpandedNode ] = [ ]
954
935
@@ -1026,6 +1007,7 @@ extension MacroApplication {
1026
1007
definition: definition,
1027
1008
attributeNode: attributeNode,
1028
1009
attachedTo: decl,
1010
+ conformanceList: conformanceList,
1029
1011
in: context,
1030
1012
indentationWidth: indentationWidth
1031
1013
)
@@ -1147,7 +1129,7 @@ extension MacroApplication {
1147
1129
expandMacro: ( _ macro: Macro . Type , _ node: any FreestandingMacroExpansionSyntax ) throws -> ExpandedMacroType ?
1148
1130
) -> MacroExpansionResult < ExpandedMacroType > {
1149
1131
guard let node,
1150
- let macro = macroSystem. lookup ( node. macroName. text)
1132
+ let macro = macroSystem. lookup ( node. macroName. text) ? . type
1151
1133
else {
1152
1134
return . notAMacro
1153
1135
}
0 commit comments