72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
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");
|
||
|
|
});
|