Improve debugging for - errors
Joe Savona committed
Feb 1, 2023 at 09:42 UTC
c2dda028fd4dd42fef7b1dc5d154b0059d5105af
3 files changed
+36
-6
compiler/forget/src/CompilerError.ts
+25
-2
@@ -1,11 +1,13 @@
1
import { Node, NodePath } from "@babel/traverse";
2
-import { SourceLocation } from "@babel/types";
2
+import { SourceLocation as BabelSourceLocation } from "@babel/types";
3
+import { SourceLocation } from "./HIR";
4
import { ExtractClassProperties } from "./Utils/types";
5
import { assertExhaustive } from "./Utils/utils";
6
7
export enum ErrorSeverity {
8
InvalidInput = "InvalidInput",
9
Todo = "Todo",
10
+ Invariant = "Invariant",
11
}
12
13
export type CompilerErrorOptions = {
@@ -23,6 +25,8 @@ function mapSeverityToErrorCtor(severity: ErrorSeverity): CompilerErrorKind {
25
return InvalidInputError;
26
case ErrorSeverity.Todo:
27
return TodoError;
28
+ case ErrorSeverity.Invariant:
29
+ return InvariantError;
30
default:
31
assertExhaustive(severity, `Unhandled severity level: ${severity}`);
32
}
@@ -39,6 +43,12 @@ class TodoError extends Error {
43
this.name = `${ErrorSeverity.Todo}Error`;
44
}
45
}
46
+class InvariantError extends Error {
47
+ constructor(message: string) {
48
+ super(message);
49
+ this.name = `${ErrorSeverity.Invariant}Error`;
50
+ }
51
+}
52
53
export function tryPrintCodeFrame(
54
options: CompilerErrorOptions
@@ -64,7 +74,7 @@ export class CompilerErrorDetail {
74
reason: string;
75
severity: ErrorSeverity;
76
codeframe: string | null;
67
- loc: SourceLocation | null;
77
+ loc: BabelSourceLocation | null;
78
79
constructor(options: CompilerErrorDetailOptions) {
80
this.reason = options.reason;
@@ -92,6 +102,19 @@ export class CompilerErrorDetail {
102
export class CompilerError extends Error {
103
details: CompilerErrorDetail[] = [];
104
105
+ static invariant(reason: string, loc: SourceLocation): never {
106
+ const errors = new CompilerError();
107
+ errors.pushErrorDetail(
108
+ new CompilerErrorDetail({
109
+ codeframe: null,
110
+ loc: typeof loc === "symbol" ? null : loc,
111
+ reason,
112
+ severity: ErrorSeverity.Invariant,
113
+ })
114
+ );
115
+ throw errors;
116
+ }
117
+
118
constructor(...args: any[]) {
119
super(...args);
120
}
compiler/forget/src/HIR/BuildHIR.ts
+2
@@ -1044,6 +1044,8 @@ function lowerExpression(
1044
const operator = expr.node.operator;
1045
1046
if (builder.currentBlockKind() === "value") {
1047
+ // try lowering the RHS in case it also contains errors
1048
+ lowerExpressionToPlace(builder, expr.get("right"));
1049
builder.errors.push({
1050
reason: `(BuildHIR::lowerExpression) Handle AssignmentExpression within a LogicalExpression or ConditionalExpression`,
1051
severity: ErrorSeverity.Todo,
compiler/forget/src/Inference/InferReferenceEffects.ts
+9
-4
@@ -6,6 +6,7 @@
6
*/
7
8
import invariant from "invariant";
9
+import { CompilerError } from "../CompilerError";
10
import {
11
BasicBlock,
12
BlockId,
@@ -199,10 +200,14 @@ class Environment {
200
const kind = this.#values.get(value)!;
201
mergedKind = mergedKind !== null ? mergeValues(mergedKind, kind) : kind;
202
}
202
- invariant(
203
- mergedKind !== null,
204
- `Expected at least one value at ${printPlace(place)}`
205
- );
203
+ if (mergedKind === null) {
204
+ CompilerError.invariant(
205
+ `InferReferenceEffects::kind: Expected at least one value at '${printPlace(
206
+ place
207
+ )}'`,
208
+ place.loc
209
+ );
210
+ }
211
return mergedKind;
212
}
213