mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
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:
@@ -0,0 +1,72 @@
|
||||
import * as t from "@babel/types";
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
semanticStaticPropertyKey,
|
||||
staticObjectProperty,
|
||||
} from "./javascriptAstValues.js";
|
||||
import { SEMANTIC_EXPRESSION_DEPTH_LIMIT } from "./javascriptSemanticResourceLimits.js";
|
||||
|
||||
it("copies ordinary members without proving requested methods or getter effects", () => {
|
||||
const method = (name: string, computed = false) =>
|
||||
t.objectMethod(
|
||||
"method",
|
||||
t.identifier(name),
|
||||
[],
|
||||
t.blockStatement([]),
|
||||
computed,
|
||||
);
|
||||
const getter = t.objectMethod(
|
||||
"get",
|
||||
t.identifier("helper"),
|
||||
[],
|
||||
t.blockStatement([]),
|
||||
);
|
||||
const setter = t.objectMethod(
|
||||
"set",
|
||||
t.identifier("helper"),
|
||||
[t.identifier("value")],
|
||||
t.blockStatement([]),
|
||||
);
|
||||
for (const [member, status] of [
|
||||
[method("helper"), "explicit"],
|
||||
[setter, "explicit"],
|
||||
[method("stdio"), "dynamic"],
|
||||
[getter, "dynamic"],
|
||||
[method("key", true), "dynamic"],
|
||||
] as const) {
|
||||
const object = t.objectExpression([
|
||||
t.objectProperty(t.identifier("stdio"), t.stringLiteral("inherit")),
|
||||
t.spreadElement(t.objectExpression([member])),
|
||||
]);
|
||||
expect(staticObjectProperty(object, "stdio").status).toBe(status);
|
||||
}
|
||||
});
|
||||
|
||||
it("limits unary-plus keys to transparent numeric literals", () => {
|
||||
const wrapped = t.tsAsExpression(t.numericLiteral(1), t.tsNumberKeyword());
|
||||
expect(semanticStaticPropertyKey(t.unaryExpression("+", wrapped), true)).toBe(
|
||||
"1",
|
||||
);
|
||||
for (const argument of [
|
||||
t.stringLiteral("1"),
|
||||
t.bigIntLiteral(1n),
|
||||
t.identifier("input"),
|
||||
])
|
||||
expect(
|
||||
semanticStaticPropertyKey(t.unaryExpression("+", argument), true),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("bounds nested inline object spreads without losing a shallow final property", () => {
|
||||
let object = t.objectExpression([
|
||||
t.objectProperty(t.identifier("stdio"), t.stringLiteral("inherit")),
|
||||
]);
|
||||
for (let depth = 0; depth < SEMANTIC_EXPRESSION_DEPTH_LIMIT; depth++)
|
||||
object = t.objectExpression([t.spreadElement(object)]);
|
||||
expect(staticObjectProperty(object, "stdio").status).toBe("explicit");
|
||||
expect(
|
||||
staticObjectProperty(t.objectExpression([t.spreadElement(object)]), "stdio")
|
||||
.status,
|
||||
).toBe("dynamic");
|
||||
});
|
||||
Reference in New Issue
Block a user