Collect bailouts in BuildHIR::lowerJsxElement
Lauren Tan committed
Jan 20, 2023 at 11:47 UTC
9ed6977c480648119dff7dc4ce10d3772b20a3fd
3 files changed
+95
-63
compiler/forget/src/HIR/BuildHIR.ts
+27
-6
@@ -1351,7 +1351,7 @@ function lowerExpression(
1351
for (const p of expr.get("params")) {
1352
if (!p.isIdentifier()) {
1353
builder.pushError({
1354
- reason: "Handle non identifier params",
1354
+ reason: `Support non identifier params: ${p.type}`,
1355
severity: ErrorSeverity.Todo,
1356
nodePath: p,
1357
});
@@ -1563,7 +1563,25 @@ function lowerJsxElement(
1563
return lowerExpressionToPlace(builder, exprPath);
1564
} else if (exprPath.isJSXExpressionContainer()) {
1565
const expression = exprPath.get("expression");
1566
- todoInvariant(expression.isExpression(), "handle empty expressions");
1566
+ if (!expression.isExpression()) {
1567
+ builder.pushError({
1568
+ reason: "Handle empty expressions",
1569
+ severity: ErrorSeverity.Todo,
1570
+ nodePath: expression,
1571
+ });
1572
+ const place: Place = buildTemporaryPlace(builder, exprLoc);
1573
+ builder.push({
1574
+ id: makeInstructionId(0),
1575
+ value: {
1576
+ kind: "UnsupportedNode",
1577
+ node: exprNode,
1578
+ loc: exprLoc,
1579
+ },
1580
+ loc: exprLoc,
1581
+ lvalue: { place: { ...place }, kind: InstructionKind.Const },
1582
+ });
1583
+ return { ...place };
1584
+ }
1585
return lowerExpressionToPlace(builder, expression);
1586
} else if (exprPath.isJSXText()) {
1587
const place: Place = buildTemporaryPlace(builder, exprLoc);
@@ -1579,10 +1597,13 @@ function lowerJsxElement(
1597
});
1598
return place;
1599
} else {
1582
- invariant(
1583
- t.isJSXFragment(exprNode) || t.isJSXSpreadChild(exprNode),
1584
- "Expected refinement to work"
1585
- );
1600
+ if (!(t.isJSXFragment(exprNode) || t.isJSXSpreadChild(exprNode))) {
1601
+ builder.pushError({
1602
+ reason: "Expected refinement to work",
1603
+ severity: ErrorSeverity.InvalidInput,
1604
+ nodePath: exprPath,
1605
+ });
1606
+ }
1607
const place: Place = buildTemporaryPlace(builder, exprLoc);
1608
builder.push({
1609
id: makeInstructionId(0),
compiler/forget/src/__tests__/fixtures/hir/error.todo-kitchensink.expect.md
+67
-57
@@ -25,6 +25,7 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
25
<Button {...args}></Button>;
26
<Button xlink:href="localhost:3000"></Button>;
27
<Button haha={1}></Button>;
28
+ <Button>{/** empty */}</Button>;
29
<DesignSystem.Button />;
30
31
const j = function bar([quz, qux], ...args) {};
@@ -149,7 +150,7 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
150
| ^^^^^^^^^
151
22 | <Button xlink:href="localhost:3000"></Button>;
152
23 | <Button haha={1}></Button>;
152
- 24 | <DesignSystem.Button />;
153
+ 24 | <Button>{/** empty */}</Button>;
154
155
[ReactForget] TodoError: Handle non-identifier jsx attribute names
156
20 |
@@ -157,86 +158,95 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
158
> 22 | <Button xlink:href="localhost:3000"></Button>;
159
| ^^^^^^^^^^
160
23 | <Button haha={1}></Button>;
160
- 24 | <DesignSystem.Button />;
161
- 25 |
161
+ 24 | <Button>{/** empty */}</Button>;
162
+ 25 | <DesignSystem.Button />;
163
163
-[ReactForget] TodoError: Handle non-identifier tags
164
+[ReactForget] TodoError: Handle empty expressions
165
22 | <Button xlink:href="localhost:3000"></Button>;
166
23 | <Button haha={1}></Button>;
166
-> 24 | <DesignSystem.Button />;
167
+> 24 | <Button>{/** empty */}</Button>;
168
+ | ^^^^^^^^^^^^
169
+ 25 | <DesignSystem.Button />;
170
+ 26 |
171
+ 27 | const j = function bar([quz, qux], ...args) {};
172
+
173
+[ReactForget] TodoError: Handle non-identifier tags
174
+ 23 | <Button haha={1}></Button>;
175
+ 24 | <Button>{/** empty */}</Button>;
176
+> 25 | <DesignSystem.Button />;
177
| ^^^^^^^^^^^^^^^^^^^
168
- 25 |
169
- 26 | const j = function bar([quz, qux], ...args) {};
170
- 27 |
171
-
172
-[ReactForget] TodoError: Handle non identifier params
173
- 24 | <DesignSystem.Button />;
174
- 25 |
175
-> 26 | const j = function bar([quz, qux], ...args) {};
178
+ 26 |
179
+ 27 | const j = function bar([quz, qux], ...args) {};
180
+ 28 |
181
+
182
+[ReactForget] TodoError: Support non-identifier params: ArrayPattern
183
+ 25 | <DesignSystem.Button />;
184
+ 26 |
185
+> 27 | const j = function bar([quz, qux], ...args) {};
186
| ^^^^^^^^^^
177
- 27 |
178
- 28 | for (; i < 3; i += 1) {
179
- 29 | x.push(i);
180
-
181
-[ReactForget] TodoError: Handle non identifier params
182
- 24 | <DesignSystem.Button />;
183
- 25 |
184
-> 26 | const j = function bar([quz, qux], ...args) {};
187
+ 28 |
188
+ 29 | for (; i < 3; i += 1) {
189
+ 30 | x.push(i);
190
+
191
+[ReactForget] TodoError: Support non-identifier params: RestElement
192
+ 25 | <DesignSystem.Button />;
193
+ 26 |
194
+> 27 | const j = function bar([quz, qux], ...args) {};
195
| ^^^^^^^
186
- 27 |
187
- 28 | for (; i < 3; i += 1) {
188
- 29 | x.push(i);
196
+ 28 |
197
+ 29 | for (; i < 3; i += 1) {
198
+ 30 | x.push(i);
199
200
[ReactForget] TodoError: Support non-variable initialization in for
191
- 26 | const j = function bar([quz, qux], ...args) {};
192
- 27 |
193
-> 28 | for (; i < 3; i += 1) {
201
+ 27 | const j = function bar([quz, qux], ...args) {};
202
+ 28 |
203
+> 29 | for (; i < 3; i += 1) {
204
| ^
195
- 29 | x.push(i);
196
- 30 | }
197
- 31 | for (; i < 3; ) {}
205
+ 30 | x.push(i);
206
+ 31 | }
207
+ 32 | for (; i < 3; ) {}
208
209
[ReactForget] TodoError: Support non-variable initialization in for
200
- 29 | x.push(i);
201
- 30 | }
202
-> 31 | for (; i < 3; ) {}
210
+ 30 | x.push(i);
211
+ 31 | }
212
+> 32 | for (; i < 3; ) {}
213
| ^^^^^^^^^^^^^^^^^^
204
- 32 | for (;;) {}
205
- 33 | }
206
- 34 |
214
+ 33 | for (;;) {}
215
+ 34 | }
216
+ 35 |
217
218
[ReactForget] TodoError: Handle empty for updater
209
- 29 | x.push(i);
210
- 30 | }
211
-> 31 | for (; i < 3; ) {}
219
+ 30 | x.push(i);
220
+ 31 | }
221
+> 32 | for (; i < 3; ) {}
222
| ^^^^^^^^^^^^^^^^^^
213
- 32 | for (;;) {}
214
- 33 | }
215
- 34 |
223
+ 33 | for (;;) {}
224
+ 34 | }
225
+ 35 |
226
227
[ReactForget] TodoError: Support non-variable initialization in for
218
- 30 | }
219
- 31 | for (; i < 3; ) {}
220
-> 32 | for (;;) {}
228
+ 31 | }
229
+ 32 | for (; i < 3; ) {}
230
+> 33 | for (;;) {}
231
| ^^^^^^^^^^^
222
- 33 | }
223
- 34 |
232
+ 34 | }
233
+ 35 |
234
235
[ReactForget] TodoError: Handle empty for updater
226
- 30 | }
227
- 31 | for (; i < 3; ) {}
228
-> 32 | for (;;) {}
236
+ 31 | }
237
+ 32 | for (; i < 3; ) {}
238
+> 33 | for (;;) {}
239
| ^^^^^^^^^^^
230
- 33 | }
231
- 34 |
240
+ 34 | }
241
+ 35 |
242
243
[ReactForget] TodoError: ForStatement without test
234
- 30 | }
235
- 31 | for (; i < 3; ) {}
236
-> 32 | for (;;) {}
244
+ 31 | }
245
+ 32 | for (; i < 3; ) {}
246
+> 33 | for (;;) {}
247
| ^^^^^^^^^^^
238
- 33 | }
239
- 34 |
248
+ 34 | }
249
+ 35 |
250
```
251
252
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/error.todo-kitchensink.js
+1
@@ -21,6 +21,7 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
21
<Button {...args}></Button>;
22
<Button xlink:href="localhost:3000"></Button>;
23
<Button haha={1}></Button>;
24
+ <Button>{/** empty */}</Button>;
25
<DesignSystem.Button />;
26
27
const j = function bar([quz, qux], ...args) {};