Record todo bailouts in CodegenReactiveFunction

Went over this pass and converted any todos to bailouts, otherwise we continue 
to throw an invariant if there's an internal error
This commit is contained in:
Lauren Tan
2023-02-01 14:49:47 -05:00
parent 1baf22a421
commit 8a0d3169fd
6 changed files with 51 additions and 27 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ export enum ErrorSeverity {
export type CompilerErrorOptions = {
reason: string;
severity: ErrorSeverity;
nodePath: AnyNodePath;
nodePath: AnyNodePath | null;
};
type AnyNodePath = NodePath<Node | null | undefined>;
type CompilerErrorKind = typeof InvalidInputError | typeof TodoError;
+2 -6
View File
@@ -46,11 +46,7 @@ export type CompilerPipelineValue =
export function* run(
func: NodePath<t.FunctionDeclaration>
): Generator<CompilerPipelineValue, t.Function> {
const lowering = lower(func).orElse((error) => {
throw error;
});
const hir = lowering.unwrap();
const hir = lower(func).unwrap();
yield log({ kind: "hir", name: "HIR", value: hir });
mergeConsecutiveBlocks(hir);
@@ -153,7 +149,7 @@ export function* run(
value: reactiveFunction,
});
const ast = codegenReactiveFunction(reactiveFunction);
const ast = codegenReactiveFunction(reactiveFunction).unwrap();
yield log({ kind: "ast", name: "Codegen", value: ast });
return ast;
@@ -7,6 +7,7 @@
import * as t from "@babel/types";
import invariant from "invariant";
import { CompilerError, ErrorSeverity } from "../CompilerError";
import {
BlockId,
GeneratedSource,
@@ -24,12 +25,12 @@ import {
ReactiveValue,
SourceLocation,
} from "../HIR/HIR";
import { todoInvariant } from "../Utils/todo";
import { Err, Ok, Result } from "../Utils/Result";
import { assertExhaustive } from "../Utils/utils";
export function codegenReactiveFunction(
fn: ReactiveFunction
): t.FunctionDeclaration {
): Result<t.FunctionDeclaration, CompilerError> {
const cx = new Context();
const params = fn.params.map((param) => convertIdentifier(param.identifier));
const body = codegenBlock(cx, fn.body);
@@ -56,13 +57,20 @@ export function codegenReactiveFunction(
])
);
}
return createFunctionDeclaration(
fn.loc,
fn.id !== null ? convertIdentifier(fn.id) : null,
params,
body,
fn.generator,
fn.async
if (cx.errors.hasErrors()) {
return Err(cx.errors);
}
return Ok(
createFunctionDeclaration(
fn.loc,
fn.id !== null ? convertIdentifier(fn.id) : null,
params,
body,
fn.generator,
fn.async
)
);
}
@@ -70,6 +78,7 @@ class Context {
#nextCacheIndex: number = 0;
#identifiers: Set<Identifier> = new Set();
temp: Temporaries = new Map();
errors: CompilerError = new CompilerError();
get nextCacheIndex(): number {
return this.#nextCacheIndex++;
@@ -711,17 +720,22 @@ function codegenInstructionValue(
} else {
if (t.isVariableDeclaration(stmt)) {
const declarator = stmt.declarations[0];
todoInvariant(
false,
`Cannot declare variables in a value block, tried to declare '${
cx.errors.push({
reason: `(CodegenReactiveFunction::codegenInstructionValue) Cannot declare variables in a value block, tried to declare '${
(declarator.id as t.Identifier).name
}'`
);
}'`,
severity: ErrorSeverity.Todo,
nodePath: null,
});
return t.stringLiteral(`TODO handle ${declarator.id}`);
} else {
cx.errors.push({
reason: `(CodegenReactiveFunction::codegenInstructionValue) Handle conversion of ${stmt.type} to expression`,
severity: ErrorSeverity.Todo,
nodePath: null,
});
return t.stringLiteral(`TODO handle ${stmt.type}`);
}
todoInvariant(
false,
`Handle conversion of ${stmt.type} to expression`
);
}
});
if (expressions.length === 0) {
@@ -788,7 +802,6 @@ function codegenValue(
}
function codegenPlace(cx: Context, place: Place): t.Expression {
todoInvariant(place.kind === "Identifier", "support scope values");
let tmp = cx.temp.get(place.identifier.id);
if (tmp != null) {
return tmp;
+6
View File
@@ -167,6 +167,9 @@ class OkImpl<T> implements Result<T, never> {
}
unwrapErr(): never {
if (this.val instanceof Error) {
throw this.val;
}
throw new Error(`Can't unwrap \`Ok\` to \`Err\`: ${this.val}`);
}
}
@@ -227,6 +230,9 @@ class ErrImpl<E> implements Result<never, E> {
}
unwrap(): never {
if (this.val instanceof Error) {
throw this.val;
}
throw new Error(`Can't unwrap \`Err\` to \`Ok\`: ${this.val}`);
}
@@ -1,3 +1,4 @@
import { CompilerError } from "../CompilerError";
import { Err, Ok, Result } from "../Utils/Result";
function addMax10(a: number, b: number): Result<number, string> {
@@ -9,6 +10,8 @@ function onlyFoo(foo: string): Result<string, string> {
return foo === "foo" ? Ok(foo) : Err(foo);
}
class CustomDummyError extends Error {}
describe("Result", () => {
test(".map", () => {
expect(addMax10(1, 1).map((n) => n * 2)).toEqual(Ok(4));
@@ -107,6 +110,9 @@ describe("Result", () => {
}).toThrowErrorMatchingInlineSnapshot(
`"Can't unwrap \`Err\` to \`Ok\`: 20 is too high"`
);
expect(() => {
Err(new CustomDummyError("oops")).unwrap();
}).toThrowErrorMatchingInlineSnapshot(`"oops"`);
});
test(".unwrapOr", () => {
@@ -126,5 +132,8 @@ describe("Result", () => {
`"Can't unwrap \`Ok\` to \`Err\`: 2"`
);
expect(addMax10(10, 10).unwrapErr()).toEqual("20 is too high");
expect(() => {
Ok(new CustomDummyError("oops")).unwrapErr();
}).toThrowErrorMatchingInlineSnapshot(`"oops"`);
});
});
@@ -19,7 +19,7 @@ function f(reader) {
## Error
```
TODO: Cannot declare variables in a value block, tried to declare 'value$0'
[ReactForget] Todo: (CodegenReactiveFunction::codegenInstructionValue) Cannot declare variables in a value block, tried to declare 'value$0'
```