fix(electron): retain nested bridge facts through wrapper resolution

Merge direct same-call nested member facts into symbolic wrapper results using canonical deduplication and ordering. Preserve unknown spread coverage rather than losing known member paths.

Validation: bounded source cases and public CLI/stdio MCP spread/no-spread controls. The existing 125,000-member stress case exceeded the 384 MiB local cap and was stopped without increasing the limit; that capacity case remains unverified locally.

Fixes #3212
This commit is contained in:
morluto committed 2026-10-14 16:54:08 +08:00
1 parent 81f7638203
commit 0351328e54
3 files changed
+82 -1

No files matched your search

@@ -36,6 +36,7 @@ import {
symbolicDefiniteExit,
symbolicLogicalRight,
} from "./javascriptSymbolicControlFlow.js";
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
const callLabel = (node: t.Node): string =>
t.isSequenceExpression(node)
@@ -410,7 +411,12 @@ export const collectElectronWrappedCallPaths = (
api_key_expression: null,
api_status: "dynamic" as const,
resolution_basis: "wrapper-substitution" as const,
members,
// The direct syntax pass recursively retains literal dotted paths. The
// symbolic resolver enumerates only immediate object keys, so its
// replacement must not erase paths already established at this call.
members: [
...new Set([...(existing?.value.members ?? []), ...members]),
].sort(compareUnicodeCodePoints),
unknown_members: resolver.unknownMembers(object),
module_key: null,
location,