Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f3502b9
docs(MachOSwiftSection): record fixture-tests branch is based on feat…
Mx-Iris May 2, 2026
b7dfd46
docs(MachOSwiftSection): add fixture-based test coverage implementati…
Mx-Iris May 2, 2026
9e208da
docs(MachOSwiftSection): switch baseline generator to SwiftSyntaxBuil…
Mx-Iris May 2, 2026
d25fb29
test(MachOTestingSupport): add MachOSwiftSectionFixtureTests base + d…
Mx-Iris May 2, 2026
86c45f4
test(MachOTestingSupport): wire FixtureLoadError.fixtureFileMissing +…
Mx-Iris May 2, 2026
17e5725
test(MachOTestingSupport): add BaselineEmitter hex helper + SwiftSynt…
Mx-Iris May 2, 2026
ba5abb6
test(MachOTestingSupport): add coverage framework — MethodKey, Fixtur…
Mx-Iris May 2, 2026
b34c1ff
test(MachOTestingSupport): scan public subscript declarations
Mx-Iris May 2, 2026
fefbacd
test(MachOSwiftSection): add fixture-based Suite + baseline for Type/…
Mx-Iris May 2, 2026
b2d5751
test(MachOSwiftSection): tighten Task 4 pilot pattern before Tasks 5-15
Mx-Iris May 2, 2026
7726a90
test(MachOSwiftSection): add fixture-based Suites for Anonymous/Modul…
Mx-Iris May 2, 2026
1ea3530
test(MachOSwiftSection): fix protocol-extension attribution for Exten…
Mx-Iris May 2, 2026
85938b7
test(MachOSwiftSection): add fixture-based Suites for ContextDescriptor/
Mx-Iris May 2, 2026
092f4e3
test(MachOSwiftSection): add fixture-based Suites for Type/Class/
Mx-Iris May 2, 2026
53d3d00
test(MachOSwiftSection): tighten Task 7 — add load helper, drop unuse…
Mx-Iris May 2, 2026
286bae5
test(MachOSwiftSection): add fixture-based Suites for Type/Enum/
Mx-Iris May 2, 2026
2910116
test(MachOSwiftSection): add fixture-based Suites for Type/ root files
Mx-Iris May 2, 2026
8452a3b
test(MachOSwiftSection): add fixture-based Suites for Protocol/
Mx-Iris May 3, 2026
11509bc
test(MachOSwiftSection): add fixture-based Suites for ProtocolConform…
Mx-Iris May 3, 2026
6b44d73
test(MachOSwiftSection): add fixture-based Suites for Generic/
Mx-Iris May 3, 2026
f4889c2
test(MachOSwiftSection): add fixture-based Suites for FieldDescriptor…
Mx-Iris May 3, 2026
6d3939e
test(MachOSwiftSection): add fixture-based Suites for Metadata/ (incl…
Mx-Iris May 3, 2026
326659c
test(MachOSwiftSection): add fixture-based Suites for misc subdirecto…
Mx-Iris May 3, 2026
6b7bd3a
feat(baseline-generator): polish CLI with --suite/--output flags
Mx-Iris May 3, 2026
c5eb947
test(MachOSwiftSection): wire up coverage invariant guard
Mx-Iris May 3, 2026
ccc30f2
docs(MachOSwiftSection): document fixture-based test coverage workflow
Mx-Iris May 3, 2026
e9e45b9
test(MachOTestingSupport): align skipsLayoutTypes test with scanner r…
Mx-Iris May 3, 2026
312ad73
refactor(MachOTestingSupport): split off MachOFixtureSupport
Mx-Iris May 3, 2026
ea21184
fix(baseline-generator): wire @main entry so binary actually runs
Mx-Iris May 4, 2026
60b31e5
feat(baseline-generator): replace shell wrapper with SwiftPM plugin
Mx-Iris May 4, 2026
7255b8e
docs(MachOSwiftSection): add fixture-coverage tightening design
Mx-Iris May 4, 2026
b6cca45
docs(MachOSwiftSection): add fixture-coverage tightening implementati…
Mx-Iris May 4, 2026
6feb6ed
feat(MachOFixtureSupport): introduce SentinelReason schema + SuiteBeh…
Mx-Iris May 4, 2026
b4a576b
test(MachOSwiftSection): seed sentinel reasons for 88 sentinel suites
Mx-Iris May 4, 2026
be89333
fix(MachOFixtureSupport): broaden SuiteBehaviorScanner to detect dire…
Mx-Iris May 4, 2026
a0ac816
test(MachOSwiftSection): reconcile A2 sentinel tags against scanner o…
Mx-Iris May 4, 2026
59f1519
test(MachOSwiftSection): enable liarSentinel + unmarkedSentinel invar…
Mx-Iris May 4, 2026
e2f44db
feat(MachOFixtureSupport): add InProcessMetadataPicker + usingInProce…
Mx-Iris May 4, 2026
c0d31b7
test(MachOSwiftSection): convert metatype/tuple/function suites to In…
Mx-Iris May 4, 2026
5491b9b
test(MachOSwiftSection): convert existential family suites to InProce…
Mx-Iris May 4, 2026
ca8eea6
test(MachOSwiftSection): convert DispatchClassMetadata to InProcess r…
Mx-Iris May 4, 2026
d25ddd5
test(MachOSwiftSection): convert metadata-layer suites to InProcess
Mx-Iris May 4, 2026
5643a99
test(MachOSwiftSection): document B1 deferral due to CoroutineAccesso…
Mx-Iris May 4, 2026
51ae7d3
test(fixture): add ResilientClasses fixture, convert 2 sentinel suites
Mx-Iris May 5, 2026
21524a9
test(fixture): add ObjCClassWrappers fixture, convert ObjC interop su…
Mx-Iris May 5, 2026
a178eb3
test(fixture): add ObjCResilientStubs fixture, convert ObjCResilientC…
Mx-Iris May 5, 2026
046a245
test: defer canonical-specialized-metadata fixture (Swift 6.2 toolcha…
Mx-Iris May 5, 2026
c00e0fe
test(fixture): add ForeignTypes fixture, convert ForeignClassMetadata
Mx-Iris May 5, 2026
286046f
test(fixture): add GenericValueParameters fixture, convert GenericVal…
Mx-Iris May 5, 2026
251e740
docs(MachOSwiftSection): update fixture-coverage workflow for sentine…
Mx-Iris May 5, 2026
f2e6bbd
fix(MachOFixtureSupport): correct stdlibAnyObjectExistential kindRawV…
Mx-Iris May 5, 2026
42f542a
Merge origin/main into feature/machoswift-section-fixture-tests
Mx-Iris May 5, 2026
b67d7ac
fix(MachOFixtureSupport): follow upstream moduleContextDescriptor typ…
Mx-Iris May 5, 2026
84fe742
test(snapshots): cover GenericValueFixtures in dump and interface sna…
Mx-Iris May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,20 @@
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "baseline-generator"
BuildableName = "baseline-generator"
BlueprintName = "baseline-generator"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
Expand Down Expand Up @@ -301,6 +315,26 @@
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "MachOTestingSupportTests"
BuildableName = "MachOTestingSupportTests"
BlueprintName = "MachOTestingSupportTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "IntegrationTests"
BuildableName = "IntegrationTests"
BlueprintName = "IntegrationTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand All @@ -313,6 +347,16 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "baseline-generator"
BuildableName = "baseline-generator"
BlueprintName = "baseline-generator"
ReferencedContainer = "container:">
</BuildableReference>
</BuildableProductRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
Expand All @@ -336,15 +380,16 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "swift-section"
BuildableName = "swift-section"
BlueprintName = "swift-section"
BlueprintIdentifier = "baseline-generator"
BuildableName = "baseline-generator"
BlueprintName = "baseline-generator"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
10 changes: 10 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/swift-section.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "IntegrationTests"
BuildableName = "IntegrationTests"
BlueprintName = "IntegrationTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
42 changes: 42 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,48 @@ Tests use `MACHO_SWIFT_SECTION_SILENT_TEST=1` to suppress verbose output.

Tests read Mach-O files from Xcode frameworks and dyld shared cache for real-world validation.

## Fixture-Based Test Coverage (MachOSwiftSection)

`MachOSwiftSection/Models/` is exhaustively covered by `Tests/MachOSwiftSectionTests/Fixtures/`. Suites mirror the source directory and assert one of:

- **Cross-reader equality** across MachOFile/MachOImage/InProcess + their ReadingContext counterparts (via `acrossAllReaders` / `acrossAllContexts` helpers), plus per-method ABI literal values from `__Baseline__/*Baseline.swift` — this is the standard depth.
- **InProcess single-reader equality** plus per-method ABI literal values (via `usingInProcessOnly` helper). Used for runtime-allocated metadata types (MetatypeMetadata, TupleTypeMetadata, etc.) that have no Mach-O section presence.
- **Sentinel allowlist** with typed `SentinelReason` (in `CoverageAllowlistEntries.swift`). Used for:
- `pureDataUtility`: pure raw-value enums / flag bitfields with no behavior to test (tests would just be tautologies)
- `runtimeOnly`: types impossible to construct stably from tests (e.g., `swift_allocBox`-allocated `GenericBoxHeapMetadata`)
- `needsFixtureExtension`: residual entries deferred by toolchain limits (e.g., `MethodDefaultOverrideTable` requires the not-yet-shipped CoroutineAccessors ABI; canonical-specialized-metadata records need the `-prespecialize-generic-metadata` frontend flag)

`MachOSwiftSectionCoverageInvariantTests` enforces four invariants:
1. Every public method in `Sources/MachOSwiftSection/Models/` has a registered test (or allowlist entry)
2. Every registered test name maps to an actual public method
3. Sentinel-tagged keys' Suites must actually have sentinel behavior (no `acrossAllReaders` / `inProcessContext` references)
4. Sentinel-behavior Suites must be tagged in the allowlist (no silent sentinels)

`SuiteBehaviorScanner` (in `MachOFixtureSupport`) classifies each `@Test func` body by substring presence of `acrossAllReaders` / `acrossAllContexts` / `machOFile` / `machOImage` / `fileContext` / `imageContext` (cross-reader real test) or `usingInProcessOnly` / `inProcessContext` (InProcess-only real test). Helper-call indirection within the same Suite class is recognized via class-scope inheritance.

To add a new public method:

1. Add the method.
2. Run `swift test --filter MachOSwiftSectionCoverageInvariantTests` to see which Suite needs updating.
3. Add a `@Test` to that Suite, using `acrossAllReaders` for fixture-bound types or `usingInProcessOnly` for runtime-only metadata.
4. Append the member name to `registeredTestMethodNames`.
5. Run `swift package --allow-writing-to-package-directory regen-baselines --suite <Name>` to regenerate the baseline.
6. Re-run the affected Suite.

To regenerate all baselines after fixture rebuild or toolchain upgrade:

```bash
xcodebuild -project Tests/Projects/SymbolTests/SymbolTests.xcodeproj -scheme SymbolTestsCore -configuration Release build
swift package --allow-writing-to-package-directory regen-baselines
git diff Tests/MachOSwiftSectionTests/Fixtures/__Baseline__/ # review drift
```

The `regen-baselines` command is provided by the `RegenerateBaselinesPlugin`
SwiftPM command plugin (`Plugins/RegenerateBaselinesPlugin/`). It builds and
invokes the `baseline-generator` executable target. From Xcode you can also
right-click the package → "Regenerate MachOSwiftSection fixture-test ABI
baselines.".

## Work In Progress

### GenericSpecializer (feature/generic-specializer branch)
Expand Down
121 changes: 116 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ var dependencies: [Package.Dependency] = [
.package(url: "https://github.com/p-x9/swift-fileio.git", from: "0.9.0"),
.package(url: "https://github.com/Mx-Iris/FrameworkToolbox", from: "0.4.0"),

.package(url: "https://github.com/MxIris-Library-Forks/swift-memberwise-init-macro", from: "0.5.3-fork"),
.package(url: "https://github.com/gohanlon/swift-memberwise-init-macro", from: "0.6.0"),
.package(url: "https://github.com/Mx-Iris/SourceKitD", from: "0.1.0"),
.package(url: "https://github.com/christophhagen/BinaryCodable", from: "3.1.0"),

Expand Down Expand Up @@ -483,6 +483,38 @@ extension Target {
]
)

static let baseline_generator = Target.executableTarget(
name: "baseline-generator",
dependencies: [
.target(.MachOFixtureSupport),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
swiftSettings: testSettings
)

// MARK: - Plugins

/// `swift package regen-baselines` — regenerates the auto-generated
/// `__Baseline__/<File>Baseline.swift` files consumed by the fixture-based
/// test coverage suites. Replaces the legacy `Scripts/regen-baselines.sh`.
static let RegenerateBaselinesPlugin = Target.plugin(
name: "RegenerateBaselinesPlugin",
capability: .command(
intent: .custom(
verb: "regen-baselines",
description: "Regenerate MachOSwiftSection fixture-test ABI baselines."
),
permissions: [
.writeToPackageDirectory(
reason: "Writes regenerated baselines under Tests/MachOSwiftSectionTests/Fixtures/__Baseline__/."
)
]
),
dependencies: [
.target(.baseline_generator),
]
)

// MARK: - Macros

static let MachOMacros = Target.macro(
Expand All @@ -497,19 +529,45 @@ extension Target {

// MARK: - Testing

static let MachOTestingSupport = Target.target(
name: "MachOTestingSupport",
/// Fixture-loading helpers, baseline generators, coverage scanners, and
/// non-Testing-dependent code. Importable from non-test targets (e.g.
/// `baseline-generator`) without dragging in `Testing.framework`.
static let MachOFixtureSupport = Target.target(
name: "MachOFixtureSupport",
dependencies: [
.product(.MachOKit),
.target(.MachOExtensions),
.target(.MachOFoundation),
.target(.MachOReading),
.target(.MachOResolving),
.target(.MachOSwiftSectionC),
.target(.SwiftDump),
.target(.SwiftInterface),
.target(.MachOTestingSupportC),
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
.product(.Demangling),
.product(.SwiftSyntax),
.product(.SwiftParser),
.product(.SwiftSyntaxBuilder),
],
swiftSettings: testSettings
)


/// `swift-testing` base classes (`MachOFileTests`, `MachOImageTests`,
/// `DyldCacheTests`, `XcodeMachOFileTests`, `MachOSwiftSectionFixtureTests`).
/// Splitting this out from `MachOFixtureSupport` keeps `Testing.framework`
/// out of the link line for non-test targets.
static let MachOTestingSupport = Target.target(
name: "MachOTestingSupport",
dependencies: [
.product(.MachOKit),
.target(.MachOFoundation),
.target(.MachOReading),
.target(.MachOResolving),
.target(.MachOFixtureSupport),
],
swiftSettings: testSettings
)

static let MachOTestingSupportC = Target.target(
name: "MachOTestingSupportC",
dependencies: [
Expand All @@ -522,6 +580,7 @@ extension Target {
dependencies: [
.target(.MachOSymbols),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
],
swiftSettings: testSettings
)
Expand All @@ -531,6 +590,7 @@ extension Target {
dependencies: [
.target(.MachOSwiftSection),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
.target(.SwiftDump),
],
swiftSettings: testSettings
Expand All @@ -541,6 +601,7 @@ extension Target {
dependencies: [
.target(.MachOSwiftSection),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
.target(.SwiftInspection),
],
swiftSettings: testSettings
Expand All @@ -551,6 +612,7 @@ extension Target {
dependencies: [
.target(.SwiftDump),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
.product(.MachOObjCSection),
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
],
Expand All @@ -562,6 +624,7 @@ extension Target {
dependencies: [
.target(.TypeIndexing),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
],
swiftSettings: testSettings
)
Expand All @@ -571,10 +634,51 @@ extension Target {
dependencies: [
.target(.SwiftInterface),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
],
swiftSettings: testSettings
)

static let MachOTestingSupportTests = Target.testTarget(
name: "MachOTestingSupportTests",
dependencies: [
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
],
exclude: [
"Coverage/Fixtures/SampleSource.swift.txt",
"Coverage/Fixtures/SuiteSampleSource.swift.txt",
],
swiftSettings: testSettings
)

static let IntegrationTests = Target.testTarget(
name: "IntegrationTests",
dependencies: [
.target(.MachOExtensions),
.target(.MachOCaches),
.target(.MachOReading),
.target(.MachOResolving),
.target(.MachOSymbols),
.target(.MachOPointers),
.target(.MachOSymbolPointers),
.target(.MachOFoundation),
.target(.MachOSwiftSection),
.target(.SwiftInspection),
.target(.SwiftDump),
.target(.SwiftInterface),
.target(.TypeIndexing),
.target(.MachOTestingSupport),
.target(.MachOFixtureSupport),
.product(.MachOKit),
.product(.MachOObjCSection),
.product(.Demangling),
.product(.Semantic),
.product(name: "Dependencies", package: "swift-dependencies"),
],
swiftSettings: testSettings
)
}

let package = Package(
Expand Down Expand Up @@ -607,11 +711,16 @@ let package = Package(
.SwiftInterface,
.TypeIndexing,
.MachOMacros,
.MachOFixtureSupport,
.MachOTestingSupport,
.MachOTestingSupportC,

// Executable
.swift_section,
.baseline_generator,

// Plugins
.RegenerateBaselinesPlugin,

// Testing
.MachOSymbolsTests,
Expand All @@ -620,6 +729,8 @@ let package = Package(
.SwiftDumpTests,
.TypeIndexingTests,
.SwiftInterfaceTests,
.MachOTestingSupportTests,
.IntegrationTests,
]
)

Expand Down
Loading
Loading