Fix multi error emission on unknown modules

This commit is contained in:
nora 2024-06-01 14:20:02 +02:00
parent 1e97275cf2
commit d6123836e8
8 changed files with 2998 additions and 11 deletions

View file

@ -20,13 +20,15 @@ export type PkgLoader = (
* dependencies (which also use the same context) do not care about that.
*/
export class GlobalContext {
public error: ErrorHandler = new ErrorHandler();
public error: ErrorHandler;
public finalizedPkgs: Pkg<Final>[] = [];
// For cycle detection.
public pkgsBeingLoaded: Set<string> = new Set<string>();
public pkgId: Ids = new Ids();
constructor(public opts: Options, public pkgLoader: PkgLoader) {}
constructor(public opts: Options, public pkgLoader: PkgLoader) {
this.error = new ErrorHandler(opts.treatErrAsBug);
}
public findItem<P extends Phase>(
id: ItemId,
@ -82,6 +84,7 @@ export type Options = {
debug: Set<string>;
noOutput: boolean;
noStd: boolean;
treatErrAsBug: boolean;
};
export function parseArgs(hardcodedInput: string): Options {
@ -91,6 +94,7 @@ export function parseArgs(hardcodedInput: string): Options {
let debug = new Set<string>();
let noOutput = false;
let noStd = false;
let treatErrAsBug = false;
if (process.argv.length > 2) {
filename = process.argv[2];
@ -122,6 +126,9 @@ export function parseArgs(hardcodedInput: string): Options {
if (process.argv.some((arg) => arg === "--no-std")) {
noStd = true;
}
if (process.argv.some((arg) => arg === "--treat-err-as-bug")) {
treatErrAsBug = true;
}
} else {
filename = "<hardcoded>";
input = hardcodedInput;
@ -142,5 +149,6 @@ export function parseArgs(hardcodedInput: string): Options {
debug,
noOutput,
noStd,
treatErrAsBug,
};
}

View file

@ -39,12 +39,19 @@ export type Emitter = (string: string) => void;
export class ErrorHandler {
private errors: CompilerError[] = [];
private treatErrAsBug: boolean;
constructor(
treatErrAsBug: boolean,
private emitter = (msg: string) => globalThis.console.error(msg),
) {}
) {
this.treatErrAsBug = treatErrAsBug;
}
public emitError(err: CompilerError): ErrorEmitted {
if (this.treatErrAsBug) {
throw new Error(`--treat-err-as-bug: ${err.msg}`);
}
renderDiagnostic(this.emitter, err, (msg) => chalk.red(`error: ${msg}`));
this.errors.push(err);
return ERROR_EMITTED;

View file

@ -4,7 +4,7 @@ import { tokenize } from "./lexer";
it("should tokenize an emtpy function", () => {
const input = `function hello() = ;`;
const tokens = tokenize(new ErrorHandler(), { content: input });
const tokens = tokenize(new ErrorHandler(false), { content: input });
if (!tokens.ok) unreachable("lexer error");
expect(tokens.tokens).toMatchSnapshot();
@ -13,7 +13,7 @@ it("should tokenize an emtpy function", () => {
it("should tokenize hello world", () => {
const input = `print("hello world")`;
const tokens = tokenize(new ErrorHandler(), { content: input });
const tokens = tokenize(new ErrorHandler(false), { content: input });
if (!tokens.ok) unreachable("lexer error");
expect(tokens.tokens).toMatchSnapshot();

View file

@ -276,8 +276,7 @@ function resolveModule(
const lhs = this.expr(expr.lhs);
if (lhs.kind === "ident" || lhs.kind === "path") {
const res =
lhs.kind === "ident" ? resolveIdent(lhs.value) : lhs.value.res;
const res = lhs.value.res;
const segments =
lhs.kind === "ident" ? [lhs.value.name] : lhs.segments;
@ -325,7 +324,7 @@ function resolveModule(
}
}
return superFoldExpr(expr, this);
return { ...expr, lhs };
}
default: {
return superFoldExpr(expr, this);

View file

@ -7,7 +7,7 @@ const SPAN: Span = Span.startOfFile({ content: "" });
const dummyEmitter: Emitter = () => {};
it("should infer types across assignments", () => {
const infcx = new InferContext(new ErrorHandler(dummyEmitter));
const infcx = new InferContext(new ErrorHandler(false, dummyEmitter));
const a = infcx.newVar();
const b = infcx.newVar();
@ -30,7 +30,7 @@ it("should infer types across assignments", () => {
it("should conflict assignments to resolvable type vars", () => {
let errorLines = 0;
const emitter = () => (errorLines += 1);
const infcx = new InferContext(new ErrorHandler(emitter));
const infcx = new InferContext(new ErrorHandler(false, emitter));
const a = infcx.newVar();
const b = infcx.newVar();
@ -46,7 +46,7 @@ it("should conflict assignments to resolvable type vars", () => {
});
it("should not cycle", () => {
const infcx = new InferContext(new ErrorHandler(dummyEmitter));
const infcx = new InferContext(new ErrorHandler(false, dummyEmitter));
const a = infcx.newVar();
const b = infcx.newVar();

View file

@ -0,0 +1,3 @@
function main() = (
let _l = list.new();
);

View file

@ -0,0 +1,4 @@
error: cannot find list
--> $DIR/module_not_found.nil:2
2 | let _l = list.new();
^^^^

2966
yarn.lock Normal file

File diff suppressed because it is too large Load diff