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