@@ -249,80 +249,17 @@ extension DiscoverableAsTestContent where Self: ~Copyable {
249
249
250
250
private import _TestingInternals
251
251
252
- /// A protocol describing a type, emitted at compile time or macro expansion
253
- /// time, that represents a single test content record.
254
- ///
255
- /// Use this protocol to make discoverable any test content records contained in
256
- /// the type metadata section (the "legacy discovery mechanism"). For example,
257
- /// if you have creasted a test content record named `myRecord` and your test
258
- /// content record typealias is named `MyRecordType`:
259
- ///
260
- /// ```swift
261
- /// private enum MyRecordContainer: TestContentRecordContainer {
262
- /// nonisolated static func storeTestContentRecord(to outTestContentRecord: UnsafeMutableRawPointer) -> Bool {
263
- /// outTestContentRecord.initializeMemory(as: MyRecordType.self, to: myRecord)
264
- /// return true
265
- /// }
266
- /// }
267
- /// ```
268
- ///
269
- /// Then, at discovery time, call ``DiscoverableAsTestContent/allTypeMetadataBasedTestContentRecords()``
270
- /// to look up `myRecord`.
271
- ///
272
- /// Types that represent test content and that should be discoverable at runtime
273
- /// should not conform to this protocol. Instead, they should conform to
274
- /// ``DiscoverableAsTestContent``.
275
- @_spi ( Experimental) @_spi ( ForToolsIntegrationOnly)
276
- @_alwaysEmitConformanceMetadata
277
- @available ( swift, deprecated: 100000.0 , message: " Do not adopt this functionality in new code. It will be removed in a future release. " )
278
- public protocol TestContentRecordContainer {
279
- /// Store this container's corresponding test content record to memory.
280
- ///
281
- /// - Parameters:
282
- /// - outTestContentRecord: A pointer to uninitialized memory large enough
283
- /// to hold a test content record. The memory is untyped so that client
284
- /// code can use a custom definition of the test content record tuple
285
- /// type.
286
- ///
287
- /// - Returns: Whether or not `outTestContentRecord` was initialized. If this
288
- /// function returns `true`, the caller is responsible for deinitializing
289
- /// said memory after it is done using it.
290
- nonisolated static func storeTestContentRecord( to outTestContentRecord: UnsafeMutableRawPointer ) -> Bool
291
- }
292
-
293
252
extension DiscoverableAsTestContent where Self: ~ Copyable {
294
- /// Make a test content record of this type from the given test content record
295
- /// container type if it matches this type's requirements.
296
- ///
297
- /// - Parameters:
298
- /// - containerType: The test content record container type.
299
- /// - sb: The section bounds containing `containerType` and, thus, the test
300
- /// content record.
301
- ///
302
- /// - Returns: A new test content record value, or `nil` if `containerType`
303
- /// failed to store a record or if the record's kind did not match this
304
- /// type's ``testContentKind`` property.
305
- private static func _makeTestContentRecord( from containerType: ( some TestContentRecordContainer ) . Type, in sb: SectionBounds ) -> TestContentRecord < Self > ? {
306
- withUnsafeTemporaryAllocation ( of: _TestContentRecord. self, capacity: 1 ) { buffer in
307
- // Load the record from the container type.
308
- guard containerType. storeTestContentRecord ( to: buffer. baseAddress!) else {
309
- return nil
310
- }
311
- let record = buffer. baseAddress!. move ( )
312
-
313
- // Make sure that the record's kind matches.
314
- guard record. kind == Self . testContentKind else {
315
- return nil
316
- }
317
-
318
- // Construct the TestContentRecord instance from the record.
319
- return TestContentRecord ( imageAddress: sb. imageAddress, record: record)
320
- }
321
- }
322
-
323
253
/// Get all test content of this type known to Swift and found in the current
324
254
/// process using the legacy discovery mechanism.
325
255
///
256
+ /// - Parameters:
257
+ /// - baseType: The type which all discovered container types must
258
+ /// conform to or subclass.
259
+ /// - loader: A function that is called once per type conforming to or
260
+ /// subclassing `baseType`. This function should load the corresponding
261
+ /// test content record into the buffer passed to it.
262
+ ///
326
263
/// - Returns: A sequence of instances of ``TestContentRecord``. Only test
327
264
/// content records matching this ``TestContent`` type's requirements are
328
265
/// included in the sequence.
@@ -332,15 +269,30 @@ extension DiscoverableAsTestContent where Self: ~Copyable {
332
269
/// opaque type due to a compiler crash. ([143080508](rdar://143080508))
333
270
/// }
334
271
@available ( swift, deprecated: 100000.0 , message: " Do not adopt this functionality in new code. It will be removed in a future release. " )
335
- public static func allTypeMetadataBasedTestContentRecords( ) -> AnySequence < TestContentRecord < Self > > {
272
+ public static func allTypeMetadataBasedTestContentRecords(
273
+ loadingWith loader: @escaping @Sendable ( Any . Type , UnsafeMutableRawBufferPointer ) -> Bool
274
+ ) -> AnySequence < TestContentRecord < Self > > {
336
275
validateMemoryLayout ( )
337
276
277
+ let typeNameHint = _testContentTypeNameHint
278
+ let kind = testContentKind
279
+ let loader : @Sendable ( Any . Type ) -> _TestContentRecord ? = { type in
280
+ withUnsafeTemporaryAllocation ( of: _TestContentRecord. self, capacity: 1 ) { buffer in
281
+ // Load the record from the container type.
282
+ guard loader ( type, . init( buffer) ) else {
283
+ return nil
284
+ }
285
+ return buffer. baseAddress!. move ( )
286
+ }
287
+ }
288
+
338
289
let result = SectionBounds . all ( . typeMetadata) . lazy. flatMap { sb in
339
290
stride ( from: sb. buffer. baseAddress!, to: sb. buffer. baseAddress! + sb. buffer. count, by: SWTTypeMetadataRecordByteCount) . lazy
340
- . compactMap { swt_getType ( fromTypeMetadataRecord: $0, ifNameContains: " __🟡$ " ) }
291
+ . compactMap { swt_getType ( fromTypeMetadataRecord: $0, ifNameContains: typeNameHint ) }
341
292
. map { unsafeBitCast ( $0, to: Any . Type. self) }
342
- . compactMap { $0 as? any TestContentRecordContainer . Type }
343
- . compactMap { _makeTestContentRecord ( from: $0, in: sb) }
293
+ . compactMap ( loader)
294
+ . filter { $0. kind == kind }
295
+ . map { TestContentRecord < Self > ( imageAddress: sb. imageAddress, record: $0) }
344
296
}
345
297
return AnySequence ( result)
346
298
}
0 commit comments