@samitouri / QOS-React / commits / e7e67f335a
Fork 0

The library for web and native user interfaces.

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