Files
rea/src/dotnet/ManagedTypeNameDigests.test.ts
T
1438422dfe fix(managed): preserve enclosing identity in member comparisons (#3079)
Keep same-named nested members paired by their source-owned enclosing identity, including selected inventories that omit the parent TypeDefs. Share the cached, bounded nominal type-name digest owner with signature resolution; preserve current unknown identity through matching, remapping and absence instead of repairing it with display names or historical compatibility.

Verification: 457 related tests passed after preserving TypeDef visibility/parent applicability and coherent fixtures; the complete static/architecture gate and real pinned-SDK MCP nested/official .NET DLL workflows passed after a sigrok-experiment-only main refresh. Documentation checks passed after the compatibility fix. Full CoreLib inspection retains the pre-existing explicit representation limit. No target assembly execution; local verification used two CPUs and an 8 GiB RSS guard.

Co-authored-by: 8rulerstar <190670431+8rulerstar@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-14 23:20:07 +08:00

114 lines
3.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
MAX_TYPE_NESTING_DEPTH,
nestedTypeDigests,
} from "./ManagedTypeNameDigests.js";
/** Rows 1..length, each nested in the row before it. */
const chain = (length: number) => {
const calls: number[] = [];
const link = (row: number) => {
calls.push(row);
return row >= 1 && row <= length
? {
namespace: "",
name: `T${String(row)}`,
enclosingRow: row > 1 ? row - 1 : null,
}
: null;
};
return { calls, digest: nestedTypeDigests(link, () => undefined) };
};
describe("nested signature type digests", () => {
it("reads each row of a chain within the nesting cap once", () => {
const { calls, digest } = chain(MAX_TYPE_NESTING_DEPTH);
for (let row = MAX_TYPE_NESTING_DEPTH; row >= 1; row -= 1)
expect(digest(row)).toBeInstanceOf(Buffer);
expect(calls).toHaveLength(MAX_TYPE_NESTING_DEPTH);
});
it("does not name a type nested deeper than the cap, and stops at the cap", () => {
const { calls, digest } = chain(4_000);
expect(digest(4_000)).toBeNull();
expect(calls.length).toBeLessThanOrEqual(MAX_TYPE_NESTING_DEPTH + 1);
expect(digest(MAX_TYPE_NESTING_DEPTH)).toBeInstanceOf(Buffer);
expect(digest(MAX_TYPE_NESTING_DEPTH + 1)).toBeNull();
});
it("reads shared parents once when many types are nested past the cap", () => {
// Rows 1..64 form a chain; rows 1001..2000 are each nested in row 64, one
// level past the cap. Naming the deepest types first must not reread the
// chain for each of them.
const calls: number[] = [];
const children = 1_000;
const link = (row: number) => {
calls.push(row);
if (row >= 1 && row <= MAX_TYPE_NESTING_DEPTH)
return {
namespace: "",
name: `T${String(row)}`,
enclosingRow: row > 1 ? row - 1 : null,
};
return row > 1_000 && row <= 1_000 + children
? {
namespace: "",
name: `C${String(row)}`,
enclosingRow: MAX_TYPE_NESTING_DEPTH,
}
: null;
};
const digest = nestedTypeDigests(link, () => undefined);
for (let row = 1_001; row <= 1_000 + children; row += 1)
expect(digest(row)).toBeNull();
// No row is read twice; the walk can stop at the cap before the outermost.
expect(new Set(calls).size).toBe(calls.length);
expect(calls.length).toBeLessThanOrEqual(MAX_TYPE_NESTING_DEPTH + children);
});
it("names every type of a long chain in linear time", () => {
const { calls, digest } = chain(4_000);
for (let row = 1; row <= 4_000; row += 1) digest(row);
// Rows past the cap may each walk at most the cap; none rewalks below it.
expect(calls.length).toBeLessThanOrEqual(
4_000 * (MAX_TYPE_NESTING_DEPTH + 1),
);
expect(calls.filter((row) => row === 1)).toHaveLength(1);
});
it("does not name a type whose nesting is cyclic", () => {
const digest = nestedTypeDigests(
(row) => ({
namespace: "",
name: `T${String(row)}`,
enclosingRow: row === 1 ? 2 : 1,
}),
() => undefined,
);
expect(digest(1)).toBeNull();
expect(digest(2)).toBeNull();
});
it("tells a nested type from a top-level type with its joined name", () => {
const nested = nestedTypeDigests(
(row) =>
row === 1
? { namespace: "", name: "Outer", enclosingRow: null }
: { namespace: "", name: "Inner", enclosingRow: 1 },
() => undefined,
);
const flat = nestedTypeDigests(
() => ({ namespace: "", name: "Outer/Inner", enclosingRow: null }),
() => undefined,
);
expect(nested(2)).not.toEqual(flat(1));
});
});