Files
scriptc/packages/compiler/test/format-float-arguments.test.ts
T
Chris Tate 29f21ffeca Evaluate a %f boolean or unit argument without lowering it twice
The util.format %f branch for boolean and unit arguments discarded the
lowered value and lowered the argument node again as a statement, so
anything lowering builds for the argument (lifted array helpers,
closures) was built twice, one copy dead. It now evaluates the value it
already lowered as a statement, and drops it when evaluating it has no
observable effect.

The same branch now also covers void calls and null | undefined unions,
which Node formats as NaN like undefined and null; they were refused.
2026-10-15 21:58:33 -05:00

36 lines
1.4 KiB
TypeScript

import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, test } from "vitest";
import { compile, deserializeModule, validateModule } from "../src/index.js";
test("util.format %f lowers a boolean argument once", async () => {
const dir = await mkdtemp(join(tmpdir(), "scriptc-format-float-"));
try {
const entry = join(dir, "main.ts");
const outPath = join(dir, "main.ir.json");
await writeFile(
entry,
[
'import { format } from "node:util";',
"const xs = [1, 2, 3];",
'console.log(format("%f %f", xs.some((x) => x > 2), xs.every((x) => x > 0)));',
].join("\n"),
);
const result = await compile(entry, { outDir: dir, outPath, outputKind: "ir" });
if (!result.ok)
throw new Error(result.diagnostics.map((d) => `${d.code}: ${d.message}`).join("\n"));
const mod = deserializeModule(await readFile(outPath, "utf8"));
expect(validateModule(mod)).toEqual([]);
// One lifted helper per argument: the evaluated-for-effect statement
// reuses the lowered value instead of lowering the argument again.
const helpers = mod.functions
.map((f) => f.name)
.filter((name) => name.startsWith("%arr."))
.map((name) => name.replace(/\.\d+$/, ""));
expect(helpers).toEqual(["%arr.some", "%arr.every"]);
} finally {
await rm(dir, { recursive: true, force: true });
}
});