@samitouri / QOS-React-2 / commits / e7e67f335a

Use CompilerError.invariant consistently

This PR updates all current usages of invariant to CompilerError.invariant along with any available locs

Lauren Tan committed Jun 22, 2023 at 10:18 UTC e7e67f335adea5a24ff59a467b22b92702350a5e
25 files changed +313 -202
compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+27 -18
@@ -8,7 +8,6 @@
8 import { NodePath, Scope } from "@babel/traverse";
9 import * as t from "@babel/types";
10 import { Expression } from "@babel/types";
11 -import invariant from "invariant";
11 import { CompilerError, ErrorSeverity } from "../CompilerError";
12 import { Err, Ok, Result } from "../Utils/Result";
13 import { assertExhaustive } from "../Utils/utils";
@@ -769,9 +768,10 @@ function lowerStatement(
768 case "FunctionDeclaration": {
769 const stmt = stmtPath as NodePath<t.FunctionDeclaration>;
770 stmt.skip();
772 - invariant(
771 + CompilerError.invariant(
772 stmt.get("id").type === "Identifier",
774 - "function declarations must have a name"
773 + "function declarations must have a name",
774 + stmt.node.loc ?? null
775 );
776 const id = stmt.get("id") as NodePath<t.Identifier>;
777
@@ -795,9 +795,10 @@ function lowerStatement(
795 ),
796 ])
797 );
798 - invariant(
798 + CompilerError.invariant(
799 desugared.length === 1,
800 - "only one declaration is created from desugaring function declaration"
800 + "only one declaration is created from desugaring function declaration",
801 + stmt.node.loc ?? null
802 );
803 lowerStatement(builder, desugared.at(0)!);
804 return;
@@ -843,9 +844,10 @@ function lowerStatement(
844 let test: Place;
845 if (left.isVariableDeclaration()) {
846 const declarations = left.get("declarations");
846 - invariant(
847 + CompilerError.invariant(
848 declarations.length === 1,
848 - `Expected only one declaration in the init of a ForOfStatement, got ${declarations.length}`
849 + `Expected only one declaration in the init of a ForOfStatement, got ${declarations.length}`,
850 + left.node.loc ?? null
851 );
852 const id = declarations[0].get("id");
853 const nextIterableOf = lowerValueToTemporary(builder, {
@@ -1517,7 +1519,11 @@ function lowerExpression(
1519 });
1520 }
1521 } else {
1520 - invariant(namePath.isJSXNamespacedName(), "Refinement");
1522 + CompilerError.invariant(
1523 + namePath.isJSXNamespacedName(),
1524 + "Refinement",
1525 + namePath.node.loc ?? null
1526 + );
1527 const namespace = namePath.node.namespace.name;
1528 const name = namePath.node.name.name;
1529 propName = `${namespace}:${name}`;
@@ -1586,9 +1592,10 @@ function lowerExpression(
1592 });
1593 return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
1594 }
1589 - invariant(
1595 + CompilerError.invariant(
1596 expr.get("quasi").get("quasis").length == 1,
1591 - "there should be only one quasi as we don't support interpolations yet"
1597 + "there should be only one quasi as we don't support interpolations yet",
1598 + expr.node.loc ?? null
1599 );
1600 const value = expr.get("quasi").get("quasis").at(0)!.node.value;
1601 if (value.raw !== value.cooked) {
@@ -1836,7 +1843,7 @@ function lowerOptionalMemberExpression(
1843 loc,
1844 };
1845 });
1839 - invariant(object !== null, "Satisfy type checker");
1846 + CompilerError.invariant(object !== null, "Satisfy type checker", null);
1847
1848 // block to evaluate if the callee is non-null/undefined. arguments are lowered in this block to preserve
1849 // the semantic of conditional evaluation depending on the callee
@@ -2268,10 +2275,10 @@ function lowerJsxMemberExpression(
2275 if (object.isJSXMemberExpression()) {
2276 objectPlace = lowerJsxMemberExpression(builder, object);
2277 } else {
2271 - invariant(
2278 + CompilerError.invariant(
2279 object.isJSXIdentifier(),
2273 - "TypeScript refinement fail: expected 'JsxIdentifier', got '%s'",
2274 - object.node.type
2280 + `TypeScript refinement fail: expected 'JsxIdentifier', got '${object.node.type}'`,
2281 + object.node.loc ?? null
2282 );
2283 objectPlace = lowerIdentifier(builder, object);
2284 }
@@ -2303,9 +2310,10 @@ function lowerJsxElement(
2310 if (expression.isJSXEmptyExpression()) {
2311 return null;
2312 } else {
2306 - invariant(
2313 + CompilerError.invariant(
2314 expression.isExpression(),
2308 - `(BuildHIR::lowerJsxElement) Expected Expression but found ${expression.type}!`
2315 + `(BuildHIR::lowerJsxElement) Expected Expression but found ${expression.type}!`,
2316 + expression.node.loc ?? null
2317 );
2318 return lowerExpressionToTemporary(builder, expression);
2319 }
@@ -2554,9 +2562,10 @@ function lowerAssignment(
2562 }
2563 case "MemberExpression": {
2564 // This can only occur because of a coding error, parsers enforce this condition
2557 - invariant(
2565 + CompilerError.invariant(
2566 kind === InstructionKind.Reassign,
2559 - "MemberExpression may only appear in an assignment expression"
2567 + "MemberExpression may only appear in an assignment expression",
2568 + lvaluePath.node.loc ?? null
2569 );
2570 const lvalue = lvaluePath as NodePath<t.MemberExpression>;
2571 const property = lvalue.get("property");
compiler/forget/packages/babel-plugin-react-forget/src/HIR/Dominator.ts
+6 -5
@@ -5,8 +5,8 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import prettyFormat from "pretty-format";
9 +import { CompilerError } from "../CompilerError";
10 import { BlockId, HIRFunction } from "./HIR";
11 import { eachTerminalSuccessor } from "./visitors";
12
@@ -88,7 +88,7 @@ export class Dominator<T> {
88 */
89 get(id: T): T | null {
90 const dominator = this.#nodes.get(id);
91 - invariant(dominator !== undefined, "Unknown node");
91 + CompilerError.invariant(dominator !== undefined, "Unknown node", null);
92 return dominator === id ? null : dominator;
93 }
94
@@ -119,7 +119,7 @@ export class PostDominator<T> {
119 */
120 get(id: T): T | null {
121 const dominator = this.#nodes.get(id);
122 - invariant(dominator !== undefined, "Unknown node");
122 + CompilerError.invariant(dominator !== undefined, "Unknown node", null);
123 return dominator === id ? null : dominator;
124 }
125
@@ -159,9 +159,10 @@ function computeImmediateDominators<T>(graph: Graph<T>): Map<T, T> {
159 break;
160 }
161 }
162 - invariant(
162 + CompilerError.invariant(
163 newIdom !== null,
164 - `At least one predecessor must have been visited for block ${id}`
164 + `At least one predecessor must have been visited for block ${id}`,
165 + null
166 );
167
168 for (const pred of node.preds) {
compiler/forget/packages/babel-plugin-react-forget/src/HIR/Environment.ts
+10 -7
@@ -6,7 +6,7 @@
6 */
7
8 import * as t from "@babel/types";
9 -import invariant from "invariant";
9 +import { CompilerError } from "../CompilerError";
10 import { ExternalFunction } from "../Entrypoint/Options";
11 import { log } from "../Utils/logger";
12 import {
@@ -195,9 +195,10 @@ export class Environment {
195 if (config?.customHooks) {
196 this.#globals = new Map(DEFAULT_GLOBALS);
197 for (const [hookName, hook] of config.customHooks) {
198 - invariant(
198 + CompilerError.invariant(
199 !this.#globals.has(hookName),
200 - `[Globals] Found existing definition in global registry for custom hook ${hookName}`
200 + `[Globals] Found existing definition in global registry for custom hook ${hookName}`,
201 + null
202 );
203 this.#globals.set(
204 hookName,
@@ -270,9 +271,10 @@ export class Environment {
271 // If an object or function has a shapeId, it must have been assigned
272 // by Forget (and be present in a builtin or user-defined registry)
273 const shape = this.#shapes.get(shapeId);
273 - invariant(
274 + CompilerError.invariant(
275 shape !== undefined,
275 - `[HIR] Forget internal error: cannot resolve shape ${shapeId}`
276 + `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
277 + null
278 );
279 return shape.properties.get(property) ?? null;
280 } else {
@@ -284,9 +286,10 @@ export class Environment {
286 const { shapeId } = type;
287 if (shapeId !== null) {
288 const shape = this.#shapes.get(shapeId);
287 - invariant(
289 + CompilerError.invariant(
290 shape !== undefined,
289 - `[HIR] Forget internal error: cannot resolve shape ${shapeId}`
291 + `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
292 + null
293 );
294 return shape.functionType;
295 }
compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIR.ts
+12 -9
@@ -6,7 +6,6 @@
6 */
7
8 import * as t from "@babel/types";
9 -import invariant from "invariant";
9 import { CompilerError } from "../CompilerError";
10 import { assertExhaustive } from "../Utils/utils";
11 import { Environment } from "./Environment";
@@ -922,9 +921,10 @@ const opaqueBlockId = Symbol();
921 export type BlockId = number & { [opaqueBlockId]: "BlockId" };
922
923 export function makeBlockId(id: number): BlockId {
925 - invariant(
924 + CompilerError.invariant(
925 id >= 0 && Number.isInteger(id),
927 - "Expected block id to be a non-negative integer"
926 + "Expected block id to be a non-negative integer",
927 + null
928 );
929 return id as BlockId;
930 }
@@ -937,9 +937,10 @@ const opaqueScopeId = Symbol();
937 export type ScopeId = number & { [opaqueScopeId]: "ScopeId" };
938
939 export function makeScopeId(id: number): ScopeId {
940 - invariant(
940 + CompilerError.invariant(
941 id >= 0 && Number.isInteger(id),
942 - "Expected block id to be a non-negative integer"
942 + "Expected block id to be a non-negative integer",
943 + null
944 );
945 return id as ScopeId;
946 }
@@ -952,9 +953,10 @@ const opaqueIdentifierId = Symbol();
953 export type IdentifierId = number & { [opaqueIdentifierId]: "IdentifierId" };
954
955 export function makeIdentifierId(id: number): IdentifierId {
955 - invariant(
956 + CompilerError.invariant(
957 id >= 0 && Number.isInteger(id),
957 - "Expected identifier id to be a non-negative integer"
958 + "Expected identifier id to be a non-negative integer",
959 + null
960 );
961 return id as IdentifierId;
962 }
@@ -967,9 +969,10 @@ const opaqueInstructionId = Symbol();
969 export type InstructionId = number & { [opaqueInstructionId]: "IdentifierId" };
970
971 export function makeInstructionId(id: number): InstructionId {
970 - invariant(
972 + CompilerError.invariant(
973 id >= 0 && Number.isInteger(id),
972 - "Expected instruction id to be a non-negative integer"
974 + "Expected instruction id to be a non-negative integer",
975 + null
976 );
977 return id as InstructionId;
978 }
compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts
+28 -13
@@ -7,7 +7,6 @@
7
8 import { Binding, NodePath } from "@babel/traverse";
9 import * as t from "@babel/types";
10 -import invariant from "invariant";
10 import { CompilerError } from "../CompilerError";
11 import { assertExhaustive } from "../Utils/utils";
12 import { Environment } from "./Environment";
@@ -388,12 +387,13 @@ export default class HIRBuilder {
387 });
388 const value = fn();
389 const last = this.#scopes.pop();
391 - invariant(
390 + CompilerError.invariant(
391 last != null &&
392 last.kind === "label" &&
393 last.label === label &&
394 last.breakBlock === breakBlock,
396 - "Mismatched label"
395 + "Mismatched label",
396 + null
397 );
398 return value;
399 }
@@ -406,12 +406,13 @@ export default class HIRBuilder {
406 });
407 const value = fn();
408 const last = this.#scopes.pop();
409 - invariant(
409 + CompilerError.invariant(
410 last != null &&
411 last.kind === "switch" &&
412 last.label === label &&
413 last.breakBlock === breakBlock,
414 - "Mismatched label"
414 + "Mismatched label",
415 + null
416 );
417 return value;
418 }
@@ -440,13 +441,14 @@ export default class HIRBuilder {
441 });
442 const value = fn();
443 const last = this.#scopes.pop();
443 - invariant(
444 + CompilerError.invariant(
445 last != null &&
446 last.kind === "loop" &&
447 last.label === label &&
448 last.continueBlock === continueBlock &&
449 last.breakBlock === breakBlock,
449 - "Mismatched loops"
450 + "Mismatched loops",
451 + null
452 );
453 return value;
454 }
@@ -462,7 +464,11 @@ export default class HIRBuilder {
464 return scope.breakBlock;
465 }
466 }
465 - invariant(false, "Expected a loop or switch to be in scope");
467 + CompilerError.invariant(
468 + false,
469 + "Expected a loop or switch to be in scope",
470 + null
471 + );
472 }
473
474 /**
@@ -478,10 +484,14 @@ export default class HIRBuilder {
484 return scope.continueBlock;
485 }
486 } else if (label !== null && scope.label === label) {
481 - invariant(false, "Continue may only refer to a labeled loop");
487 + CompilerError.invariant(
488 + false,
489 + "Continue may only refer to a labeled loop",
490 + null
491 + );
492 }
493 }
484 - invariant(false, "Expected a loop to be in scope");
494 + CompilerError.invariant(false, "Expected a loop to be in scope", null);
495 }
496 }
497
@@ -501,7 +511,11 @@ function _shrink(func: HIR): void {
511 return target;
512 }
513 const block = func.blocks.get(blockId);
504 - invariant(block != null, "expected block %s to exist", blockId);
514 + CompilerError.invariant(
515 + block != null,
516 + `expected block ${blockId} to exist`,
517 + null
518 + );
519 target = getTargetIfIndirection(block);
520 if (target !== null) {
521 // the target might also be a simple goto, recurse
@@ -717,9 +731,10 @@ export function markInstructionIds(func: HIR): void {
731 const visited = new Set<Instruction>();
732 for (const [_, block] of func.blocks) {
733 for (const instr of block.instructions) {
720 - invariant(
734 + CompilerError.invariant(
735 !visited.has(instr),
722 - `${printInstruction(instr)} already visited!`
736 + `${printInstruction(instr)} already visited!`,
737 + instr.loc
738 );
739 visited.add(instr);
740 instr.id = makeInstructionId(++id);
compiler/forget/packages/babel-plugin-react-forget/src/HIR/MergeConsecutiveBlocks.ts
+7 -7
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 BlockId,
11 Effect,
@@ -47,10 +47,10 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
47 const originalPredecessorId = Array.from(block.preds)[0]!;
48 const predecessorId = merged.get(originalPredecessorId);
49 const predecessor = fn.body.blocks.get(predecessorId);
50 - invariant(
50 + CompilerError.invariant(
51 predecessor !== undefined,
52 - "Expected predecessor %s to exist",
53 - predecessorId
52 + `Expected predecessor ${predecessorId} to exist`,
53 + null
54 );
55 if (predecessor.terminal.kind !== "goto" || predecessor.kind !== "block") {
56 // The predecessor is not guaranteed to transfer control to this block,
@@ -60,10 +60,10 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
60
61 // Replace phis in the merged block with canonical assignments to the single operand value
62 for (const phi of block.phis) {
63 - invariant(
63 + CompilerError.invariant(
64 phi.operands.size === 1,
65 - "Found a block with a single predecessor but where a phi has multiple (%s) operands",
66 - phi.operands.size
65 + `Found a block with a single predecessor but where a phi has multiple (${phi.operands.size}) operands`,
66 + null
67 );
68 const operand = Array.from(phi.operands.values())[0]!;
69 const instr: Instruction = {
compiler/forget/packages/babel-plugin-react-forget/src/HIR/ObjectShape.ts
+4 -3
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import { Effect, ValueKind } from "./HIR";
10 import {
11 BuiltInType,
@@ -103,9 +103,10 @@ function addShape(
103 functionType,
104 };
105
106 - invariant(
106 + CompilerError.invariant(
107 !registry.has(id),
108 - `[ObjectShape] Could not add shape to registry: name ${id} already exists.`
108 + `[ObjectShape] Could not add shape to registry: name ${id} already exists.`,
109 + null
110 );
111 registry.set(id, shape);
112 return shape;
compiler/forget/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts
+4 -3
@@ -6,7 +6,7 @@
6 */
7
8 import generate from "@babel/generator";
9 -import invariant from "invariant";
9 +import { CompilerError } from "../CompilerError";
10 import DisjointSet from "../Utils/DisjointSet";
11 import { assertExhaustive } from "../Utils/utils";
12 import {
@@ -467,9 +467,10 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
467 }
468 case "TemplateLiteral": {
469 value = "`";
470 - invariant(
470 + CompilerError.invariant(
471 instrValue.subexprs.length === instrValue.quasis.length - 1,
472 - "Bad assumption about quasi length."
472 + "Bad assumption about quasi length.",
473 + instrValue.loc
474 );
475 for (let i = 0; i < instrValue.subexprs.length; i++) {
476 value += instrValue.quasis[i].raw;
compiler/forget/packages/babel-plugin-react-forget/src/HIR/Types.ts
+4 -3
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9
10 export type BuiltInType = PrimitiveType | FunctionType | ObjectType;
11
@@ -62,9 +62,10 @@ const opaqueTypeId = Symbol();
62 export type TypeId = number & { [opaqueTypeId]: "IdentifierId" };
63
64 export function makeTypeId(id: number): TypeId {
65 - invariant(
65 + CompilerError.invariant(
66 id >= 0 && Number.isInteger(id),
67 - "Expected instruction id to be a non-negative integer"
67 + "Expected instruction id to be a non-negative integer",
68 + null
69 );
70 return id as TypeId;
71 }
compiler/forget/packages/babel-plugin-react-forget/src/Inference/AnalyseFunctions.ts
+4 -3
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 Effect,
11 FunctionExpression,
@@ -169,9 +169,10 @@ function infer(
169 // In practice this never really matters because the Component function has no
170 // context refs, so it will never have duplicate deps.
171 for (const place of context) {
172 - invariant(
172 + CompilerError.invariant(
173 place.identifier.name !== null,
174 - "context refs should always have a name"
174 + "context refs should always have a name",
175 + place.loc
176 );
177
178 const effect = mutations.get(place.identifier.name);
compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferMutableLifetimes.ts
+4 -3
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 Effect,
11 HIRFunction,
@@ -108,9 +108,10 @@ export function inferMutableLifetimes(
108 start = Math.min(start, operand.mutableRange.start);
109 end = Math.max(end, operand.mutableRange.end);
110 }
111 - invariant(
111 + CompilerError.invariant(
112 start !== Number.MAX_SAFE_INTEGER,
113 - "Expected phi to have a start range value"
113 + "Expected phi to have a start range value",
114 + null
115 );
116 phi.id.mutableRange = {
117 start: makeInstructionId(start),
compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts
+29 -20
@@ -5,7 +5,6 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import { CompilerError } from "../CompilerError";
9 import { Environment } from "../HIR";
10 import {
@@ -192,9 +191,10 @@ class InferenceState {
191 * (Re)initializes a @param value with its default @param kind.
192 */
193 initialize(value: InstructionValue, kind: ValueKind): void {
195 - invariant(
194 + CompilerError.invariant(
195 value.kind !== "LoadLocal",
197 - "Expected all top-level identifiers to be defined as variables, not values"
196 + "Expected all top-level identifiers to be defined as variables, not values",
197 + value.loc
198 );
199 this.#values.set(value, kind);
200 }
@@ -204,11 +204,12 @@ class InferenceState {
204 */
205 kind(place: Place): ValueKind {
206 const values = this.#variables.get(place.identifier.id);
207 - invariant(
207 + CompilerError.invariant(
208 values != null,
209 `Expected value kind to be initialized at '${printSourceLocation(
210 place.loc
211 - )}'`
211 + )}'`,
212 + place.loc
213 );
214 let mergedKind: ValueKind | null = null;
215 for (const value of values) {
@@ -229,10 +230,10 @@ class InferenceState {
230 */
231 alias(place: Place, value: Place): void {
232 const values = this.#variables.get(value.identifier.id);
232 - invariant(
233 + CompilerError.invariant(
234 values != null,
234 - "Expected value for identifier `%s` to be initialized.",
235 - value.identifier.id
235 + `Expected value for identifier \`${value.identifier.id}\` to be initialized.`,
236 + value.loc
237 );
238 this.#variables.set(place.identifier.id, new Set(values));
239 }
@@ -241,9 +242,10 @@ class InferenceState {
242 * Defines (initializing or updating) a variable with a specific kind of value.
243 */
244 define(place: Place, value: InstructionValue): void {
244 - invariant(
245 + CompilerError.invariant(
246 this.#values.has(value),
246 - `Expected value to be initialized at '${printSourceLocation(value.loc)}'`
247 + `Expected value to be initialized at '${printSourceLocation(value.loc)}'`,
248 + value.loc
249 );
250 this.#variables.set(place.identifier.id, new Set([value]));
251 }
@@ -363,9 +365,10 @@ class InferenceState {
365 break;
366 }
367 case Effect.Unknown: {
366 - invariant(
368 + CompilerError.invariant(
369 false,
368 - "Unexpected unknown effect, expected to infer a precise effect kind"
370 + "Unexpected unknown effect, expected to infer a precise effect kind",
371 + place.loc
372 );
373 }
374 default: {
@@ -375,7 +378,11 @@ class InferenceState {
378 );
379 }
380 }
378 - invariant(effect !== null, "Expected effect to be set");
381 + CompilerError.invariant(
382 + effect !== null,
383 + "Expected effect to be set",
384 + place.loc
385 + );
386 place.effect = effect;
387 }
388
@@ -746,9 +753,10 @@ function inferBlock(
753 continue;
754 }
755 case "MethodCall": {
749 - invariant(
756 + CompilerError.invariant(
757 state.isDefined(instrValue.receiver),
751 - "[InferReferenceEffects] Internal error: receiver of PropertyCall should have been defined by corresponding PropertyLoad"
758 + "[InferReferenceEffects] Internal error: receiver of PropertyCall should have been defined by corresponding PropertyLoad",
759 + instrValue.loc
760 );
761 state.reference(instrValue.property, Effect.Read);
762
@@ -882,9 +890,10 @@ function inferBlock(
890 const lvalue = instr.lvalue;
891 lvalue.effect = Effect.ConditionallyMutate;
892 const valueKind = state.kind(instrValue.place);
885 - invariant(
893 + CompilerError.invariant(
894 valueKind === ValueKind.Mutable || valueKind === ValueKind.Context,
887 - "[InferReferenceEffects] Context variables are always mutable."
895 + "[InferReferenceEffects] Context variables are always mutable.",
896 + instrValue.loc
897 );
898 state.initialize(instrValue, valueKind);
899 state.define(lvalue, instrValue);
@@ -971,10 +980,10 @@ function inferBlock(
980 }
981
982 for (const operand of eachInstructionOperand(instr)) {
974 - invariant(
983 + CompilerError.invariant(
984 effectKind != null,
976 - "effectKind must be set for instruction value `%s`",
977 - instrValue.kind
985 + `effectKind must be set for instruction value \`${instrValue.kind}\``,
986 + instrValue.loc
987 );
988 state.reference(operand, effectKind);
989 }
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveBlocks.ts
+20 -9
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 BlockId,
11 InstructionId,
@@ -70,7 +70,11 @@ class Context {
70 this.#builders.push(builder);
71 fn();
72 const popped = this.#builders.pop();
73 - invariant(popped === builder, "Expected push/pop to be called 1:1");
73 + CompilerError.invariant(
74 + popped === builder,
75 + "Expected push/pop to be called 1:1",
76 + null
77 + );
78 return builder.complete();
79 }
80 }
@@ -90,7 +94,11 @@ class Builder {
94
95 append(item: ReactiveStatement, label: BlockId | null): void {
96 if (label !== null) {
93 - invariant(item.kind === "terminal", "Only terminals may have a label");
97 + CompilerError.invariant(
98 + item.kind === "terminal",
99 + "Only terminals may have a label",
100 + null
101 + );
102 item.label = label;
103 }
104 this.#instructions.push(item);
@@ -130,9 +138,10 @@ class Builder {
138 // "Expected all scopes to be closed when exiting a block"
139 // );
140 const first = this.#stack[0]!;
133 - invariant(
141 + CompilerError.invariant(
142 first.kind === "block",
135 - "Expected first stack item to be a basic block"
143 + "Expected first stack item to be a basic block",
144 + null
145 );
146 return first.block;
147 }
@@ -164,9 +173,10 @@ function visitBlock(context: Context, block: ReactiveBlock): void {
173 break;
174 }
175 case "scope": {
167 - invariant(
176 + CompilerError.invariant(
177 false,
169 - "Expected the function to not have scopes already assigned"
178 + "Expected the function to not have scopes already assigned",
179 + null
180 );
181 }
182 default: {
@@ -182,10 +192,11 @@ function visitBlock(context: Context, block: ReactiveBlock): void {
192 export function getInstructionScope(
193 instr: ReactiveInstruction
194 ): ReactiveScope | null {
185 - invariant(
195 + CompilerError.invariant(
196 instr.lvalue !== null,
197 "Expected lvalues to not be null when assigning scopes. " +
188 - "Pruning lvalues too early can result in missing scope information."
198 + "Pruning lvalues too early can result in missing scope information.",
199 + instr.loc
200 );
201 for (const operand of eachInstructionLValue(instr)) {
202 const operandScope = getPlaceScope(instr.id, operand);
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveFunction.ts
+51 -37
@@ -5,7 +5,6 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import { CompilerError } from "../CompilerError";
9 import {
10 BasicBlock,
@@ -66,9 +65,10 @@ class Driver {
65 }
66
67 visitBlock(block: BasicBlock, blockValue: ReactiveBlock): void {
69 - invariant(
68 + CompilerError.invariant(
69 !this.cx.emitted.has(block.id),
71 - `Cannot emit the same block twice: bb${block.id}`
70 + `Cannot emit the same block twice: bb${block.id}`,
71 + null
72 );
73 this.cx.emitted.add(block.id);
74 for (const instruction of block.instructions) {
@@ -252,9 +252,10 @@ class Driver {
252 loopBody = this.traverseBlock(this.cx.ir.blocks.get(loopId)!);
253 } else {
254 const break_ = this.visitBreak(terminal.loop, null);
255 - invariant(
255 + CompilerError.invariant(
256 break_ !== null,
257 - "If loop body is already scheduled it must be a break"
257 + "If loop body is already scheduled it must be a break",
258 + null
259 );
260 loopBody = [break_];
261 }
@@ -308,9 +309,10 @@ class Driver {
309 loopBody = this.traverseBlock(this.cx.ir.blocks.get(loopId)!);
310 } else {
311 const break_ = this.visitBreak(terminal.loop, null);
311 - invariant(
312 + CompilerError.invariant(
313 break_ !== null,
313 - "If loop body is already scheduled it must be a break"
314 + "If loop body is already scheduled it must be a break",
315 + null
316 );
317 loopBody = [break_];
318 }
@@ -392,9 +394,10 @@ class Driver {
394 loopBody = this.traverseBlock(this.cx.ir.blocks.get(loopId)!);
395 } else {
396 const break_ = this.visitBreak(terminal.loop, null);
395 - invariant(
397 + CompilerError.invariant(
398 break_ !== null,
397 - "If loop body is already scheduled it must be a break"
399 + "If loop body is already scheduled it must be a break",
400 + null
401 );
402 loopBody = [break_];
403 }
@@ -467,9 +470,10 @@ class Driver {
470 loopBody = this.traverseBlock(this.cx.ir.blocks.get(loopId)!);
471 } else {
472 const break_ = this.visitBreak(terminal.loop, null);
470 - invariant(
473 + CompilerError.invariant(
474 break_ !== null,
472 - "If loop body is already scheduled it must be a break"
475 + "If loop body is already scheduled it must be a break",
476 + null
477 );
478 loopBody = [break_];
479 }
@@ -626,7 +630,11 @@ class Driver {
630 break;
631 }
632 case "unsupported": {
629 - invariant(false, "Unexpected unsupported terminal");
633 + CompilerError.invariant(
634 + false,
635 + "Unexpected unsupported terminal",
636 + terminal.loc
637 + );
638 }
639 default: {
640 assertExhaustive(terminal, "Unexpected terminal");
@@ -654,10 +662,11 @@ class Driver {
662 };
663 } else if (defaultBlock.instructions.length === 1) {
664 const instr = defaultBlock.instructions[0]!;
657 - invariant(
665 + CompilerError.invariant(
666 instr.lvalue.identifier.id ===
667 defaultBlock.terminal.test.identifier.id,
660 - "Expected branch block to end in an instruction that sets the test value"
668 + "Expected branch block to end in an instruction that sets the test value",
669 + instr.lvalue.loc
670 );
671 return {
672 block: defaultBlock.id,
@@ -684,9 +693,10 @@ class Driver {
693 } else if (defaultBlock.terminal.kind === "goto") {
694 const instructions = defaultBlock.instructions;
695 if (instructions.length === 0) {
687 - invariant(
696 + CompilerError.invariant(
697 false,
689 - "Expected goto value block to have at least one instruction"
698 + "Expected goto value block to have at least one instruction",
699 + null
700 );
701 } else if (defaultBlock.instructions.length === 1) {
702 const instr = defaultBlock.instructions[0]!;
@@ -782,10 +792,10 @@ class Driver {
792 case "optional": {
793 const test = this.visitValueBlock(terminal.test, terminal.loc);
794 const testBlock = this.cx.ir.blocks.get(test.block)!;
785 - invariant(
795 + CompilerError.invariant(
796 testBlock.terminal.kind === "branch",
787 - "Unexpected terminal kind '%s' for optional call test block",
788 - testBlock.terminal.kind
797 + `Unexpected terminal kind '${testBlock.terminal.kind}' for optional call test block`,
798 + testBlock.terminal.loc
799 );
800 const consequent = this.visitValueBlock(
801 testBlock.terminal.consequent,
@@ -821,10 +831,10 @@ class Driver {
831 case "logical": {
832 const test = this.visitValueBlock(terminal.test, terminal.loc);
833 const testBlock = this.cx.ir.blocks.get(test.block)!;
824 - invariant(
834 + CompilerError.invariant(
835 testBlock.terminal.kind === "branch",
826 - "Unexpected terminal kind '%s' for logical test block",
827 - testBlock.terminal.kind
836 + `Unexpected terminal kind '${testBlock.terminal.kind}' for logical test block`,
837 + testBlock.terminal.loc
838 );
839
840 const leftFinal = this.visitValueBlock(
@@ -866,10 +876,10 @@ class Driver {
876 case "ternary": {
877 const test = this.visitValueBlock(terminal.test, terminal.loc);
878 const testBlock = this.cx.ir.blocks.get(test.block)!;
869 - invariant(
879 + CompilerError.invariant(
880 testBlock.terminal.kind === "branch",
871 - "Unexpected terminal kind '%s' for ternary test block",
872 - testBlock.terminal.kind
881 + `Unexpected terminal kind '${testBlock.terminal.kind}' for ternary test block`,
882 + testBlock.terminal.loc
883 );
884 const consequent = this.visitValueBlock(
885 testBlock.terminal.consequent,
@@ -895,10 +905,10 @@ class Driver {
905 };
906 }
907 default: {
898 - invariant(
908 + CompilerError.invariant(
909 false,
900 - "Unexpected value block terminal kind '%s'",
901 - terminal.kind
910 + `Unexpected value block terminal kind '${terminal.kind}'`,
911 + terminal.loc
912 );
913 }
914 }
@@ -914,7 +924,7 @@ class Driver {
924 ): ReactiveTerminalStatement<ReactiveBreakTerminal> {
925 const target = this.cx.getBreakTarget(block);
926 if (target === null) {
917 - invariant(false, "Expected a break target");
927 + CompilerError.invariant(false, "Expected a break target", null);
928 }
929 switch (target.type) {
930 case "implicit": {
@@ -952,9 +962,10 @@ class Driver {
962 id: InstructionId
963 ): ReactiveTerminalStatement<ReactiveContinueTerminal> {
964 const target = this.cx.getContinueTarget(block);
955 - invariant(
965 + CompilerError.invariant(
966 target !== null,
957 - `Expected continue target to be scheduled for bb${block}`
967 + `Expected continue target to be scheduled for bb${block}`,
968 + null
969 );
970 switch (target.type) {
971 case "implicit": {
@@ -1035,9 +1046,10 @@ class Context {
1046 */
1047 schedule(block: BlockId, type: "if" | "switch" | "case"): number {
1048 const id = this.#nextScheduleId++;
1038 - invariant(
1049 + CompilerError.invariant(
1050 !this.#scheduled.has(block),
1040 - `Break block is already scheduled: bb${block}`
1051 + `Break block is already scheduled: bb${block}`,
1052 + null
1053 );
1054 this.#scheduled.add(block);
1055 this.#controlFlowStack.push({ block, id, type });
@@ -1052,9 +1064,10 @@ class Context {
1064 const id = this.#nextScheduleId++;
1065 const ownsBlock = !this.#scheduled.has(fallthroughBlock);
1066 this.#scheduled.add(fallthroughBlock);
1055 - invariant(
1067 + CompilerError.invariant(
1068 !this.#scheduled.has(continueBlock),
1057 - `Continue block is already scheduled: bb${continueBlock}`
1069 + `Continue block is already scheduled: bb${continueBlock}`,
1070 + null
1071 );
1072 this.#scheduled.add(continueBlock);
1073 let ownsLoop = false;
@@ -1080,9 +1093,10 @@ class Context {
1093 */
1094 unschedule(scheduleId: number): void {
1095 const last = this.#controlFlowStack.pop();
1083 - invariant(
1096 + CompilerError.invariant(
1097 last !== undefined && last.id === scheduleId,
1085 - "Can only unschedule the last target"
1098 + "Can only unschedule the last target",
1099 + null
1100 );
1101 if (last.type !== "loop" || last.ownsBlock !== null) {
1102 this.#scheduled.delete(last.block);
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+35 -25
@@ -6,7 +6,6 @@
6 */
7
8 import * as t from "@babel/types";
9 -import invariant from "invariant";
9 import { pruneUnusedLValues, pruneUnusedLabels, renameVariables } from ".";
10 import { CompilerError, ErrorSeverity } from "../CompilerError";
11 import { Environment } from "../HIR";
@@ -216,10 +215,10 @@ function codegenReactiveScope(
215 firstOutputIndex = index;
216 }
217
219 - invariant(
218 + CompilerError.invariant(
219 identifier.name != null,
221 - "Expected identifier '@%s' to be named",
222 - identifier.id
220 + `Expected identifier '@${identifier.id}' to be named`,
221 + null
222 );
223
224 const name = convertIdentifier(identifier);
@@ -284,10 +283,10 @@ function codegenReactiveScope(
283 null as t.Expression | null
284 );
285 if (testCondition === null) {
287 - invariant(
286 + CompilerError.invariant(
287 firstOutputIndex !== null,
289 - "Expected scope '@%s' to have at least one declaration",
290 - scope.id
288 + `Expected scope '@${scope.id}' to have at least one declaration`,
289 + null
290 );
291 testCondition = t.binaryExpression(
292 "===",
@@ -542,7 +541,11 @@ function codegenInstructionNullable(
541 ]);
542 }
543 case InstructionKind.Reassign: {
545 - invariant(value !== null, "Expected a value for reassignment");
544 + CompilerError.invariant(
545 + value !== null,
546 + "Expected a value for reassignment",
547 + instr.value.loc
548 + );
549 const expr = t.assignmentExpression("=", codegenLValue(lvalue), value);
550 if (instr.lvalue !== null) {
551 if (instr.value.kind !== "StoreContext") {
@@ -589,9 +592,10 @@ function codegenForInit(
592 }))
593 ).body;
594 const declaration = body[0]!;
592 - invariant(
595 + CompilerError.invariant(
596 declaration.type === "VariableDeclaration",
594 - "Expected a variable declaration"
597 + "Expected a variable declaration",
598 + declaration.loc ?? null
599 );
600 return declaration;
601 } else {
@@ -740,9 +744,10 @@ function codegenInstructionValue(
744 switch (optionalValue.type) {
745 case "OptionalCallExpression":
746 case "CallExpression": {
743 - invariant(
747 + CompilerError.invariant(
748 t.isExpression(optionalValue.callee),
745 - "v8 intrinsics are validated during lowering"
749 + "v8 intrinsics are validated during lowering",
750 + optionalValue.callee.loc ?? null
751 );
752 value = t.optionalCallExpression(
753 optionalValue.callee,
@@ -754,9 +759,10 @@ function codegenInstructionValue(
759 case "OptionalMemberExpression":
760 case "MemberExpression": {
761 const property = optionalValue.property;
757 - invariant(
762 + CompilerError.invariant(
763 t.isExpression(property),
759 - "Private names are validated during lowering"
764 + "Private names are validated during lowering",
765 + property.loc ?? null
766 );
767 value = t.optionalMemberExpression(
768 optionalValue.object,
@@ -779,19 +785,21 @@ function codegenInstructionValue(
785 }
786 case "MethodCall": {
787 const memberExpr = codegenPlace(cx, instrValue.property);
782 - invariant(
788 + CompilerError.invariant(
789 t.isMemberExpression(memberExpr) ||
790 t.isOptionalMemberExpression(memberExpr),
791 "[Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. " +
786 - `Got a '${memberExpr.type}'`
792 + `Got a '${memberExpr.type}'`,
793 + memberExpr.loc ?? null
794 );
788 - invariant(
795 + CompilerError.invariant(
796 t.isNodesEquivalent(
797 memberExpr.object,
798 codegenPlace(cx, instrValue.receiver)
799 ),
800 "[Codegen] Internal error: Forget should always generate MethodCall::property " +
794 - "as a MemberExpression of MethodCall::receiver"
801 + "as a MemberExpression of MethodCall::receiver",
802 + memberExpr.loc ?? null
803 );
804 const args = instrValue.args.map((arg) => codegenArgument(cx, arg));
805 value = createCallExpression(instrValue.loc, memberExpr, args);
@@ -843,10 +851,10 @@ function codegenInstructionValue(
851 } else if (tagValue.type === "MemberExpression") {
852 tag = convertMemberExpressionToJsx(tagValue);
853 } else {
846 - invariant(
854 + CompilerError.invariant(
855 tagValue.type === "StringLiteral",
848 - "Expected JSX tag to be an identifier or string, got '%s'",
849 - tagValue.type
856 + `Expected JSX tag to be an identifier or string, got '${tagValue.type}'`,
857 + tagValue.loc ?? null
858 );
859 if (tagValue.value.indexOf(":") >= 0) {
860 const [namespace, name] = tagValue.value.split(":", 2);
@@ -1185,17 +1193,19 @@ function codegenJsxElement(
1193 function convertMemberExpressionToJsx(
1194 expr: t.MemberExpression
1195 ): t.JSXMemberExpression {
1188 - invariant(
1196 + CompilerError.invariant(
1197 expr.property.type === "Identifier",
1190 - "Expected JSX member expression property to be a string"
1198 + "Expected JSX member expression property to be a string",
1199 + expr.loc ?? null
1200 );
1201 const property = t.jsxIdentifier(expr.property.name);
1202 if (expr.object.type === "Identifier") {
1203 return t.jsxMemberExpression(t.jsxIdentifier(expr.object.name), property);
1204 } else {
1196 - invariant(
1205 + CompilerError.invariant(
1206 expr.object.type === "MemberExpression",
1198 - "Expected JSX member expression to be an identifier or nested member expression"
1207 + "Expected JSX member expression to be an identifier or nested member expression",
1208 + expr.object.loc ?? null
1209 );
1210 const object = convertMemberExpressionToJsx(expr.object);
1211 return t.jsxMemberExpression(object, property);
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/DeriveMinimalDependencies.ts
+13 -9
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import { Identifier, ReactiveScopeDependency } from "../HIR";
10 import { printIdentifier } from "../HIR/PrintHIR";
11 import { assertExhaustive } from "../Utils/utils";
@@ -122,11 +122,12 @@ export class ReactiveScopeDependencyTree {
122 const results = new Set<ReactiveScopeDependency>();
123 for (const [rootId, rootNode] of this.#roots.entries()) {
124 const deps = deriveMinimalDependenciesInSubtree(rootNode);
125 - invariant(
125 + CompilerError.invariant(
126 deps.every(
127 (dep) => dep.accessType === PropertyAccessType.UnconditionalDependency
128 ),
129 - "[PropagateScopeDependencies] All dependencies must be reduced to unconditional dependencies."
129 + "[PropagateScopeDependencies] All dependencies must be reduced to unconditional dependencies.",
130 + null
131 );
132
133 for (const dep of deps) {
@@ -162,9 +163,10 @@ export class ReactiveScopeDependencyTree {
163 promoteDepsFromExhaustiveConditionals(
164 trees: Array<ReactiveScopeDependencyTree>
165 ): void {
165 - invariant(
166 + CompilerError.invariant(
167 trees.length > 1,
167 - "Expected trees to be at least 2 elements long."
168 + "Expected trees to be at least 2 elements long.",
169 + null
170 );
171
172 for (const [id, root] of this.#roots) {
@@ -456,16 +458,18 @@ function addSubtreeIntersection(
458 otherProperties: Array<Map<string, DependencyNode>>,
459 currProperties: Map<string, DependencyNode>
460 ): void {
459 - invariant(
461 + CompilerError.invariant(
462 otherProperties.length > 1,
461 - "[DeriveMinimalDependencies] Expected otherProperties to be at least 2 elements long."
463 + "[DeriveMinimalDependencies] Expected otherProperties to be at least 2 elements long.",
464 + null
465 );
466
467 otherProperties.forEach((properties) =>
468 properties.forEach((node, _) =>
466 - invariant(
469 + CompilerError.invariant(
470 !isUnconditional(node.accessType),
468 - "[DeriveMinimalDependencies] Expected otherProperties to only contain unconditional nodes!"
471 + "[DeriveMinimalDependencies] Expected otherProperties to only contain unconditional nodes!",
472 + null
473 )
474 )
475 );
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PrintReactiveFunction.ts
+6 -2
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 ReactiveFunction,
11 ReactiveScopeBlock,
@@ -226,7 +226,11 @@ function printTerminal(writer: Writer, terminal: ReactiveTerminal): void {
226 writer.writeLine(`${prefix}: {`);
227 writer.indented(() => {
228 const block = case_.block;
229 - invariant(block != null, "Expected case to have a block");
229 + CompilerError.invariant(
230 + block != null,
231 + "Expected case to have a block",
232 + case_.test?.loc ?? null
233 + );
234 printReactiveInstructions(writer, block);
235 });
236 writer.writeLine("}");
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts
+11 -6
@@ -5,7 +5,6 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import prettyFormat from "pretty-format";
9 import { CompilerError } from "../CompilerError";
10 import {
@@ -244,9 +243,10 @@ class State {
243 this.scopes.set(scope.id, node);
244 }
245 const identifierNode = this.identifiers.get(identifier);
247 - invariant(
246 + CompilerError.invariant(
247 identifierNode !== undefined,
249 - "Expected identifier to be initialized"
248 + "Expected identifier to be initialized",
249 + place.loc
250 );
251 identifierNode.scopes.add(scope.id);
252 }
@@ -264,9 +264,10 @@ function computeMemoizedIdentifiers(state: State): Set<IdentifierId> {
264 // Visit an identifier, optionally forcing it to be memoized
265 function visit(id: IdentifierId, forceMemoize: boolean = false): boolean {
266 const node = state.identifiers.get(id);
267 - invariant(
267 + CompilerError.invariant(
268 node !== undefined,
269 - `Expected a node for all identifiers, none found for '${id}'`
269 + `Expected a node for all identifiers, none found for '${id}'`,
270 + null
271 );
272 if (node.seen) {
273 return node.memoized;
@@ -302,7 +303,11 @@ function computeMemoizedIdentifiers(state: State): Set<IdentifierId> {
303 // Force all the scope's optionally-memoizeable dependencies (not "Never") to be memoized
304 function forceMemoizeScopeDependencies(id: ScopeId): void {
305 const node = state.scopes.get(id);
305 - invariant(node !== undefined, "Expected a node for all scopes");
306 + CompilerError.invariant(
307 + node !== undefined,
308 + "Expected a node for all scopes",
309 + null
310 + );
311 if (node.seen) {
312 return;
313 }
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/RenameVariables.ts
+2 -2
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import {
10 Identifier,
11 IdentifierId,
@@ -103,6 +103,6 @@ class Scopes {
103 this.#stack.push(next);
104 fn();
105 const last = this.#stack.pop();
106 - invariant(last === next, "Mismatch push/pop calls");
106 + CompilerError.invariant(last === next, "Mismatch push/pop calls", null);
107 }
108 }
compiler/forget/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts
+6 -2
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9 import { BlockId, HIRFunction, Identifier, Place } from "../HIR/HIR";
10 import {
11 eachInstructionLValue,
@@ -83,7 +83,11 @@ export function eliminateRedundantPhi(fn: HIRFunction): void {
83 same = operand;
84 }
85 }
86 - invariant(same !== null, "Expected phis to be non-empty");
86 + CompilerError.invariant(
87 + same !== null,
88 + "Expected phis to be non-empty",
89 + null
90 + );
91 rewrites.set(phi.id, same);
92 block.phis.delete(phi);
93 }
compiler/forget/packages/babel-plugin-react-forget/src/SSA/EnterSSA.ts
+9 -7
@@ -5,7 +5,6 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import { CompilerError } from "../CompilerError";
9 import { Environment } from "../HIR/Environment";
10 import {
@@ -68,9 +67,10 @@ class SSABuilder {
67 }
68
69 state(): State {
71 - invariant(
70 + CompilerError.invariant(
71 this.#current !== null,
73 - "we need to be in a block to access state!"
72 + "we need to be in a block to access state!",
73 + null
74 );
75 return this.#states.get(this.#current)!;
76 }
@@ -237,9 +237,10 @@ function enterSSAImpl(
237 ): void {
238 const visitedBlocks: Set<BasicBlock> = new Set();
239 for (const [blockId, block] of func.body.blocks) {
240 - invariant(
240 + CompilerError.invariant(
241 !visitedBlocks.has(block),
242 - `found a cycle! visiting bb${block.id} again`
242 + `found a cycle! visiting bb${block.id} again`,
243 + null
244 );
245 visitedBlocks.add(block);
246
@@ -269,9 +270,10 @@ function enterSSAImpl(
270 ) {
271 const loweredFunc = instr.value.loweredFunc;
272 const entry = loweredFunc.body.blocks.get(loweredFunc.body.entry)!;
272 - invariant(
273 + CompilerError.invariant(
274 entry.preds.size === 0,
274 - "Expected function expression entry block to have zero predecessors"
275 + "Expected function expression entry block to have zero predecessors",
276 + null
277 );
278 entry.preds.add(blockId);
279 builder.defineFunction(loweredFunc);
compiler/forget/packages/babel-plugin-react-forget/src/SSA/LeaveSSA.ts
+8 -4
@@ -5,7 +5,6 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 import { CompilerError } from "../CompilerError";
9 import {
10 BasicBlock,
@@ -220,7 +219,11 @@ export function leaveSSA(fn: HIRFunction): void {
219 }
220 }
221 }
223 - invariant(kind !== null, "Expected at least one operand");
222 + CompilerError.invariant(
223 + kind !== null,
224 + "Expected at least one operand",
225 + null
226 + );
227 value.lvalue.kind = kind;
228 }
229 rewritePlace(lvalue, rewrites, declarations);
@@ -353,9 +356,10 @@ export function leaveSSA(fn: HIRFunction): void {
356
357 // If we never saw a declaration for this phi, it may have been pruned by DCE, so synthesize
358 // a new Let binding
356 - invariant(
359 + CompilerError.invariant(
360 phi.id.name != null,
358 - "Expected reassignment phis to have a name"
361 + "Expected reassignment phis to have a name",
362 + null
363 );
364 const declaration = declarations.get(phi.id.name);
365 if (declaration === undefined) {
compiler/forget/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts
+6 -2
@@ -6,7 +6,7 @@
6 */
7
8 import * as t from "@babel/types";
9 -import invariant from "invariant";
9 +import { CompilerError } from "../CompilerError";
10 import { Environment } from "../HIR";
11 import {
12 HIRFunction,
@@ -342,7 +342,11 @@ class Unifier {
342 if (type.kind === "Phi") {
343 const operands = new Set(type.operands.map((i) => this.get(i).kind));
344
345 - invariant(operands.size > 0, "there should be at least one operand");
345 + CompilerError.invariant(
346 + operands.size > 0,
347 + "there should be at least one operand",
348 + null
349 + );
350 const kind = operands.values().next().value;
351
352 // there's only one unique type and it's not a type var
compiler/forget/packages/babel-plugin-react-forget/src/Utils/DisjointSet.ts
+6 -2
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import invariant from "invariant";
8 +import { CompilerError } from "../CompilerError";
9
10 /**
11 * Represents items which form disjoint sets.
@@ -20,7 +20,11 @@ export default class DisjointSet<T> {
20 */
21 union(items: Array<T>): void {
22 const first = items.shift();
23 - invariant(first != null, "Expected set to be non-empty");
23 + CompilerError.invariant(
24 + first != null,
25 + "Expected set to be non-empty",
26 + null
27 + );
28 // determine an arbitrary "root" for this set: if the first
29 // item already has a root then use that, otherwise the first item
30 // will be the new root.
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo.destructure-assignment-to-context-var.expect.md
+1 -1
@@ -18,7 +18,7 @@ function useFoo(props) {
18 ## Error
19
20 ```
21 -[InferReferenceEffects] Context variables are always mutable.
21 +[ReactForget] Invariant: [InferReferenceEffects] Context variables are always mutable. (5:5)
22 ```
23
24
\ No newline at end of file