Skip to content

Commit 6eb9aea

Browse files
committed
Update Swift Syntax to 602.0.0
1 parent dcab218 commit 6eb9aea

File tree

4 files changed

+322
-24
lines changed

4 files changed

+322
-24
lines changed

Package.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ let package = Package(
2525
dependencies: [
2626
.package(
2727
url: "https://github.com/fetch-rewards/swift-locking.git",
28-
exact: "0.2.0"
28+
exact: "0.2.1"
2929
),
3030
.package(
3131
url: "https://github.com/swiftlang/swift-syntax.git",
32-
exact: "600.0.0" // Must match SwiftSyntaxSugar's swift-syntax version
32+
from: "602.0.0" // Must match SwiftSyntaxSugar's swift-syntax version
3333
),
3434
.package(
3535
url: "https://github.com/fetch-rewards/SwiftSyntaxSugar.git",
36-
exact: "0.1.1" // Must match swift-locking's SwiftSyntaxSugar version
36+
from: "0.1.2" // Must match swift-locking's SwiftSyntaxSugar version
3737
),
3838
],
3939
targets: [
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// GenericMethodsWithInlineArrayTypes.swift
3+
//
4+
// Copyright © 2025 Fetch.
5+
//
6+
7+
import Foundation
8+
public import Mocking
9+
10+
/// A protocol for verifying Mocked's handling of generic methods that leverage
11+
/// inline array syntax and value-generic arguments.
12+
///
13+
/// - Important: Please only use this protocol for permanent verification of
14+
/// Mocked's handling of inline array syntax. For temporary testing of Mocked's
15+
/// expansion, use the `Playground` protocol in `main.swift`.
16+
@available(macOS 26.0, *)
17+
@Mocked
18+
public protocol GenericMethodsWithInlineArrayTypes {
19+
func genericMethodWithInlineArrayParameter<Element>(
20+
parameter: [3 of Element]
21+
) -> [3 of Element]
22+
23+
func genericMethodReturningInlineArray<Element>(
24+
parameter: InlineArray<3, Element>
25+
) -> InlineArray<3, Element>
26+
27+
func genericMethodWithInlineArraySameTypeRequirement<Element>(
28+
parameter: InlineArray<3, Element>
29+
) -> Element where Element: Sendable, InlineArray<3, Element> == InlineArray<3, Element>
30+
}

Sources/MockingMacros/Macros/MockedMethodMacro/MockedMethodMacro+TypeErasure.swift

Lines changed: 141 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ extension MockedMethodMacro {
247247
ifTypeIsContainedIn: genericParameters,
248248
typeConstrainedBy: genericWhereClause
249249
)
250+
case var .inlineArrayType(type):
251+
let (element, didTypeEraseElement) = self.syntax(
252+
type.element,
253+
ifTypeIsContainedIn: genericParameters,
254+
typeConstrainedBy: genericWhereClause
255+
)
256+
257+
type = type.with(\.element, element)
258+
result = (newType: type, didTypeErase: didTypeEraseElement)
250259
case let .tupleType(type):
251260
result = self.syntax(
252261
type,
@@ -456,9 +465,7 @@ extension MockedMethodMacro {
456465
):
457466
let (newGenericArgumentClause, didTypeErase) = self.syntax(
458467
genericArgumentClause,
459-
withElementsInCollectionAt: \.arguments,
460-
typeErasedAt: \.argument,
461-
ifTypeIsContainedIn: genericParameters,
468+
typeErasedIfElementsIn: genericParameters,
462469
typeConstrainedBy: genericWhereClause
463470
)
464471
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
@@ -470,15 +477,25 @@ extension MockedMethodMacro {
470477
):
471478
let (newGenericArgumentClause, didTypeErase) = self.syntax(
472479
genericArgumentClause,
473-
withElementsInCollectionAt: \.arguments,
474-
typeErasedAt: \.argument,
475-
ifTypeIsContainedIn: genericParameters,
480+
typeErasedIfElementsIn: genericParameters,
476481
typeConstrainedBy: genericWhereClause
477482
) { index in
478483
index == .zero ? AnyHashable.self : Any.self
479484
}
480485
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
481486

487+
return (newType, didTypeErase)
488+
case let .identifierType(type) where self.isIdentifierType(
489+
type,
490+
named: "InlineArray"
491+
):
492+
let (newGenericArgumentClause, didTypeErase) = self.inlineArrayGenericArgumentClause(
493+
genericArgumentClause,
494+
typeErasingElementsIn: genericParameters,
495+
typeConstrainedBy: genericWhereClause
496+
)
497+
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
498+
482499
return (newType, didTypeErase)
483500
case let .memberType(type) where self.isMemberType(
484501
type,
@@ -487,9 +504,7 @@ extension MockedMethodMacro {
487504
):
488505
let (newGenericArgumentClause, didTypeErase) = self.syntax(
489506
genericArgumentClause,
490-
withElementsInCollectionAt: \.arguments,
491-
typeErasedAt: \.argument,
492-
ifTypeIsContainedIn: genericParameters,
507+
typeErasedIfElementsIn: genericParameters,
493508
typeConstrainedBy: genericWhereClause
494509
)
495510
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
@@ -502,22 +517,31 @@ extension MockedMethodMacro {
502517
):
503518
let (newGenericArgumentClause, didTypeErase) = self.syntax(
504519
genericArgumentClause,
505-
withElementsInCollectionAt: \.arguments,
506-
typeErasedAt: \.argument,
507-
ifTypeIsContainedIn: genericParameters,
520+
typeErasedIfElementsIn: genericParameters,
508521
typeConstrainedBy: genericWhereClause
509522
) { index in
510523
index == .zero ? AnyHashable.self : Any.self
511524
}
512525
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
513526

527+
return (newType, didTypeErase)
528+
case let .memberType(type) where self.isMemberType(
529+
type,
530+
named: "InlineArray",
531+
withBaseTypeNamed: "Swift"
532+
):
533+
let (newGenericArgumentClause, didTypeErase) = self.inlineArrayGenericArgumentClause(
534+
genericArgumentClause,
535+
typeErasingElementsIn: genericParameters,
536+
typeConstrainedBy: genericWhereClause
537+
)
538+
let newType = type.with(\.genericArgumentClause, newGenericArgumentClause)
539+
514540
return (newType, didTypeErase)
515541
default:
516542
let (_, didTypeErase) = self.syntax(
517543
genericArgumentClause,
518-
withElementsInCollectionAt: \.arguments,
519-
typeErasedAt: \.argument,
520-
ifTypeIsContainedIn: genericParameters,
544+
typeErasedIfElementsIn: genericParameters,
521545
typeConstrainedBy: genericWhereClause
522546
)
523547

@@ -531,6 +555,108 @@ extension MockedMethodMacro {
531555
}
532556
}
533557

558+
private static func syntax(
559+
_ argument: GenericArgumentSyntax,
560+
ifTypeIsContainedIn genericParameters: GenericParameterListSyntax?,
561+
typeConstrainedBy genericWhereClause: GenericWhereClauseSyntax?,
562+
typeErasedType: (some Any).Type = Any.self
563+
) -> (GenericArgumentSyntax, Bool) {
564+
guard case let .type(type) = argument.argument else {
565+
return (argument, false)
566+
}
567+
568+
let (erasedType, didTypeErase) = self.type(
569+
type,
570+
typeErasedIfNecessaryUsing: genericParameters,
571+
typeConstrainedBy: genericWhereClause,
572+
typeErasedType: typeErasedType
573+
)
574+
575+
let newArgument = argument.with(
576+
\.argument,
577+
.type(TypeSyntax(erasedType))
578+
)
579+
580+
return (newArgument, didTypeErase)
581+
}
582+
583+
private static func syntax(
584+
_ clause: GenericArgumentClauseSyntax,
585+
typeErasedIfElementsIn genericParameters: GenericParameterListSyntax?,
586+
typeConstrainedBy genericWhereClause: GenericWhereClauseSyntax?,
587+
typeErasedType: (Int) -> Any.Type
588+
) -> (GenericArgumentClauseSyntax, Bool) {
589+
var didTypeErase = false
590+
var newArguments: [GenericArgumentSyntax] = []
591+
592+
for (index, argument) in clause.arguments.enumerated() {
593+
let (newArgument, didTypeEraseArgument) = self.syntax(
594+
argument,
595+
ifTypeIsContainedIn: genericParameters,
596+
typeConstrainedBy: genericWhereClause,
597+
typeErasedType: typeErasedType(index)
598+
)
599+
600+
newArguments.append(newArgument)
601+
didTypeErase = didTypeErase || didTypeEraseArgument
602+
}
603+
604+
let newClause = clause.with(
605+
\.arguments,
606+
GenericArgumentListSyntax(newArguments)
607+
)
608+
609+
return (newClause, didTypeErase)
610+
}
611+
612+
private static func syntax(
613+
_ clause: GenericArgumentClauseSyntax,
614+
typeErasedIfElementsIn genericParameters: GenericParameterListSyntax?,
615+
typeConstrainedBy genericWhereClause: GenericWhereClauseSyntax?
616+
) -> (GenericArgumentClauseSyntax, Bool) {
617+
self.syntax(
618+
clause,
619+
typeErasedIfElementsIn: genericParameters,
620+
typeConstrainedBy: genericWhereClause
621+
) { _ in Any.self }
622+
}
623+
624+
private static func inlineArrayGenericArgumentClause(
625+
_ clause: GenericArgumentClauseSyntax,
626+
typeErasingElementsIn genericParameters: GenericParameterListSyntax?,
627+
typeConstrainedBy genericWhereClause: GenericWhereClauseSyntax?
628+
) -> (GenericArgumentClauseSyntax, Bool) {
629+
guard !clause.arguments.isEmpty else {
630+
return (clause, false)
631+
}
632+
633+
var didTypeErase = false
634+
var newArguments: [GenericArgumentSyntax] = []
635+
636+
for (index, argument) in clause.arguments.enumerated() {
637+
if index == .zero {
638+
newArguments.append(argument)
639+
continue
640+
}
641+
642+
let (newArgument, didTypeEraseArgument) = self.syntax(
643+
argument,
644+
ifTypeIsContainedIn: genericParameters,
645+
typeConstrainedBy: genericWhereClause
646+
)
647+
648+
newArguments.append(newArgument)
649+
didTypeErase = didTypeErase || didTypeEraseArgument
650+
}
651+
652+
let newClause = clause.with(
653+
\.arguments,
654+
GenericArgumentListSyntax(newArguments)
655+
)
656+
657+
return (newClause, didTypeErase)
658+
}
659+
534660
/// Returns a Boolean value indicating whether the provided identifier
535661
/// type's name matches any of the provided `names`.
536662
///

0 commit comments

Comments
 (0)