mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
- Compile the production validator and exercise native IR construction and validation on C and LLVM. - Preserve Error causes, wider callbacks, and discriminated JSON layouts in static programs. - Version the IR and runtime ABI and cover the new compiler paths with differential and sanitizer tests.
67 lines
2.9 KiB
TypeScript
67 lines
2.9 KiB
TypeScript
export {};
|
|
|
|
class CompilerError extends Error {
|
|
constructor(message?: string, options?: ErrorOptions) {
|
|
super(message, options);
|
|
this.name = "CompilerError";
|
|
}
|
|
}
|
|
class Derived extends CompilerError {}
|
|
class Inherited extends TypeError {}
|
|
class DeepInherited extends Inherited {}
|
|
|
|
function report(label: string, error: Error): void {
|
|
console.log(label, error.name, JSON.stringify(error.message), "cause" in error, error.cause);
|
|
}
|
|
function make(message?: string, options?: ErrorOptions): CompilerError {
|
|
return new CompilerError(message, options);
|
|
}
|
|
report("absent", make());
|
|
report("empty", make("", {}));
|
|
report("explicit undefined", make(undefined, { cause: undefined }));
|
|
report("null", make("null cause", { cause: null }));
|
|
report("number", make("number cause", { cause: 42 }));
|
|
report("boolean", make("boolean cause", { cause: false }));
|
|
report("string", make("string cause", { cause: "root" }));
|
|
report("derived", new Derived("inherited", { cause: 7 }));
|
|
report("builtin chain", new DeepInherited(undefined, { cause: "root" }));
|
|
report("default chain", new DeepInherited());
|
|
report("Error", new Error("message", { cause: "error" }));
|
|
report("TypeError", new TypeError("message", { cause: "type" }));
|
|
report("RangeError", new RangeError("message", { cause: "range" }));
|
|
report("SyntaxError", new SyntaxError("message", { cause: "syntax" }));
|
|
|
|
// Forwarding the standard library interface keeps missing and undefined
|
|
// distinct even when the options travel through nullable control flow.
|
|
function forward(flag: number): Error {
|
|
let options: ErrorOptions | undefined;
|
|
if (flag === 1) options = {};
|
|
if (flag === 2) options = { cause: undefined };
|
|
if (flag === 3) options = { cause: "present" };
|
|
return new Derived(undefined, options);
|
|
}
|
|
for (let flag = 0; flag < 4; flag++) report("forward " + flag, forward(flag));
|
|
|
|
const original: Error = new RangeError("underlying");
|
|
const wrapped = new CompilerError("wrapper", { cause: original });
|
|
const cause = wrapped.cause;
|
|
console.log("identity", cause instanceof Error && cause === original);
|
|
if (cause instanceof Error) console.log("cause class", cause.name, cause.message, cause instanceof RangeError);
|
|
console.log("class", wrapped instanceof Error, wrapped instanceof CompilerError, wrapped.toString());
|
|
|
|
// Constructor arguments run exactly once, left-to-right, before super's
|
|
// field initializers and the rest of the subclass body.
|
|
let events = "";
|
|
function message(): string { events += "message;"; return "value"; }
|
|
function options(): ErrorOptions { events += "options;"; return { cause: 5 }; }
|
|
function field(): number { events += "field;"; return 9; }
|
|
class Ordered extends Error {
|
|
value = field();
|
|
constructor(message?: string, options?: ErrorOptions) {
|
|
super(message, options);
|
|
events += "body;";
|
|
}
|
|
}
|
|
const ordered = new Ordered(message(), options());
|
|
console.log("order", events, ordered.message, ordered.cause, ordered.value);
|