Files
scriptc/packages/compiler/test/internal-compiler-error.test.ts
Chris Tate 469efdd7f0 refactor: clarify compiler module boundaries (#232)
* refactor: clarify compiler module boundaries

- Rename backend, frontend, IR, and cache modules for explicit ownership.
- Split native cache/vendor and frontend shared concerns into focused modules.
- Expand compiler context names and refresh imports, tests, and documentation.

* fix: preserve renamed compiler interfaces
2026-08-23 20:16:13 -05:00

61 lines
2.2 KiB
TypeScript

import { expect, test } from "vitest";
import { emitCModule, InternalCompilerError } from "../src/index.js";
import { resolveCc } from "../src/backend/native-toolchain.js";
import { deserializeModule } from "../src/ir/serialize.js";
import { fibModule } from "./fixtures/fib-ir.js";
function captureError(run: () => unknown): Error {
try {
run();
} catch (error) {
if (error instanceof Error) return error;
throw error;
}
throw new Error("expected the operation to throw");
}
test("InternalCompilerError is a public, identifiable compiler failure", () => {
const cause = new Error("filesystem failure");
const error = new InternalCompilerError("emitter bug: broken invariant", { cause });
expect(error).toBeInstanceOf(Error);
expect(error).toBeInstanceOf(InternalCompilerError);
expect(error.name).toBe("InternalCompilerError");
expect(error.message).toBe("emitter bug: broken invariant");
expect(error.cause).toBe(cause);
});
test("emitter invariant failures preserve their message and public type", () => {
const malformed = structuredClone(fibModule);
const main = malformed.functions.find((fn) => fn.name === "__main")!;
const statement = main.body[0]!;
if (statement.kind !== "exprStmt" || statement.expr.kind !== "intrinsic") {
throw new Error("fixture lost its console.log call");
}
statement.expr.args[0] = {
kind: "closure",
fnName: "missing",
captures: [],
type: { kind: "func", params: [], returnType: { kind: "void" } },
loc: statement.loc,
};
expect(() => emitCModule(malformed)).toThrow(
expect.objectContaining({
constructor: InternalCompilerError,
message: "emitter bug: closure over unknown function missing",
name: "InternalCompilerError",
}),
);
});
test("caller configuration and input failures are not internal compiler errors", () => {
const configuration = captureError(() => resolveCc({ SCRIPTC_CC: "unsupported" }));
expect(configuration.message).toContain("unknown SCRIPTC_CC");
expect(configuration).not.toBeInstanceOf(InternalCompilerError);
const externalIr = captureError(() => deserializeModule('{"irVersion": 5}'));
expect(externalIr.message).toContain("IR version mismatch");
expect(externalIr).not.toBeInstanceOf(InternalCompilerError);
});