@@ -312,19 +312,61 @@ private func expandAccessorMacroWithExistingAccessors(
312
312
return " \( raw: indentedSource) "
313
313
}
314
314
315
+ private func buildQualifiedType( _ inner: DeclSyntax ) -> TypeSyntax ? {
316
+ if let ext = inner. as ( ExtensionDeclSyntax . self) {
317
+ return ext. extendedType. trimmed
318
+ }
319
+
320
+ guard let identified = inner. asProtocol ( NamedDeclSyntax . self) else {
321
+ return nil
322
+ }
323
+
324
+ var typeNames : [ TokenSyntax ] = [ ]
325
+ var parentExtension : TypeSyntax ? = nil
326
+ var possibleParent = inner. parent
327
+ while let parent = possibleParent {
328
+ possibleParent = parent. parent
329
+ if let parent = parent. asProtocol ( NamedDeclSyntax . self) {
330
+ typeNames. append ( parent. name. trimmed)
331
+ } else if let parent = parent. as ( ExtensionDeclSyntax . self) {
332
+ // Extensions must be top level
333
+ if parentExtension != nil {
334
+ return nil
335
+ }
336
+ parentExtension = parent. extendedType. trimmed
337
+ }
338
+ }
339
+
340
+ // Attached type is within an extension
341
+ if let parentExtension {
342
+ // Extensions must be top level
343
+ if !typeNames. isEmpty {
344
+ return nil
345
+ }
346
+ return TypeSyntax ( MemberTypeSyntax ( baseType: parentExtension, name: identified. name. trimmed) )
347
+ }
348
+
349
+ // Attached type is top level
350
+ if typeNames. isEmpty {
351
+ return TypeSyntax ( IdentifierTypeSyntax ( name: identified. name. trimmed) )
352
+ }
353
+
354
+ // Attached type is nested in another type(s)
355
+ var baseType : TypeSyntax = TypeSyntax ( IdentifierTypeSyntax ( name: typeNames. popLast ( ) !) )
356
+ while let typeName = typeNames. popLast ( ) {
357
+ baseType = TypeSyntax ( MemberTypeSyntax ( baseType: baseType, name: typeName) )
358
+ }
359
+ return TypeSyntax ( MemberTypeSyntax ( baseType: baseType, name: identified. name. trimmed) )
360
+ }
361
+
315
362
private func expandExtensionMacro(
316
363
definition: ExtensionMacro . Type ,
317
364
attributeNode: AttributeSyntax ,
318
365
attachedTo: DeclSyntax ,
319
366
in context: some MacroExpansionContext ,
320
367
indentationWidth: Trivia
321
368
) throws -> CodeBlockItemListSyntax ? {
322
- let extendedType : TypeSyntax
323
- if let identified = attachedTo. asProtocol ( NamedDeclSyntax . self) {
324
- extendedType = " \( identified. name. trimmed) "
325
- } else if let ext = attachedTo. as ( ExtensionDeclSyntax . self) {
326
- extendedType = " \( ext. extendedType. trimmed) "
327
- } else {
369
+ guard let extendedType = buildQualifiedType ( attachedTo) else {
328
370
return nil
329
371
}
330
372
0 commit comments