mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 08:25:02 +01:00
Fix multi error emission on unknown modules
This commit is contained in:
parent
1e97275cf2
commit
d6123836e8
8 changed files with 2998 additions and 11 deletions
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
3
ui-tests/resolve/module_not_found.nil
Normal file
3
ui-tests/resolve/module_not_found.nil
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
function main() = (
|
||||
let _l = list.new();
|
||||
);
|
||||
4
ui-tests/resolve/module_not_found.stderr
Normal file
4
ui-tests/resolve/module_not_found.stderr
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
error: cannot find list
|
||||
--> $DIR/module_not_found.nil:2
|
||||
2 | let _l = list.new();
|
||||
^^^^
|
||||
Loading…
Add table
Add a link
Reference in a new issue