Skip to content

refactor(core): consume the ObjC rendering and indexing layers from the library - #102

Merged
Mx-Iris merged 5 commits into
nextfrom
feature/objc-rendering-and-indexing
Aug 15, 2026
Merged

refactor(core): consume the ObjC rendering and indexing layers from the library#102
Mx-Iris merged 5 commits into
nextfrom
feature/objc-rendering-and-indexing

Conversation

@Mx-Iris

@Mx-Iris Mx-Iris commented Aug 14, 2026

Copy link
Copy Markdown
Member

Implements Evolution 0007 — ObjC 关系索引归还应用侧, the downstream adaptation of MachOObjCSection 0003.

Two halves, in order:

1. The rendering and indexing layers move to the library

The ObjC renderer and interface indexer were never RuntimeViewer-specific — they turn ObjC metadata into semantic declarations and build a queryable index, which any MachOObjCSection consumer wants — yet ~1500 lines of them sat in this app's core layer. They now ship with MachOObjCSection, so RuntimeObjCSection drops from 617 lines to 471 and is left translating library results into RuntimeViewer domain types.

The concrete transformer modules likewise move to the libraries that own their vocabulary. What stays is the aggregate Transformer.Configuration: it spans both halves, and nothing outside RuntimeViewer persists them as a unit. Re-exports keep every existing Transformer.… reference compiling.

2. The relationship tables come back to the application

MachOObjCSection 0003 removed the inheritance and protocol-adoption reverse tables from ObjCIndexing: the library parses and broadcasts what it finds, and no longer remembers how classes relate. RuntimeObjCRelationshipIndex is where those broadcasts become tables again, one per image, fed by the event stream during prepare().

The hazard here is not the three deleted APIs — the compiler catches those. It is that eventHandler quietly changed from an observer into the sole channel carrying relationship data, while RuntimeObjCSection installed one only when a progress stream was supplied. Six of the seven section-creation call sites pass no progress stream, background indexing among them, so keeping that condition would have emptied the Relationships pane for nearly every image while still compiling and still passing most tests. The handler is now unconditional; only the forwarding of .progress events depends on there being a stream.

Tables build on first query instead of behind a seal-the-index call. Requiring one would have reintroduced exactly the failure this change exists to remove: forget it, or miss it because prepare() threw, and every query silently returns nothing.

RuntimeObjCSectionFactory's aggregate indexer goes away rather than moving — it was only ever written to, since RuntimeRelationshipsResolver fans out across images itself.

Equivalence

No user-visible change is intended: the Relationships pane keeps its contents and its order.

Pinned by a baseline captured through relationships(for:) before the pin moved, since that is the only vantage point existing on both sides of the change. Output matches it verbatim: 307 NSObject subclasses, 9 NSCoding and 68 NSCopying conformers, identical in order and in imagePath.

Three properties the match rests on get their own unit tests — inline and category adoptions sharing one table, arrival-order replay, and dedup keyed on all three fields so a class reaching one protocol twice with differing isSwiftStable stays twice.

Dependency pins

Moves to the tags carrying the extracted layers: MachOObjCSection 0.8.102, MachOSwiftSection 0.15.0, swift-semantic-string 0.3.0. MachOKit goes to 0.52.100 because 0.8.102 requires it.

This branch cannot resolve against the remote pins yet. MachOSwiftSection 0.15.0 holds MachOObjCSection at exact 0.8.102, so building and testing needs USING_LOCAL_DEPENDENCIES=1 until that pin moves to 0.8.103. This is why the target is next rather than main — next builds against the local sibling checkouts by design.

Merge notes

  • RuntimeViewerCore/Package.resolved conflicts with next in three places: originHash, MachInjector (next 0.5.0 vs 0.4.3 here) and swift-helper-service (next 0.3.1 vs 0.2.0 here). Take next's versions for both packages and re-resolve so SPM recomputes originHash; every pin unique to this branch merges cleanly and must be kept.
  • Overlaps Feature/node store adoption #101 (feature/node-store-adoption) on five files, RuntimeObjCInterfaceIndexer.swift most substantially — both lines rewrote it. Whichever lands second needs a real merge, not a side pick.
  • Commit 33c1f8a also settles what to do about f41648a on Feature/node store adoption #101, which added removeSubIndexer to plug the leak the aggregate indexer caused — with no aggregate there is nothing to detach.

…rary

