Collect bailouts in BuildHIR::lowerMemberExpression
Lauren Tan committed
Jan 20, 2023 at 11:47 UTC
9697e15bd556dc50e5a6b355765de0bcb270fb3a
3 files changed
+142
-108
compiler/forget/src/HIR/BuildHIR.ts
+30
-6
@@ -1388,11 +1388,23 @@ function lowerMemberExpression(
1388
builder: HIRBuilder,
1389
expr: NodePath<t.MemberExpression>
1390
): { object: Place; property: Place | string; value: InstructionValue } {
1391
- const exprLoc = expr.node.loc ?? GeneratedSource;
1391
+ const exprNode = expr.node;
1392
+ const exprLoc = exprNode.loc ?? GeneratedSource;
1393
const object = lowerExpressionToPlace(builder, expr.get("object"));
1394
const property = expr.get("property");
1395
if (!expr.node.computed) {
1395
- todoInvariant(property.isIdentifier(), "Support private names");
1396
+ if (!property.isIdentifier()) {
1397
+ builder.pushError({
1398
+ reason: "Support private names",
1399
+ severity: ErrorSeverity.Todo,
1400
+ nodePath: property,
1401
+ });
1402
+ return {
1403
+ object,
1404
+ property: property.toString(),
1405
+ value: { kind: "UnsupportedNode", node: exprNode, loc: exprLoc },
1406
+ };
1407
+ }
1408
const value: InstructionValue = {
1409
kind: "PropertyLoad",
1410
object: { ...object },
@@ -1401,10 +1413,22 @@ function lowerMemberExpression(
1413
};
1414
return { object, property: property.node.name, value };
1415
} else {
1404
- invariant(
1405
- property.isExpression(),
1406
- "Expected private names to be non-computed"
1407
- );
1416
+ if (!property.isExpression()) {
1417
+ builder.pushError({
1418
+ reason: "Expected private names to be non-computed",
1419
+ severity: ErrorSeverity.InvalidInput,
1420
+ nodePath: property,
1421
+ });
1422
+ return {
1423
+ object,
1424
+ property: property.toString(),
1425
+ value: {
1426
+ kind: "UnsupportedNode",
1427
+ node: exprNode,
1428
+ loc: exprLoc,
1429
+ },
1430
+ };
1431
+ }
1432
const propertyPlace = lowerExpressionToPlace(builder, property);
1433
const value: InstructionValue = {
1434
kind: "ComputedLoad",
compiler/forget/src/__tests__/fixtures/hir/error.todo-kitchensink.expect.md
+106
-101
@@ -6,7 +6,12 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
6
let i = 0;
7
var x = [];
8
9
- class Bar {}
9
+ class Bar {
10
+ #secretSauce = 42;
11
+ constructor() {
12
+ console.log(this.#secretSauce);
13
+ }
14
+ }
15
16
with (true) {
17
}
@@ -70,158 +75,158 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
75
> 3 | var x = [];
76
| ^^^^^^^^^^^
77
4 |
73
- 5 | class Bar {}
74
- 6 |
78
+ 5 | class Bar {
79
+ 6 | #secretSauce = 42;
80
81
[ReactForget] TodoError: Unhandled statement type: ClassDeclaration
82
3 | var x = [];
83
4 |
79
-> 5 | class Bar {}
80
- | ^^^^^^^^^^^^
81
- 6 |
82
- 7 | with (true) {
83
- 8 | }
84
+> 5 | class Bar {
85
+ | ^
86
+ 6 | #secretSauce = 42;
87
+ 7 | constructor() {
88
+ 8 | console.log(this.#secretSauce);
89
90
[ReactForget] TodoError: Unhandled statement type: WithStatement
86
- 5 | class Bar {}
87
- 6 |
88
-> 7 | with (true) {
91
+ 10 | }
92
+ 11 |
93
+> 12 | with (true) {
94
| ^
90
- 8 | }
91
- 9 |
92
- 10 | const g = { ...a };
95
+ 13 | }
96
+ 14 |
97
+ 15 | const g = { ...a };
98
99
[ReactForget] TodoError: Handle object property spread
95
- 8 | }
96
- 9 |
97
-> 10 | const g = { ...a };
100
+ 13 | }
101
+ 14 |
102
+> 15 | const g = { ...a };
103
| ^^^^
99
- 11 | const h = [...b];
100
- 12 | new c(...args);
101
- 13 | c(...args);
104
+ 16 | const h = [...b];
105
+ 17 | new c(...args);
106
+ 18 | c(...args);
107
108
[ReactForget] TodoError: Handle non-expression array elements
104
- 9 |
105
- 10 | const g = { ...a };
106
-> 11 | const h = [...b];
109
+ 14 |
110
+ 15 | const g = { ...a };
111
+> 16 | const h = [...b];
112
| ^^^^
108
- 12 | new c(...args);
109
- 13 | c(...args);
110
- 14 | g["e"] += 1;
113
+ 17 | new c(...args);
114
+ 18 | c(...args);
115
+ 19 | g["e"] += 1;
116
117
[ReactForget] TodoError: Support non-expression arguments to NewExpression
113
- 10 | const g = { ...a };
114
- 11 | const h = [...b];
115
-> 12 | new c(...args);
118
+ 15 | const g = { ...a };
119
+ 16 | const h = [...b];
120
+> 17 | new c(...args);
121
| ^^^^^^^
117
- 13 | c(...args);
118
- 14 | g["e"] += 1;
119
- 15 |
122
+ 18 | c(...args);
123
+ 19 | g["e"] += 1;
124
+ 20 |
125
126
[ReactForget] TodoError: Support non-expression arguments to CallExpression
122
- 11 | const h = [...b];
123
- 12 | new c(...args);
124
-> 13 | c(...args);
127
+ 16 | const h = [...b];
128
+ 17 | new c(...args);
129
+> 18 | c(...args);
130
| ^^^^^^^
126
- 14 | g["e"] += 1;
127
- 15 |
128
- 16 | <Button {...args}></Button>;
131
+ 19 | g["e"] += 1;
132
+ 20 |
133
+ 21 | <Button {...args}></Button>;
134
135
[ReactForget] TodoError: Assignment expression to dynamic properties is not yet supported
131
- 12 | new c(...args);
132
- 13 | c(...args);
133
-> 14 | g["e"] += 1;
136
+ 17 | new c(...args);
137
+ 18 | c(...args);
138
+> 19 | g["e"] += 1;
139
| ^^^
135
- 15 |
136
- 16 | <Button {...args}></Button>;
137
- 17 | <Button xlink:href="localhost:3000"></Button>;
140
+ 20 |
141
+ 21 | <Button {...args}></Button>;
142
+ 22 | <Button xlink:href="localhost:3000"></Button>;
143
144
[ReactForget] TodoError: Handle spread attributes
140
- 14 | g["e"] += 1;
141
- 15 |
142
-> 16 | <Button {...args}></Button>;
145
+ 19 | g["e"] += 1;
146
+ 20 |
147
+> 21 | <Button {...args}></Button>;
148
| ^^^^^^^^^
144
- 17 | <Button xlink:href="localhost:3000"></Button>;
145
- 18 | <Button haha={1}></Button>;
146
- 19 |
149
+ 22 | <Button xlink:href="localhost:3000"></Button>;
150
+ 23 | <Button haha={1}></Button>;
151
+ 24 |
152
153
[ReactForget] TodoError: Handle non-identifier jsx attribute names
149
- 15 |
150
- 16 | <Button {...args}></Button>;
151
-> 17 | <Button xlink:href="localhost:3000"></Button>;
154
+ 20 |
155
+ 21 | <Button {...args}></Button>;
156
+> 22 | <Button xlink:href="localhost:3000"></Button>;
157
| ^^^^^^^^^^
153
- 18 | <Button haha={1}></Button>;
154
- 19 |
155
- 20 | const j = function bar([quz, qux], ...args) {};
158
+ 23 | <Button haha={1}></Button>;
159
+ 24 |
160
+ 25 | const j = function bar([quz, qux], ...args) {};
161
162
[ReactForget] TodoError: Handle non identifier params
158
- 18 | <Button haha={1}></Button>;
159
- 19 |
160
-> 20 | const j = function bar([quz, qux], ...args) {};
163
+ 23 | <Button haha={1}></Button>;
164
+ 24 |
165
+> 25 | const j = function bar([quz, qux], ...args) {};
166
| ^^^^^^^^^^
162
- 21 |
163
- 22 | for (; i < 3; i += 1) {
164
- 23 | x.push(i);
167
+ 26 |
168
+ 27 | for (; i < 3; i += 1) {
169
+ 28 | x.push(i);
170
171
[ReactForget] TodoError: Handle non identifier params
167
- 18 | <Button haha={1}></Button>;
168
- 19 |
169
-> 20 | const j = function bar([quz, qux], ...args) {};
172
+ 23 | <Button haha={1}></Button>;
173
+ 24 |
174
+> 25 | const j = function bar([quz, qux], ...args) {};
175
| ^^^^^^^
171
- 21 |
172
- 22 | for (; i < 3; i += 1) {
173
- 23 | x.push(i);
176
+ 26 |
177
+ 27 | for (; i < 3; i += 1) {
178
+ 28 | x.push(i);
179
180
[ReactForget] TodoError: Support non-variable initialization in for
176
- 20 | const j = function bar([quz, qux], ...args) {};
177
- 21 |
178
-> 22 | for (; i < 3; i += 1) {
181
+ 25 | const j = function bar([quz, qux], ...args) {};
182
+ 26 |
183
+> 27 | for (; i < 3; i += 1) {
184
| ^
180
- 23 | x.push(i);
181
- 24 | }
182
- 25 | for (; i < 3; ) {}
185
+ 28 | x.push(i);
186
+ 29 | }
187
+ 30 | for (; i < 3; ) {}
188
189
[ReactForget] TodoError: Support non-variable initialization in for
185
- 23 | x.push(i);
186
- 24 | }
187
-> 25 | for (; i < 3; ) {}
190
+ 28 | x.push(i);
191
+ 29 | }
192
+> 30 | for (; i < 3; ) {}
193
| ^^^^^^^^^^^^^^^^^^
189
- 26 | for (;;) {}
190
- 27 | }
191
- 28 |
194
+ 31 | for (;;) {}
195
+ 32 | }
196
+ 33 |
197
198
[ReactForget] TodoError: Handle empty for updater
194
- 23 | x.push(i);
195
- 24 | }
196
-> 25 | for (; i < 3; ) {}
199
+ 28 | x.push(i);
200
+ 29 | }
201
+> 30 | for (; i < 3; ) {}
202
| ^^^^^^^^^^^^^^^^^^
198
- 26 | for (;;) {}
199
- 27 | }
200
- 28 |
203
+ 31 | for (;;) {}
204
+ 32 | }
205
+ 33 |
206
207
[ReactForget] TodoError: Support non-variable initialization in for
203
- 24 | }
204
- 25 | for (; i < 3; ) {}
205
-> 26 | for (;;) {}
208
+ 29 | }
209
+ 30 | for (; i < 3; ) {}
210
+> 31 | for (;;) {}
211
| ^^^^^^^^^^^
207
- 27 | }
208
- 28 |
212
+ 32 | }
213
+ 33 |
214
215
[ReactForget] TodoError: Handle empty for updater
211
- 24 | }
212
- 25 | for (; i < 3; ) {}
213
-> 26 | for (;;) {}
216
+ 29 | }
217
+ 30 | for (; i < 3; ) {}
218
+> 31 | for (;;) {}
219
| ^^^^^^^^^^^
215
- 27 | }
216
- 28 |
220
+ 32 | }
221
+ 33 |
222
223
[ReactForget] TodoError: ForStatement without test
219
- 24 | }
220
- 25 | for (; i < 3; ) {}
221
-> 26 | for (;;) {}
224
+ 29 | }
225
+ 30 | for (; i < 3; ) {}
226
+> 31 | for (;;) {}
227
| ^^^^^^^^^^^
223
- 27 | }
224
- 28 |
228
+ 32 | }
229
+ 33 |
230
```
231
232
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/error.todo-kitchensink.js
+6
-1
@@ -2,7 +2,12 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
2
let i = 0;
3
var x = [];
4
5
- class Bar {}
5
+ class Bar {
6
+ #secretSauce = 42;
7
+ constructor() {
8
+ console.log(this.#secretSauce);
9
+ }
10
+ }
11
12
with (true) {
13
}