fix(javascript): preserve effective child-process stdio options (#4336)

* fix(javascript): preserve effective child-process stdio options

* fix(javascript): retain proven callbacks and primitive stdio keys

* fix(javascript): preserve argv shapes and nullish spreads

* fix(javascript): bound callable proofs and retain exposed binding uncertainty

* test(javascript): keep callback acceptance within transport budget

* test(javascript): inspect application coverage for callback proof limits

* fix(javascript): keep spread command argument slots uncertain

* fix(javascript): bound mapped argument content proofs

* fix(javascript): distinguish erased declarations from runtime shadows

* fix(javascript): prove runtime module context before binding isolation

* fix(javascript): share erased declaration and opaque scope proofs

* fix(javascript): keep lowered enum scopes opaque

* fix(javascript): narrow stdio proofs and consolidate regressions

* perf(javascript): reuse lexical references for child shapes

* fix(javascript): retain CommonJS child argument context

* fix(javascript): keep Annex B affected child arguments unknown

* fix(javascript): recognize value import-equals runtime modules

* fix(javascript): retain exact stdio through module and primitive syntax

* fix(javascript): bound inline spread property resolution

* fix(javascript): distinguish copied methods from getters
This commit is contained in:
星闌
2026-10-17 15:51:55 +08:00
committed by GitHub
parent 0cd4eafd61
commit de9371b85d
18 changed files with 1114 additions and 93 deletions
@@ -1,6 +1,22 @@
import { expect, it } from "vitest";
import { analyzeJavaScriptSemantics } from "./javascriptSemanticAnalysis.js";
it("resolves void keys while retaining their calls and binding writes", () => {
const ir = analyzeJavaScriptSemantics(`
import {spawn} from "node:child_process";
const routes = {[void sideEffect()]: "HOME"};
const root = routes[void 0];
let argv=[]; const changed = {[void (argv={})]: 1};
spawn("changed",argv,{stdio:"inherit"});
`);
expect(ir.bindings.find(({ name }) => name === "root")?.value).toEqual({
status: "literal",
value: "HOME",
});
expect(ir.references.some(({ name }) => name === "sideEffect")).toBe(true);
expect(ir.childProcessSpawns[0]?.stdioMode).toBe("dynamic");
});
it.each([
"const routes = {'': 'HOME'}; const root = routes[''];",
"const routes = {['']: 'HOME'}; const root = routes[''];",