Files
scriptc/packages/compiler/test/native-codegen-lowering.test.ts
T
Chris Tate cb94453647 feat(compiler): bootstrap the C emitter natively
- Compile the production C emitter and reproduce its output across native generations.
- Support the union operations, recursive spreads, and compression options needed by the emitter.
- Fix temporary ownership and verify the bootstrap and shared call operands with both backends and sanitizers.
2026-09-27 21:45:26 -05:00

78 lines
2.6 KiB
TypeScript

import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, test } from "vitest";
import { analyze } from "../src/index.js";
function diagnostics(source: string) {
const dir = mkdtempSync(join(process.platform === "win32" ? tmpdir() : "/tmp", "scriptc-native-lowering-"));
try {
const entry = join(dir, "main.ts");
writeFileSync(entry, source);
const { coverage } = analyze(entry, { dynamic: false });
expect(coverage.preflightFailed).toBe(false);
return coverage.diagnostics;
} finally {
rmSync(dir, { recursive: true, force: true });
}
}
for (const options of [
"{ level: 10 }",
"{ level: -2 }",
"{ level: 1.5 }",
"{ level: Number.NaN }",
"{ level }",
"{ level: 9, strategy: 1 }",
"{ level: 9, windowBits: 15 }",
"{ ...{ level: 9 } }",
"{ ['level']: 9 }",
]) {
test(`static zlib refuses unmodeled options ${options}`, () => {
const diags = diagnostics(`
import { deflateRawSync } from "node:zlib";
const level = 9;
console.log(deflateRawSync("payload", ${options}).length);
`);
expect(diags).toHaveLength(1);
expect(diags[0]!.code).toBe("SC2020");
expect(diags[0]!.message).toContain("deflateRawSync with these options");
expect(diags[0]!.hint).toContain("integer literal from -1 through 9");
});
}
test("compression-level support does not silently accept decompression options", () => {
const diags = diagnostics(`
import { inflateRawSync } from "node:zlib";
console.log(inflateRawSync(Buffer.from([3, 0]), { windowBits: 15 }).length);
`);
expect(diags).toHaveLength(1);
expect(diags[0]!.code).toBe("SC2020");
expect(diags[0]!.message).toContain("inflateRawSync with explicit options");
});
test("union writes keep the refusal for incompatible field storage", () => {
const diags = diagnostics(`
type Value = { kind: "text"; value: string } | { kind: "number"; value: number };
function write(value: Value): void { value.value = "changed"; }
write({ kind: "number", value: 1 });
`);
expect(diags).toHaveLength(1);
expect(diags[0]!.code).toBe("SC1090");
expect(diags[0]!.message).toContain("assignment to non-variables");
});
test("ordinary scalar union switches stay static", () => {
const diags = diagnostics(`
function choose(value: string | number): void {
switch (value) {
case "text": break;
case 1: break;
}
}
choose("text");
`);
// Ordinary scalar unions remain entirely static after control-flow changes.
expect(diags).toEqual([]);
});