Skip to content

Commit

Permalink
Search all available dlyd images for known providers (#38)
Browse files Browse the repository at this point in the history
Fixes issue where `#StorybookPage` declarations from dynamic frameworks
are not being picked up by the Book iterator
  • Loading branch information
JohnEstropia committed Mar 15, 2024
1 parent 9dcffa6 commit b1e1709
Showing 1 changed file with 22 additions and 28 deletions.
50 changes: 22 additions & 28 deletions Sources/StorybookKit/Internals/machOLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,28 @@ extension Book {
guard !moduleName.isEmpty else {
return nil
}
guard
let imageIndex = (0..<_dyld_image_count()).first(
where: {
guard let pathC = _dyld_get_image_name($0) else {
return false
}
let path = String(cString: pathC)
let imageName = path
.components(separatedBy: "/")
.last?
.components(separatedBy: ".")
.first
if imageName == moduleName {
print(path)
}
return imageName == moduleName
}
var results: [any BookProvider.Type] = []
for imageIndex in 0 ..< _dyld_image_count() {
self.findAllBookProviders(
inImageIndex: .init(imageIndex),
filterByStorybookPageMacro: filterByStorybookPageMacro,
results: &results
)
else {
return nil
}
return results
}

private static func findAllBookProviders(
inImageIndex imageIndex: UInt32,
filterByStorybookPageMacro: Bool,
results: inout [any BookProvider.Type]
) {
// Follows same approach here: https://github.com/apple/swift-testing/blob/main/Sources/TestingInternals/Discovery.cpp#L318
guard
let headerRawPtr: UnsafeRawPointer = _dyld_get_image_header(imageIndex)
.map(UnsafeRawPointer.init(_:))
else {
return nil
return
}
let headerPtr = headerRawPtr.assumingMemoryBound(
to: mach_header_64.self
Expand All @@ -79,23 +73,23 @@ extension Book {
)
.map(UnsafeRawPointer.init(_:))
else {
return nil
return
}
let capacity: Int = .init(size) / MemoryLayout<SwiftTypeMetadataRecord>.size
let sectionPtr = sectionRawPtr.assumingMemoryBound(
to: SwiftTypeMetadataRecord.self
)
return (0 ..< capacity).compactMap { index in
for index in 0 ..< capacity {
let record = sectionPtr.advanced(by: index)
guard
let contextDescriptor = record.pointee.contextDescriptor(
from: record
)
else {
return nil
continue
}
guard !contextDescriptor.pointee.isGeneric() else {
return nil
continue
}
guard
contextDescriptor.pointee.kind().canConformToProtocol,
Expand All @@ -106,23 +100,23 @@ extension Book {
}
)
else {
return nil
continue
}
let metadataClosure = contextDescriptor.resolveValue(for: \.metadataAccessFunction)
let metadata = metadataClosure(0xFF)
guard
let metadataAccessFunction = metadata.value
else {
return nil
continue
}
let anyType = unsafeBitCast(
metadataAccessFunction,
to: Any.Type.self
)
guard let bookProviderType = anyType as? any BookProvider.Type else {
return nil
continue
}
return bookProviderType
results.append(bookProviderType)
}
}
}
Expand Down

0 comments on commit b1e1709

Please sign in to comment.