The ObjC renderer and interface indexer were never RuntimeViewer-specific —
they turn ObjC metadata into semantic declarations and build a queryable
index, which any MachOObjCSection consumer wants — yet ~1500 lines of them
sat in this app's core layer. They now ship with MachOObjCSection, so
RuntimeObjCSection drops from 617 lines to 471 and is left doing what it
should: translating library results into RuntimeViewer domain types.

The library reports progress and discovered relationships through a single
ObjCIndexingEvent channel where this code had two; the adapter back onto
RuntimeObjectsLoadingEvent lives in ObjCIndexingEvent+LoadingProgress.

The concrete transformer modules likewise move to the libraries that own
their vocabulary. What stays is the aggregate Transformer.Configuration:
it spans both halves, and nothing outside RuntimeViewer persists them as a
unit. Re-exports keep every existing Transformer.… reference compiling.
RuntimeObjCSection becomes the thin translation layer it should be; the
renderer, indexer and transformer modules now ship with the libraries.
Points at the tags that carry the extracted layers: MachOObjCSection 0.8.102,
MachOSwiftSection 0.15.0, swift-semantic-string 0.3.0. MachOKit goes to
0.52.100 because 0.8.102 requires it — the old 0.51.101 pin only held because
the previously referenced MachOObjCSection 0.7.103 asked for far less.

Package.resolved is regenerated with everything resolving remotely, so its
pins are complete.
The 0.15.0 tag was recut to include the release commit (changelog plus the
BundledVersion bump its release workflow requires), so the version now
resolves to a different revision than the one recorded here.
MachOObjCSection 0003 removed the inheritance and protocol-adoption reverse
tables from ObjCIndexing: the library parses and broadcasts what it finds, and
no longer remembers how classes relate. RuntimeObjCRelationshipIndex is where
those broadcasts become tables again, one per image, fed by the event stream
during prepare().

The hazard here is not the three deleted APIs — the compiler catches those. It
is that eventHandler quietly changed from an observer into the sole channel
carrying relationship data, and RuntimeObjCSection installed one only when a
progress stream was supplied. Six of the seven section-creation call sites pass
no progress stream, background indexing among them, so keeping that condition
would have emptied the Relationships pane for nearly every image while still
compiling and still passing most tests. The handler is now unconditional; only
the forwarding of .progress events depends on there being a stream.

Equivalence is pinned by a baseline captured through relationships(for:) before
the pin moved, since that is the only vantage point existing on both sides of
the change. Output matches it verbatim: 307 NSObject subclasses, 9 NSCoding and
68 NSCopying conformers, identical in order and in imagePath. Three properties
the match rests on get their own unit tests — inline and category adoptions
sharing one table, arrival-order replay, and dedup keyed on all three fields so
a class reaching one protocol twice with differing isSwiftStable stays twice.

RuntimeObjCSectionFactory's aggregate indexer goes away rather than moving: it
was only ever written to, since RuntimeRelationshipsResolver fans out across
images itself. That also settles what to do about f41648a on
feature/node-store-adoption, which added removeSubIndexer to plug the leak the
aggregate caused — with no aggregate there is nothing to detach.

Tables build on first query instead of behind a seal-the-index call. Requiring
one would have reintroduced exactly the failure this change exists to remove:
forget it, or miss it because prepare() threw, and every query silently returns
nothing.

Note: this cannot resolve against the remote pins yet. MachOSwiftSection 0.15.0
holds MachOObjCSection at exact 0.8.102, so building and testing this branch
needs USING_LOCAL_DEPENDENCIES=1 until that pin moves to 0.8.103.
Copilot AI lite review requested due to automatic review settings August 14, 2026 13:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors RuntimeViewerCore to consume Objective-C declaration rendering and interface indexing from the upstream libraries (MachOObjCSection / MachOSwiftSection / swift-semantic-string), while reintroducing Objective-C relationship reverse tables in-app by rebuilding them from the library’s ObjCIndexingEvent stream (per Evolution 0007).

