@@ -25,7 +25,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
25
25
guard _diagnoseIssues ( with: declaration, suiteAttribute: node, in: context) else {
26
26
return [ ]
27
27
}
28
- return _createTestContainerDecls ( for: declaration, suiteAttribute: node, in: context)
28
+ return _createSuiteDecls ( for: declaration, suiteAttribute: node, in: context)
29
29
}
30
30
31
31
public static func expansion(
@@ -97,8 +97,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
97
97
return !diagnostics. lazy. map ( \. severity) . contains ( . error)
98
98
}
99
99
100
- /// Create a declaration for a type that conforms to the `__TestContainer`
101
- /// protocol and which contains the given suite type.
100
+ /// Create the declarations necessary to discover a suite at runtime.
102
101
///
103
102
/// - Parameters:
104
103
/// - declaration: The type declaration the result should encapsulate.
@@ -107,7 +106,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
107
106
///
108
107
/// - Returns: An array of declarations providing runtime information about
109
108
/// the test suite type `declaration`.
110
- private static func _createTestContainerDecls (
109
+ private static func _createSuiteDecls (
111
110
for declaration: some DeclGroupSyntax ,
112
111
suiteAttribute: AttributeSyntax ,
113
112
in context: some MacroExpansionContext
@@ -127,28 +126,48 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
127
126
// Parse the @Suite attribute.
128
127
let attributeInfo = AttributeInfo ( byParsing: suiteAttribute, on: declaration, in: context)
129
128
130
- // The emitted type must be public or the compiler can optimize it away
131
- // (since it is not actually used anywhere that the compiler can see.)
132
- //
133
- // The emitted type must be deprecated to avoid causing warnings in client
134
- // code since it references the suite metatype, which may be deprecated
135
- // to allow test functions to validate deprecated APIs. The emitted type is
136
- // also annotated unavailable, since it's meant only for use by the testing
137
- // library at runtime. The compiler does not allow combining 'unavailable'
138
- // and 'deprecated' into a single availability attribute: rdar://111329796
139
- let typeName = declaration. type. tokens ( viewMode: . fixedUp) . map ( \. textWithoutBackticks) . joined ( )
140
- let enumName = context. makeUniqueName ( " __🟠$test_container__suite__ \( typeName) " )
129
+ let generatorName = context. makeUniqueName ( " generator " )
130
+ result. append (
131
+ """
132
+ @available(*, deprecated, message: " This property is an implementation detail of the testing library. Do not use it directly. " )
133
+ @Sendable private static func \( generatorName) () async -> Testing.Test {
134
+ .__type(
135
+ \( declaration. type. trimmed) .self,
136
+ \( raw: attributeInfo. functionArgumentList ( in: context) )
137
+ )
138
+ }
139
+ """
140
+ )
141
+
142
+ let accessorName = context. makeUniqueName ( " accessor " )
143
+ result. append (
144
+ """
145
+ @available(*, deprecated, message: " This property is an implementation detail of the testing library. Do not use it directly. " )
146
+ private nonisolated static let \( accessorName) : Testing.__TestContentRecordAccessor = { outValue, type, _ in
147
+ Testing.Test.__store( \( generatorName) , into: outValue, asTypeAt: type)
148
+ }
149
+ """
150
+ )
151
+
152
+ let testContentRecordName = context. makeUniqueName ( " testContentRecord " )
153
+ result. append (
154
+ makeTestContentRecordDecl (
155
+ named: testContentRecordName,
156
+ in: declaration. type,
157
+ ofKind: . testDeclaration,
158
+ accessingWith: accessorName,
159
+ context: attributeInfo. testContentRecordFlags
160
+ )
161
+ )
162
+
163
+ // Emit a type that contains a reference to the test content record.
164
+ let className = context. makeUniqueName ( " __🟠$ " )
141
165
result. append (
142
166
"""
143
167
@available(*, deprecated, message: " This type is an implementation detail of the testing library. Do not use it directly. " )
144
- enum \( enumName) : Testing.__TestContainer {
145
- static var __tests: [Testing.Test] {
146
- get async {[
147
- .__type(
148
- \( declaration. type. trimmed) .self,
149
- \( raw: attributeInfo. functionArgumentList ( in: context) )
150
- )
151
- ]}
168
+ private final class \( className) : Testing.__TestContentRecordContainer {
169
+ override nonisolated class var __testContentRecord: Testing.__TestContentRecord {
170
+ \( testContentRecordName)
152
171
}
153
172
}
154
173
"""
0 commit comments