fix(javascript): preserve guarded factory fallthrough (#4341)

Preserve per-exit factory initialization and shared export facts.
Keep capture/caller boundaries, call-kind semantics and conditional
registration evidence consistent through CLI and MCP.

Fixes #3963
This commit is contained in:
Ysopwnable authored and GitHub committed 2026-10-16 13:10:49 +08:00
1 parent 8ab5024397
commit 2c7583599b
8 files changed
+1297 -136

No files matched your search

@@ -4,6 +4,10 @@ import type * as t from "@babel/types";
export interface SymbolicEnvironment {
readonly values: ReadonlyMap<string, SymbolicValue>;
readonly parent?: SymbolicEnvironment;
/** Stable activation identity, shared by its completed views. */
readonly activation?: object;
/** Known synchronous caller, distinct from lexical capture. */
readonly caller?: SymbolicEnvironment;
/** Source point at which the current function is being symbolically executed. */
readonly point?: t.Node;
/** Lexical function scope for point-sensitive local initializer checks. */
@@ -12,6 +16,8 @@ export interface SymbolicEnvironment {
readonly scopeNode?: t.Function;
/** Completion boundary proven for this captured activation. */
readonly completedAt?: t.Node;
/** Shared completion facts must remain unchanged through this later exit. */
readonly commonThrough?: t.Node;
}
export interface SymbolicCondition {
@@ -62,6 +68,12 @@ export type SymbolicValue = (
readonly values: ReadonlyMap<string, SymbolicValue>;
}
| { readonly kind: "union"; readonly values: readonly SymbolicValue[] }
| { readonly kind: "iterator" }
| {
readonly kind: "promise";
readonly value: SymbolicValue;
readonly returnPoint?: t.Node;
}
| SymbolicFunction
) &
SymbolicMetadata;
@@ -90,9 +102,16 @@ export const symbolicTruth = (value: SymbolicValue): boolean | undefined => {
}
return value.kind === "literal"
? Boolean(value.value)
: ["function", "object", "namespace", "array", "record", "loader"].includes(
value.kind,
)
: [
"function",
"object",
"namespace",
"array",
"record",
"loader",
"promise",
"iterator",
].includes(value.kind)
? true
: undefined;
};