@@ -249,80 +249,17 @@ extension DiscoverableAsTestContent where Self: ~Copyable {
249249
250250private import _TestingInternals
251251
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-
293252extension 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-
323253 /// Get all test content of this type known to Swift and found in the current
324254 /// process using the legacy discovery mechanism.
325255 ///
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+ ///
326263 /// - Returns: A sequence of instances of ``TestContentRecord``. Only test
327264 /// content records matching this ``TestContent`` type's requirements are
328265 /// included in the sequence.
@@ -332,15 +269,30 @@ extension DiscoverableAsTestContent where Self: ~Copyable {
332269 /// opaque type due to a compiler crash. ([143080508](rdar://143080508))
333270 /// }
334271 @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 > > {
336275 validateMemoryLayout ( )
337276
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+
338289 let result = SectionBounds . all ( . typeMetadata) . lazy. flatMap { sb in
339290 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 ) }
341292 . 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) }
344296 }
345297 return AnySequence ( result)
346298 }
0 commit comments