fix(managed): derive selected scope from parsed declarations

This commit is contained in:
morluto committed 2026-10-24 02:37:47 +08:00
1 parent ba781330d6
commit 1f0eb228e5
6 files changed
+105 -32

No files matched your search

@@ -11,6 +11,7 @@ import {
import {
buildComparisonCoverage,
hasCompleteMethodRows,
selectedDeclaringTypes,
buildComparisonMatching,
buildComparisonSummary,
comparisonLimitations,
@@ -216,11 +217,6 @@ export interface ManagedMemberComparisonSide {
readonly result: ManagedMemberInspection;
}
const selectedTypes = (
result: ManagedMemberInspection,
): ReadonlySet<string> | null =>
result.selection === null ? null : new Set(result.selection.type_names);
const callEdgesByCaller = (
result: ManagedMemberInspection,
): ReadonlyMap<
@@ -275,8 +271,8 @@ export const compareManagedMembers = (
rightMethodsComplete:
right.result.metadata.status === "complete" &&
hasCompleteMethodRows(right.result),
leftSelection: selectedTypes(left.result),
rightSelection: selectedTypes(right.result),
leftSelection: selectedDeclaringTypes(left.result),
rightSelection: selectedDeclaringTypes(right.result),
signatureResolutionExamined:
hasSignatureResolution(left.result) &&
hasSignatureResolution(right.result),
@@ -50,6 +50,14 @@ const sameMethodRows = (
left.method_rows.count === right.method_rows.count &&
left.method_rows.total === right.method_rows.total);
/** Returned type facts, rather than request spelling, own the observed scope. */
export const selectedDeclaringTypes = (
result: ManagedMemberInspection,
): ReadonlySet<string> | null =>
result.selection === null
? null
: new Set(result.types.map(({ full_name }) => full_name));
/** Whether both observations inspected the same declaring types. */
const sameSelection = (
left: ManagedMemberInspection,
@@ -1,4 +1,7 @@
import { hasCompleteMethodRows } from "./managedMemberComparisonCoverage.js";
import {
hasCompleteMethodRows,
selectedDeclaringTypes,
} from "./managedMemberComparisonCoverage.js";
import { digestCanonicalValue } from "../canonicalDigest.js";
import {
managedMemberInspectionSchema,
@@ -490,12 +493,15 @@ const groupBy = <Item>(
};
/** Whether a side's inventory observed members of this declaring type. */
const observedBy =
(side: ManagedMemberComparisonSide) =>
({ declaring_type }: { readonly declaring_type: string | null }): boolean =>
side.result.selection === null ||
(declaring_type !== null &&
side.result.selection.type_names.includes(declaring_type));
const observedBy = (side: ManagedMemberComparisonSide) => {
const types = selectedDeclaringTypes(side.result);
return ({
declaring_type,
}: {
readonly declaring_type: string | null;
}): boolean =>
types === null || (declaring_type !== null && types.has(declaring_type));
};
/**
* Pair only members whose declaring type both sides observed. A member outside
+16 -15
View File
@@ -29,7 +29,6 @@ import {
import {
parseTypes,
readTypeDefinitions,
type TypeRange,
} from "./ManagedMemberInspectorCore.js";
import { edgeTargets } from "./ManagedMethodSpecs.js";
import { managedTypeNameDigests } from "./ManagedTypeNameDigests.js";
@@ -124,26 +123,27 @@ const readMemberLayout = (bytes: Buffer, pe: ManagedPeLayout) => {
};
const selectTypes = (
ranges: readonly TypeRange[],
types: ManagedMemberInspection["types"],
typeNames: readonly string[] | undefined,
): {
readonly tokens: SelectedTypeTokens;
readonly selection: ManagedMemberInspection["selection"];
readonly unreadableNames: number;
} => {
if (typeNames === undefined)
return { tokens: null, selection: null, unreadableNames: 0 };
if (typeNames === undefined) return { tokens: null, selection: null };
const requested = new Set(typeNames);
const tokens = new Set<string>();
const matched = new Set<string>();
for (const range of ranges) {
if (range.fullName === null || !requested.has(range.fullName)) continue;
tokens.add(range.token);
matched.add(range.fullName);
for (const type of types) {
const nested = (type.flags & 0x7) >= 2;
const spellings = nested ? [type.full_name, type.name] : [type.full_name];
for (const name of spellings) {
if (!requested.has(name)) continue;
tokens.add(type.token);
matched.add(name);
}
}
return {
tokens,
unreadableNames: ranges.filter(({ fullName }) => fullName === null).length,
selection: {
type_names: [...typeNames],
unmatched_type_names: typeNames.filter((name) => !matched.has(name)),
@@ -198,12 +198,13 @@ export const inspectManagedMembersBytes = (
const identity = readManagedModuleIdentity(bytes, layout);
appendManagedParseIssues(issues, identity.issues);
const ranges = readTypeDefinitions(bytes, layout, issues, memberLists);
const {
tokens: selected,
selection,
unreadableNames,
} = selectTypes(ranges, typeNames);
const parsedTypes = parseTypes(bytes, layout, ranges);
const { tokens: selected, selection } = selectTypes(
parsedTypes.types,
typeNames,
);
const unreadableNames =
typeNames === undefined ? 0 : ranges.length - parsedTypes.types.length;
appendManagedParseIssues(issues, parsedTypes.issues);
const typeReferences = managedTypeReferences(bytes, layout, issues);
const signatureTypeName = managedTypeNameDigests(