Skip to content

Commit dce8d14

Browse files
bfaheyclaude
authored andcommitted
Consolidate member block transformation into shared helper
- Extract mockMemberBlockItems helper that works on MemberBlockItemListSyntax - mockMemberBlock delegates to shared helper - mockIfConfigDeclaration uses shared helper directly - Remove mockIfConfigClause entirely (-46 lines) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 637bc5f commit dce8d14

File tree

1 file changed

+70
-116
lines changed

1 file changed

+70
-116
lines changed

Sources/MockingMacros/Macros/MockedMacro/MockedMacro.swift

Lines changed: 70 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -314,53 +314,64 @@ extension MockedMacro {
314314
from protocolDeclaration: ProtocolDeclSyntax
315315
) throws -> MemberBlockSyntax {
316316
let accessLevel = protocolDeclaration.minimumConformingAccessLevel
317-
let memberBlock = protocolDeclaration.memberBlock
318-
let initializerDeclarations = memberBlock.memberDeclarations(
319-
ofType: InitializerDeclSyntax.self
320-
)
321-
let propertyDeclarations = memberBlock.memberDeclarations(
322-
ofType: VariableDeclSyntax.self
323-
)
324-
let methodDeclarations = memberBlock.memberDeclarations(
325-
ofType: FunctionDeclSyntax.self
326-
)
327-
let ifConfigDeclarations = memberBlock.memberDeclarations(
328-
ofType: IfConfigDeclSyntax.self
317+
let transformedMembers = try self.mockMemberBlockItems(
318+
from: protocolDeclaration.memberBlock.members,
319+
with: accessLevel,
320+
in: protocolDeclaration
329321
)
322+
return MemberBlockSyntax(members: transformedMembers)
323+
}
330324

331-
return try MemberBlockSyntax {
332-
for initializerDeclaration in initializerDeclarations {
333-
try self.mockInitializerConformanceDeclaration(
334-
with: accessLevel,
335-
from: initializerDeclaration
336-
)
337-
}
338-
339-
for propertyDeclaration in propertyDeclarations {
340-
for binding in propertyDeclaration.bindings {
341-
try self.mockPropertyConformanceDeclaration(
342-
with: accessLevel,
343-
for: binding,
344-
from: propertyDeclaration
325+
/// Transforms member block items into mocked declarations.
326+
///
327+
/// Associated types are skipped since they become generic parameters on the
328+
/// mock class rather than member declarations.
329+
///
330+
/// - Parameters:
331+
/// - members: The member block items to transform.
332+
/// - accessLevel: The access level to apply to the mocked declarations.
333+
/// - protocolDeclaration: The protocol being mocked.
334+
/// - Returns: The transformed member block items.
335+
private static func mockMemberBlockItems(
336+
from members: MemberBlockItemListSyntax,
337+
with accessLevel: AccessLevelSyntax,
338+
in protocolDeclaration: ProtocolDeclSyntax
339+
) throws -> MemberBlockItemListSyntax {
340+
try MemberBlockItemListSyntax {
341+
for member in members {
342+
if let initializerDecl = member.decl.as(InitializerDeclSyntax.self) {
343+
MemberBlockItemSyntax(
344+
decl: try self.mockInitializerConformanceDeclaration(
345+
with: accessLevel,
346+
from: initializerDecl
347+
)
345348
)
346-
}
347-
}
348-
349-
for methodDeclaration in methodDeclarations {
350-
try self.mockMethodConformanceDeclaration(
351-
with: accessLevel,
352-
for: methodDeclaration,
353-
in: protocolDeclaration
354-
)
355-
}
356-
357-
for ifConfigDeclaration in ifConfigDeclarations {
358-
if let mockedIfConfig = try self.mockIfConfigDeclaration(
359-
from: ifConfigDeclaration,
360-
with: accessLevel,
361-
in: protocolDeclaration
362-
) {
363-
mockedIfConfig
349+
} else if let propertyDecl = member.decl.as(VariableDeclSyntax.self) {
350+
for binding in propertyDecl.bindings {
351+
MemberBlockItemSyntax(
352+
decl: try self.mockPropertyConformanceDeclaration(
353+
with: accessLevel,
354+
for: binding,
355+
from: propertyDecl
356+
)
357+
)
358+
}
359+
} else if let methodDecl = member.decl.as(FunctionDeclSyntax.self) {
360+
MemberBlockItemSyntax(
361+
decl: try self.mockMethodConformanceDeclaration(
362+
with: accessLevel,
363+
for: methodDecl,
364+
in: protocolDeclaration
365+
)
366+
)
367+
} else if let ifConfigDecl = member.decl.as(IfConfigDeclSyntax.self) {
368+
if let mockedIfConfig = try self.mockIfConfigDeclaration(
369+
from: ifConfigDecl,
370+
with: accessLevel,
371+
in: protocolDeclaration
372+
) {
373+
MemberBlockItemSyntax(decl: mockedIfConfig)
374+
}
364375
}
365376
}
366377
}
@@ -619,15 +630,25 @@ extension MockedMacro {
619630
with accessLevel: AccessLevelSyntax,
620631
in protocolDeclaration: ProtocolDeclSyntax
621632
) throws -> IfConfigDeclSyntax? {
622-
let transformedClauses = try IfConfigClauseListSyntax {
623-
for clause in ifConfigDecl.clauses {
624-
try self.mockIfConfigClause(
625-
from: clause,
633+
let transformedClauses = try IfConfigClauseListSyntax(
634+
ifConfigDecl.clauses.map { clause in
635+
guard case let .decls(memberBlockItems) = clause.elements else {
636+
return clause
637+
}
638+
639+
let transformedMembers = try self.mockMemberBlockItems(
640+
from: memberBlockItems,
626641
with: accessLevel,
627642
in: protocolDeclaration
628643
)
644+
645+
return IfConfigClauseSyntax(
646+
poundKeyword: clause.poundKeyword.trimmed,
647+
condition: clause.condition?.trimmed,
648+
elements: .decls(transformedMembers)
649+
)
629650
}
630-
}
651+
)
631652

632653
let allClausesEmpty = transformedClauses.allSatisfy { clause in
633654
guard case let .decls(members) = clause.elements else {
@@ -645,71 +666,4 @@ extension MockedMacro {
645666
poundEndif: ifConfigDecl.poundEndif.trimmed
646667
)
647668
}
648-
649-
/// Returns a transformed `IfConfigClauseSyntax` with mocked member declarations.
650-
///
651-
/// Associated types are skipped since they become generic parameters on the
652-
/// mock class rather than member declarations.
653-
///
654-
/// - Parameters:
655-
/// - clause: The clause to transform.
656-
/// - accessLevel: The access level to apply to the mocked declarations.
657-
/// - protocolDeclaration: The protocol being mocked.
658-
/// - Returns: A transformed `IfConfigClauseSyntax`.
659-
private static func mockIfConfigClause(
660-
from clause: IfConfigClauseSyntax,
661-
with accessLevel: AccessLevelSyntax,
662-
in protocolDeclaration: ProtocolDeclSyntax
663-
) throws -> IfConfigClauseSyntax {
664-
guard case let .decls(memberBlockItems) = clause.elements else {
665-
return clause
666-
}
667-
668-
let transformedMembers = try MemberBlockItemListSyntax {
669-
for member in memberBlockItems {
670-
if let initializerDecl = member.decl.as(InitializerDeclSyntax.self) {
671-
MemberBlockItemSyntax(
672-
decl: try self.mockInitializerConformanceDeclaration(
673-
with: accessLevel,
674-
from: initializerDecl
675-
)
676-
)
677-
} else if let propertyDecl = member.decl.as(VariableDeclSyntax.self) {
678-
for binding in propertyDecl.bindings {
679-
MemberBlockItemSyntax(
680-
decl: try self.mockPropertyConformanceDeclaration(
681-
with: accessLevel,
682-
for: binding,
683-
from: propertyDecl
684-
)
685-
)
686-
}
687-
} else if let methodDecl = member.decl.as(FunctionDeclSyntax.self) {
688-
MemberBlockItemSyntax(
689-
decl: try self.mockMethodConformanceDeclaration(
690-
with: accessLevel,
691-
for: methodDecl,
692-
in: protocolDeclaration
693-
)
694-
)
695-
} else if let nestedIfConfig = member.decl.as(IfConfigDeclSyntax.self) {
696-
if let mockedIfConfig = try self.mockIfConfigDeclaration(
697-
from: nestedIfConfig,
698-
with: accessLevel,
699-
in: protocolDeclaration
700-
) {
701-
MemberBlockItemSyntax(decl: mockedIfConfig)
702-
}
703-
}
704-
// AssociatedTypeDeclSyntax is intentionally skipped since
705-
// associated types become generic parameters on the mock class.
706-
}
707-
}
708-
709-
return IfConfigClauseSyntax(
710-
poundKeyword: clause.poundKeyword.trimmed,
711-
condition: clause.condition?.trimmed,
712-
elements: .decls(transformedMembers)
713-
)
714-
}
715669
}

0 commit comments

Comments
 (0)