mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
refactor(objc): retire obsolete class discovery paths
Remove the test-only selection/projection facade and its unused synthesized binding scan. Keep lexical and identity controls at their active owners, with combined behavior covered through EnhancedTools.
This commit is contained in:
1 parent
3ae7daa101
commit
8defd220a9
3 files changed
+67
-83
No files matched your search
@@ -183,6 +183,29 @@ it.each([
|
||||
},
|
||||
);
|
||||
|
||||
it("reports no applicable identity scan when names contain no owned class labels", async () => {
|
||||
const execute = vi.fn(
|
||||
createPort({
|
||||
names: [
|
||||
{ address: "0x1000", value: "__objc_class_HuntRoot_class" },
|
||||
{ address: "0x2000", value: "PTR__OBJC_CLASS_$_NSAlert_100028668" },
|
||||
{ address: "0x3000", value: "s__OBJC_CLASS_$_NSAlert_10002ed0d" },
|
||||
],
|
||||
}).execute,
|
||||
);
|
||||
const tools = new EnhancedTools({ execute });
|
||||
await expect(tools.execute("get_objc_classes", {})).resolves.toEqual({
|
||||
ok: true,
|
||||
value: {
|
||||
count: 0,
|
||||
classes: [],
|
||||
identity_coverage: { status: "not_applicable", reason: null },
|
||||
},
|
||||
});
|
||||
expect(execute).toHaveBeenCalledTimes(1);
|
||||
expect(execute.mock.calls[0]?.[0]).toBe("list_names");
|
||||
});
|
||||
|
||||
describe("Objective-C class import identity composition", () => {
|
||||
it("joins only exact same-target bind slots and preserves literal filter selection", async () => {
|
||||
const tools = new EnhancedTools(createPort());
|
||||
@@ -209,7 +232,22 @@ describe("Objective-C class import identity composition", () => {
|
||||
ok: true,
|
||||
value: {
|
||||
count: 1,
|
||||
classes: [{ address: "0x1000", name: "OBJC_CLASS_$_Document$GOT" }],
|
||||
classes: [
|
||||
{
|
||||
address: "0x1000",
|
||||
name: "OBJC_CLASS_$_Document$GOT",
|
||||
binding_identity: {
|
||||
symbol: "_OBJC_CLASS_$_Document",
|
||||
binding_source: "chained",
|
||||
library_ordinal: 1,
|
||||
library: "/System/Library/Frameworks/AppKit.framework/AppKit",
|
||||
weak: false,
|
||||
addend: "0",
|
||||
slot_addresses: ["0x1000"],
|
||||
},
|
||||
},
|
||||
],
|
||||
identity_coverage: { status: "complete", reason: null },
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -274,6 +312,12 @@ describe("Objective-C class import identity composition", () => {
|
||||
it("keeps names with unknown identity when binding inspection is unavailable", async () => {
|
||||
const tools = new EnhancedTools(
|
||||
createPort({
|
||||
names: [
|
||||
{ address: "0x1000", value: "OBJC_CLASS_$_Document$GOT" },
|
||||
{ address: "0x1000", value: "OBJC_CLASS_$_Document" },
|
||||
{ address: "0x2000", value: "OBJC_CLASS_$_Document" },
|
||||
{ address: "0x2000", value: "OBJC_CLASS_$_Document" },
|
||||
],
|
||||
metadataFailure: new AnalysisCapabilityUnavailableError(
|
||||
provider.id,
|
||||
"inspect_native_dispatch_metadata",
|
||||
@@ -284,7 +328,12 @@ describe("Objective-C class import identity composition", () => {
|
||||
await expect(tools.execute("get_objc_classes", {})).resolves.toMatchObject({
|
||||
ok: true,
|
||||
value: {
|
||||
count: 2,
|
||||
count: 3,
|
||||
classes: [
|
||||
{ address: "0x1000", name: "OBJC_CLASS_$_Document$GOT" },
|
||||
{ address: "0x1000", name: "OBJC_CLASS_$_Document" },
|
||||
{ address: "0x2000", name: "OBJC_CLASS_$_Document" },
|
||||
],
|
||||
identity_coverage: {
|
||||
status: "unknown",
|
||||
reason: "No static Mach-O reader",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
discoverObjcClasses,
|
||||
selectObjcClassCandidates,
|
||||
projectObjcClassCandidates,
|
||||
} from "./symbolAnalysis.js";
|
||||
|
||||
@@ -19,15 +19,11 @@ const classImport = {
|
||||
describe("Objective-C class label discovery", () => {
|
||||
it("does not reinterpret a provider-specific label without an owner tag", () => {
|
||||
expect(
|
||||
discoverObjcClasses(
|
||||
selectObjcClassCandidates(
|
||||
[{ address: "0x1", name: "__objc_class_HuntRoot_class" }],
|
||||
"Hunt",
|
||||
),
|
||||
).toEqual({
|
||||
count: 0,
|
||||
classes: [],
|
||||
identity_coverage: { status: "not_applicable", reason: null },
|
||||
});
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("uses provider-tagged stripped class labels and filters their exact text", () => {
|
||||
@@ -51,25 +47,10 @@ describe("Objective-C class label discovery", () => {
|
||||
: {}),
|
||||
}));
|
||||
|
||||
expect(discoverObjcClasses(names, "Hunt")).toEqual({
|
||||
count: 6,
|
||||
classes: names.slice(0, 6).map(({ address, name }) => ({
|
||||
address,
|
||||
name,
|
||||
})),
|
||||
identity_coverage: {
|
||||
status: "unknown",
|
||||
reason: "Exact class-import binding identity is unavailable.",
|
||||
},
|
||||
});
|
||||
expect(discoverObjcClasses(names, "__objc_class_HuntRoot_class")).toEqual({
|
||||
count: 1,
|
||||
classes: [{ address: "0x1", name: "__objc_class_HuntRoot_class" }],
|
||||
identity_coverage: {
|
||||
status: "unknown",
|
||||
reason: "Exact class-import binding identity is unavailable.",
|
||||
},
|
||||
});
|
||||
expect(selectObjcClassCandidates(names, "Hunt")).toEqual(names.slice(0, 6));
|
||||
expect(
|
||||
selectObjcClassCandidates(names, "__objc_class_HuntRoot_class"),
|
||||
).toEqual([names[0]]);
|
||||
});
|
||||
|
||||
it("coalesces only selected rows whose own addresses prove the same import", () => {
|
||||
@@ -102,24 +83,6 @@ describe("Objective-C class label discovery", () => {
|
||||
],
|
||||
identity_coverage: completeCoverage,
|
||||
});
|
||||
expect(discoverObjcClasses([alias, canonical], "$GOT", scan)).toEqual({
|
||||
count: 1,
|
||||
classes: [
|
||||
{
|
||||
...alias,
|
||||
binding_identity: {
|
||||
symbol: classImport.symbol,
|
||||
binding_source: classImport.binding_source,
|
||||
library_ordinal: classImport.library_ordinal,
|
||||
library: classImport.library,
|
||||
weak: false,
|
||||
addend: "0",
|
||||
slot_addresses: ["0x1000"],
|
||||
},
|
||||
},
|
||||
],
|
||||
identity_coverage: completeCoverage,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not join same-name rows without exact slot evidence", () => {
|
||||
@@ -153,20 +116,13 @@ describe("Objective-C class label discovery", () => {
|
||||
).toMatchObject({ count: 2, classes: rows });
|
||||
});
|
||||
|
||||
it("keeps same-named candidates at distinct addresses until bind identity is known", () => {
|
||||
it("deduplicates exact class labels while keeping distinct addresses", () => {
|
||||
const rows = [
|
||||
{ address: "0x1000", name: "OBJC_CLASS_$_Document" },
|
||||
{ address: "0x1000", name: "OBJC_CLASS_$_Document" },
|
||||
{ address: "0x2000", name: "OBJC_CLASS_$_Document" },
|
||||
];
|
||||
expect(discoverObjcClasses(rows, "")).toEqual({
|
||||
count: 2,
|
||||
classes: [rows[0], rows[2]],
|
||||
identity_coverage: {
|
||||
status: "unknown",
|
||||
reason: "Exact class-import binding identity is unavailable.",
|
||||
},
|
||||
});
|
||||
expect(selectObjcClassCandidates(rows, "")).toEqual([rows[0], rows[2]]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,7 +132,7 @@ it("keeps equal symbols separate when only their lookup ordinals differ", () =>
|
||||
{ address: "0x2000", name: "OBJC_CLASS_$_Document$GOT" },
|
||||
];
|
||||
expect(
|
||||
discoverObjcClasses(rows, "", {
|
||||
projectObjcClassCandidates(rows, {
|
||||
bindings: [
|
||||
{ ...classImport, library_ordinal: -1, library: null },
|
||||
{
|
||||
@@ -203,7 +159,7 @@ it("keeps regular self-scope and weak rebinding records separate", () => {
|
||||
{ address: "0x2000", name: "OBJC_CLASS_$_Document$GOT" },
|
||||
];
|
||||
expect(
|
||||
discoverObjcClasses(rows, "", {
|
||||
projectObjcClassCandidates(rows, {
|
||||
bindings: [
|
||||
{ ...classImport, library_ordinal: 0, library: null },
|
||||
{
|
||||
@@ -226,7 +182,7 @@ it("keeps regular self-scope and weak rebinding records separate", () => {
|
||||
});
|
||||
|
||||
it("excludes pointer and string labels that only contain a class marker", () => {
|
||||
const result = discoverObjcClasses(
|
||||
const result = selectObjcClassCandidates(
|
||||
[
|
||||
{ address: "0x1", name: "PTR__OBJC_CLASS_$_NSAlert_100028668" },
|
||||
{ address: "0x2", name: "s__OBJC_CLASS_$_NSAlert_10002ed0d" },
|
||||
@@ -234,8 +190,7 @@ it("excludes pointer and string labels that only contain a class marker", () =>
|
||||
],
|
||||
"",
|
||||
);
|
||||
expect(result).toMatchObject({
|
||||
count: 1,
|
||||
classes: [{ address: "0x3", name: "AppKit::_OBJC_CLASS_$_NSAlert" }],
|
||||
});
|
||||
expect(result).toEqual([
|
||||
{ address: "0x3", name: "AppKit::_OBJC_CLASS_$_NSAlert" },
|
||||
]);
|
||||
});
|
||||
@@ -54,16 +54,7 @@ export const selectObjcClassCandidates = (
|
||||
/** Project selected class labels, coalescing only exact proven import identities. */
|
||||
export const projectObjcClassCandidates = (
|
||||
candidates: readonly AddressedName[],
|
||||
bindingScan: ObjcClassImportBindingScan = {
|
||||
bindings: [],
|
||||
coverage: {
|
||||
status: candidates.length === 0 ? "not_applicable" : "unknown",
|
||||
reason:
|
||||
candidates.length === 0
|
||||
? null
|
||||
: "Exact class-import binding identity is unavailable.",
|
||||
},
|
||||
},
|
||||
bindingScan: ObjcClassImportBindingScan,
|
||||
): JsonValue => {
|
||||
const classes = coalesceBoundClassAliases(candidates, bindingScan.bindings);
|
||||
return {
|
||||
@@ -76,17 +67,6 @@ export const projectObjcClassCandidates = (
|
||||
};
|
||||
};
|
||||
|
||||
/** Select, then project Objective-C class labels for provider-neutral callers. */
|
||||
export const discoverObjcClasses = (
|
||||
names: readonly AddressedName[],
|
||||
pattern: string,
|
||||
bindingScan?: ObjcClassImportBindingScan,
|
||||
): JsonValue =>
|
||||
projectObjcClassCandidates(
|
||||
selectObjcClassCandidates(names, pattern),
|
||||
bindingScan,
|
||||
);
|
||||
|
||||
/** Select and deduplicate Objective-C and Swift protocol labels. */
|
||||
export const discoverObjcProtocols = (
|
||||
names: readonly AddressedName[],
|
||||
|
||||
Reference in new issue
Block a user