@@ -173,14 +173,23 @@ class MacroApplication<Context: MacroExpansionContext>: SyntaxRewriter {
173
173
let newItem = visit ( item. item)
174
174
newItems. append ( item. with ( \. item, newItem) )
175
175
176
- // Expand any peer declarations triggered by macros used as attributes.
176
+ // Expand any peer declarations or conformances triggered by macros used
177
+ // as attributes.
177
178
if case let . decl( decl) = item. item {
178
179
let peers = expandPeers ( of: decl)
179
180
newItems. append (
180
181
contentsOf: peers. map {
181
182
newDecl in CodeBlockItemSyntax ( item: . decl( newDecl) )
182
183
}
183
184
)
185
+
186
+ if let declGroup = decl. asProtocol ( DeclGroupSyntax . self) {
187
+ newItems. append (
188
+ contentsOf: expandConformances ( of: declGroup) . map {
189
+ newDecl in CodeBlockItemSyntax ( item: . decl( newDecl) )
190
+ }
191
+ )
192
+ }
184
193
}
185
194
}
186
195
@@ -389,6 +398,43 @@ extension MacroApplication {
389
398
return peers
390
399
}
391
400
401
+ // If any of the custom attributes associated with the given declaration
402
+ // refer to conformance macros, expand them and return the resulting
403
+ // set of extension declarations.
404
+ private func expandConformances( of decl: DeclGroupSyntax ) -> [ DeclSyntax ] {
405
+ let extendedType : Syntax
406
+ if let identified = decl. asProtocol ( IdentifiedDeclSyntax . self) {
407
+ extendedType = Syntax ( identified. identifier. trimmed)
408
+ } else if let ext = decl. as ( ExtensionDeclSyntax . self) {
409
+ extendedType = Syntax ( ext. extendedType. trimmed)
410
+ } else {
411
+ return [ ]
412
+ }
413
+
414
+ var extensions : [ DeclSyntax ] = [ ]
415
+ let macroAttributes = getMacroAttributes ( attachedTo: decl. as ( DeclSyntax . self) !, ofType: ConformanceMacro . Type. self)
416
+ for (attribute, conformanceMacro) in macroAttributes {
417
+ do {
418
+ let newConformances = try conformanceMacro. expansion ( of: attribute, providingConformancesOf: decl, in: context)
419
+
420
+ for (type, whereClause) in newConformances {
421
+ var ext : DeclSyntax = """
422
+ extension \( extendedType) : \( type) { }
423
+ """
424
+ if let whereClause {
425
+ ext = DeclSyntax ( ( ext. cast ( ExtensionDeclSyntax . self) ) . with ( \. genericWhereClause, whereClause) )
426
+ }
427
+
428
+ extensions. append ( DeclSyntax ( ext) )
429
+ }
430
+ } catch {
431
+ context. addDiagnostics ( from: error, node: attribute)
432
+ }
433
+ }
434
+
435
+ return extensions
436
+ }
437
+
392
438
/// Expands any attached custom attributes that refer to member declaration macros,
393
439
/// and returns result of adding those members to the given declaration.
394
440
private func expandMembers< Decl: DeclGroupSyntax & DeclSyntaxProtocol > (
0 commit comments