Changes:

  • Replace the app-owned ObjC renderer/indexer with library-provided ObjCInterfaceIndexer + ObjCInterfaceBuilder, mapping RuntimeViewer transformer settings into the new API.
  • Add RuntimeObjCRelationshipIndex to rebuild inheritance/protocol-adoption tables from ObjCIndexingEvent, and update relationships resolution to query it.
  • Restructure/add tests: new snapshot + regression coverage for relationships and a focused Transformer.Configuration persistence suite; update dependency pins and documentation.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/TransformerTests.swift Removed legacy transformer tests after transformer engines/modules moved library-side.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/TransformerConfigurationTests.swift New tests validating unified Transformer namespace + Transformer.Configuration persistence.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/TransformerAdditionalTests.swift Removed extensive Swift-side transformer module tests now owned/tested upstream.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/Snapshots/relationships-baseline.txt Added golden baseline snapshot for relationship equivalence checks.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/RuntimeObjCRelationshipIndexTests.swift New unit tests pinning correctness properties of the rebuilt relationship tables.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/RelationshipsWithoutProgressStreamTests.swift New regression test ensuring relationship data survives when no progress stream is supplied.
RuntimeViewerCore/Tests/RuntimeViewerCoreTests/RelationshipsEquivalenceSnapshotTests.swift New end-to-end snapshot test for RuntimeEngine.relationships(for:) output equivalence.
RuntimeViewerCore/Sources/RuntimeViewerCore/Utils/ObjCDump+SemanticString.swift Deleted app-owned ObjCDump→Semantic rendering implementation now provided by the library.
RuntimeViewerCore/Sources/RuntimeViewerCore/Utils/MachOImage+AddressFormatting.swift Deleted local address formatting helpers (now using library/shared equivalents).
RuntimeViewerCore/Sources/RuntimeViewerCore/Transformer/Transformer+ObjCIvarOffset.swift Deleted ObjC transformer module moved to MachOObjCSection.
RuntimeViewerCore/Sources/RuntimeViewerCore/Transformer/Transformer+CType.swift Deleted ObjC transformer module moved to MachOObjCSection.
RuntimeViewerCore/Sources/RuntimeViewerCore/Transformer/Transformer+Configuration.swift Added RuntimeViewer-owned aggregate configuration spanning ObjC+Swift transformer halves.
RuntimeViewerCore/Sources/RuntimeViewerCore/Transformer/Transformer.swift Updated re-exports to point at new transformer namespace/modules split across libraries.
RuntimeViewerCore/Sources/RuntimeViewerCore/Relationships/RuntimeRelationshipsResolver.swift Switched ObjC relationship queries to use objcRelationshipIndex + new reference type.
RuntimeViewerCore/Sources/RuntimeViewerCore/Relationships/RuntimeObjCRelationshipIndex.swift Added per-image relationship reverse-table builder fed by ObjCIndexingEvent.
RuntimeViewerCore/Sources/RuntimeViewerCore/Indexing/RuntimeSwiftInterfaceIndexer.swift Updated commentary to reflect ObjC indexer type/name changes.
RuntimeViewerCore/Sources/RuntimeViewerCore/Indexing/RuntimeObjCInterfaceIndexer.swift Deleted app-owned ObjC interface indexer (replaced by library indexer).
RuntimeViewerCore/Sources/RuntimeViewerCore/Core/RuntimeObjCSection.swift Rewired ObjC section construction to library indexer/builder; installed unconditional event handler; integrated relationship index.
RuntimeViewerCore/Sources/RuntimeViewerCore/Core/ObjCIndexingEvent+LoadingProgress.swift Added mapping from library indexing phases to RuntimeViewer loading phases.
RuntimeViewerCore/Package.swift Updated dependency pins and product dependencies for moved ObjC/Swift transformer & indexing/rendering layers.
RuntimeViewerCore/Package.resolved Updated lockfile pins (currently inconsistent with manifest for MachOObjCSection).
Documentations/README.md Updated evolution count/list to include new proposals.
Documentations/Evolutions/README.md Added entry for Evolution 0007.
Documentations/Evolutions/0007-objc-relationship-index-returns-to-application.md Added full Evolution 0007 design/rollout document for the relationship-index migration.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 95 to 98
remote: .package(
url: "https://github.com/MxIris-Reverse-Engineering/MachOObjCSection",
exact: "0.7.103",
exact: "0.8.103",
),
Comment on lines 79 to 83
"location" : "https://github.com/MxIris-Reverse-Engineering/MachOObjCSection",
"state" : {
"revision" : "63e4b8a61d54fe90bb30e87c0c93f6a8b9c181f9",
"version" : "0.7.103"
"revision" : "415430845bcafd2309cba7c822e260a3cb811523",
"version" : "0.8.102"
}
@Mx-Iris
Mx-Iris merged commit 6cf23b0 into next Aug 15, 2026
4 checks passed
@Mx-Iris
Mx-Iris deleted the feature/objc-rendering-and-indexing branch August 15, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants