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

Support spread elements in CallExpression args

Joe Savona committed Mar 15, 2023 at 17:13 UTC f88713bba5f935370ba398f123e1a504303e6036
15 files changed +375 -206
compiler/forget/src/HIR/BuildHIR.ts
+24 -7
@@ -916,17 +916,25 @@ function lowerExpression(
916 }
917 if (calleePath.isMemberExpression()) {
918 const { object, property } = lowerMemberExpression(builder, calleePath);
919 - let args: Place[] = [];
919 + let args: Array<Place | SpreadPattern> = [];
920 for (const argPath of expr.get("arguments")) {
921 - if (!argPath.isExpression()) {
921 + if (argPath.isSpreadElement()) {
922 + args.push({
923 + kind: "Spread",
924 + place: lowerExpressionToTemporary(
925 + builder,
926 + argPath.get("argument")
927 + ),
928 + });
929 + } else if (argPath.isExpression()) {
930 + args.push(lowerExpressionToTemporary(builder, argPath));
931 + } else {
932 builder.errors.push({
933 reason: `(BuildHIR::lowerExpression) Handle ${argPath.type} arguments in CallExpression`,
934 severity: ErrorSeverity.Todo,
935 nodePath: argPath,
936 });
927 - continue;
937 }
929 - args.push(lowerExpressionToTemporary(builder, argPath));
938 }
939 if (typeof property === "string") {
940 return {
@@ -947,9 +955,19 @@ function lowerExpression(
955 }
956 } else {
957 const callee = lowerExpressionToTemporary(builder, calleePath);
950 - let args: Place[] = [];
958 + let args: Array<Place | SpreadPattern> = [];
959 for (const argPath of expr.get("arguments")) {
952 - if (!argPath.isExpression()) {
960 + if (argPath.isSpreadElement()) {
961 + args.push({
962 + kind: "Spread",
963 + place: lowerExpressionToTemporary(
964 + builder,
965 + argPath.get("argument")
966 + ),
967 + });
968 + } else if (argPath.isExpression()) {
969 + args.push(lowerExpressionToTemporary(builder, argPath));
970 + } else {
971 builder.errors.push({
972 reason: `(BuildHIR::lowerExpression) Handle ${argPath.type} arguments in CallExpression`,
973 severity: ErrorSeverity.Todo,
@@ -957,7 +975,6 @@ function lowerExpression(
975 });
976 continue;
977 }
960 - args.push(lowerExpressionToTemporary(builder, argPath));
978 }
979 return {
980 kind: "CallExpression",
compiler/forget/src/HIR/HIR.ts
+3 -3
@@ -480,21 +480,21 @@ export type InstructionValue =
480 | {
481 kind: "CallExpression";
482 callee: Place;
483 - args: Array<Place>;
483 + args: Array<Place | SpreadPattern>;
484 loc: SourceLocation;
485 }
486 | {
487 kind: "PropertyCall";
488 receiver: Place;
489 property: string;
490 - args: Array<Place>;
490 + args: Array<Place | SpreadPattern>;
491 loc: SourceLocation;
492 }
493 | {
494 kind: "ComputedCall";
495 receiver: Place;
496 property: Place;
497 - args: Array<Place>;
497 + args: Array<Place | SpreadPattern>;
498 loc: SourceLocation;
499 }
500 | {
compiler/forget/src/HIR/PrintHIR.ts
+3 -3
@@ -258,20 +258,20 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
258 }
259 case "CallExpression": {
260 value = `Call ${printPlace(instrValue.callee)}(${instrValue.args
261 - .map((arg) => printPlace(arg))
261 + .map((arg) => printPattern(arg))
262 .join(", ")})`;
263 break;
264 }
265 case "PropertyCall": {
266 value = `PropertyCall ${printPlace(instrValue.receiver)}.${
267 instrValue.property
268 - }(${instrValue.args.map((arg) => printPlace(arg)).join(", ")})`;
268 + }(${instrValue.args.map((arg) => printPattern(arg)).join(", ")})`;
269 break;
270 }
271 case "ComputedCall": {
272 value = `ComputedCall ${printPlace(instrValue.receiver)}[${printPlace(
273 instrValue.property
274 - )}](${instrValue.args.map((arg) => printPlace(arg)).join(", ")})`;
274 + )}](${instrValue.args.map((arg) => printPattern(arg)).join(", ")})`;
275 break;
276 }
277 case "JSXText":
compiler/forget/src/HIR/visitors.ts
+33 -6
@@ -14,6 +14,7 @@ import {
14 Pattern,
15 Place,
16 ReactiveInstruction,
17 + SpreadPattern,
18 Terminal,
19 } from "./HIR";
20
@@ -45,7 +46,7 @@ export function* eachInstructionValueOperand(
46 case "NewExpression":
47 case "CallExpression": {
48 yield instrValue.callee;
48 - yield* instrValue.args;
49 + yield* eachCallArgument(instrValue.args);
50 break;
51 }
52 case "BinaryExpression": {
@@ -55,13 +56,13 @@ export function* eachInstructionValueOperand(
56 }
57 case "PropertyCall": {
58 yield instrValue.receiver;
58 - yield* instrValue.args;
59 + yield* eachCallArgument(instrValue.args);
60 break;
61 }
62 case "ComputedCall": {
63 yield instrValue.receiver;
64 yield instrValue.property;
64 - yield* instrValue.args;
65 + yield* eachCallArgument(instrValue.args);
66 break;
67 }
68 case "LoadLocal": {
@@ -185,6 +186,18 @@ export function* eachInstructionValueOperand(
186 }
187 }
188
189 +export function* eachCallArgument(
190 + args: Array<Place | SpreadPattern>
191 +): Iterable<Place> {
192 + for (const arg of args) {
193 + if (arg.kind === "Identifier") {
194 + yield arg;
195 + } else {
196 + yield arg.place;
197 + }
198 + }
199 +}
200 +
201 export function doesPatternContainSpreadElement(pattern: Pattern): boolean {
202 switch (pattern.kind) {
203 case "ArrayPattern": {
@@ -331,18 +344,18 @@ export function mapInstructionOperands(
344 case "NewExpression":
345 case "CallExpression": {
346 instrValue.callee = fn(instrValue.callee);
334 - instrValue.args = instrValue.args.map((arg) => fn(arg));
347 + instrValue.args = mapCallArguments(instrValue.args, fn);
348 break;
349 }
350 case "PropertyCall": {
351 instrValue.receiver = fn(instrValue.receiver);
339 - instrValue.args = instrValue.args.map((arg) => fn(arg));
352 + instrValue.args = mapCallArguments(instrValue.args, fn);
353 break;
354 }
355 case "ComputedCall": {
356 instrValue.receiver = fn(instrValue.receiver);
357 instrValue.property = fn(instrValue.property);
345 - instrValue.args = instrValue.args.map((arg) => fn(arg));
358 + instrValue.args = mapCallArguments(instrValue.args, fn);
359 break;
360 }
361 case "UnaryExpression": {
@@ -423,6 +436,20 @@ export function mapInstructionOperands(
436 }
437 }
438
439 +export function mapCallArguments(
440 + args: Array<Place | SpreadPattern>,
441 + fn: (place: Place) => Place
442 +): Array<Place | SpreadPattern> {
443 + return args.map((arg) => {
444 + if (arg.kind === "Identifier") {
445 + return fn(arg);
446 + } else {
447 + arg.place = fn(arg.place);
448 + return arg;
449 + }
450 + });
451 +}
452 +
453 export function mapPatternOperands(
454 pattern: Pattern,
455 fn: (place: Place) => Place
compiler/forget/src/Inference/DropMemoCalls.ts
+21 -17
@@ -21,14 +21,16 @@ export default function (func: HIRFunction): void {
21 //
22 // after:
23 // foo = Call $9()
24 - instr.value = {
25 - kind: "CallExpression",
26 - callee: fn,
27 - // Drop the args, including the deps array which DCE will remove
28 - // later.
29 - args: [],
30 - loc: instr.value.loc,
31 - };
24 + if (fn.kind === "Identifier") {
25 + instr.value = {
26 + kind: "CallExpression",
27 + callee: fn,
28 + // Drop the args, including the deps array which DCE will remove
29 + // later.
30 + args: [],
31 + loc: instr.value.loc,
32 + };
33 + }
34 } else if (name === "useCallback") {
35 const [fn] = instr.value.args;
36
@@ -39,16 +41,18 @@ export default function (func: HIRFunction): void {
41 //
42 // after:
43 // foo = $19
42 - instr.value = {
43 - kind: "LoadLocal",
44 - place: {
45 - kind: "Identifier",
46 - identifier: fn.identifier,
47 - effect: Effect.Unknown,
44 + if (fn.kind === "Identifier") {
45 + instr.value = {
46 + kind: "LoadLocal",
47 + place: {
48 + kind: "Identifier",
49 + identifier: fn.identifier,
50 + effect: Effect.Unknown,
51 + loc: instr.value.loc,
52 + },
53 loc: instr.value.loc,
49 - },
50 - loc: instr.value.loc,
51 - };
54 + };
55 + }
56 }
57 }
58 }
compiler/forget/src/Inference/InferReferenceEffects.ts
+10 -2
@@ -673,7 +673,11 @@ function inferBlock(
673
674 state.reference(instrValue.receiver, Effect.Mutate);
675 for (const arg of instrValue.args) {
676 - state.reference(arg, Effect.Mutate);
676 + if (arg.kind === "Identifier") {
677 + state.reference(arg, Effect.Mutate);
678 + } else {
679 + state.reference(arg.place, Effect.Mutate);
680 + }
681 }
682 state.initialize(instrValue, ValueKind.Mutable);
683 state.define(instr.lvalue, instrValue);
@@ -695,7 +699,11 @@ function inferBlock(
699 state.reference(instrValue.receiver, Effect.Mutate);
700 state.reference(instrValue.property, Effect.Read);
701 for (const arg of instrValue.args) {
698 - state.reference(arg, Effect.Mutate);
702 + if (arg.kind === "Identifier") {
703 + state.reference(arg, Effect.Mutate);
704 + } else {
705 + state.reference(arg.place, Effect.Mutate);
706 + }
707 }
708 state.initialize(instrValue, ValueKind.Mutable);
709 state.define(instr.lvalue, instrValue);
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+14 -3
@@ -556,7 +556,7 @@ function codegenInstructionValue(
556 }
557 case "CallExpression": {
558 const callee = codegenPlace(cx, instrValue.callee);
559 - const args = instrValue.args.map((arg) => codegenPlace(cx, arg));
559 + const args = instrValue.args.map((arg) => codegenArgument(cx, arg));
560 value = createCallExpression(instrValue.loc, callee, args);
561 break;
562 }
@@ -566,7 +566,7 @@ function codegenInstructionValue(
566 receiver,
567 t.identifier(instrValue.property)
568 );
569 - const args = instrValue.args.map((arg) => codegenPlace(cx, arg));
569 + const args = instrValue.args.map((arg) => codegenArgument(cx, arg));
570 value = createCallExpression(instrValue.loc, callee, args);
571 break;
572 }
@@ -574,7 +574,7 @@ function codegenInstructionValue(
574 const receiver = codegenPlace(cx, instrValue.receiver);
575 const property = codegenPlace(cx, instrValue.property);
576 const callee = t.memberExpression(receiver, property, true);
577 - const args = instrValue.args.map((arg) => codegenPlace(cx, arg));
577 + const args = instrValue.args.map((arg) => codegenArgument(cx, arg));
578 value = createCallExpression(instrValue.loc, callee, args);
579 break;
580 }
@@ -940,6 +940,17 @@ function codegenValue(
940 }
941 }
942
943 +function codegenArgument(
944 + cx: Context,
945 + arg: Place | SpreadPattern
946 +): t.Expression | t.SpreadElement {
947 + if (arg.kind === "Identifier") {
948 + return codegenPlace(cx, arg);
949 + } else {
950 + return t.spreadElement(codegenPlace(cx, arg.place));
951 + }
952 +}
953 +
954 function codegenPlace(cx: Context, place: Place): t.Expression {
955 let tmp = cx.temp.get(place.identifier.id);
956 if (tmp != null) {
compiler/forget/src/__tests__/fixtures/compiler/call-spread.expect.md new
+33
@@ -0,0 +1,33 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const x = foo(...props.a, null, ...props.b);
7 + return x;
8 +}
9 +
10 +```
11 +
12 +## Code
13 +
14 +```javascript
15 +function Component(props) {
16 + const $ = React.unstable_useMemoCache(3);
17 + const c_0 = $[0] !== props.a;
18 + const c_1 = $[1] !== props.b;
19 + let t0;
20 + if (c_0 || c_1) {
21 + t0 = foo(...props.a, null, ...props.b);
22 + $[0] = props.a;
23 + $[1] = props.b;
24 + $[2] = t0;
25 + } else {
26 + t0 = $[2];
27 + }
28 + const x = t0;
29 + return x;
30 +}
31 +
32 +```
33 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/call-spread.js new
+4
@@ -0,0 +1,4 @@
1 +function Component(props) {
2 + const x = foo(...props.a, null, ...props.b);
3 + return x;
4 +}
compiler/forget/src/__tests__/fixtures/compiler/computed-call-spread.expect.md new
+35
@@ -0,0 +1,35 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const x = foo[props.method](...props.a, null, ...props.b);
7 + return x;
8 +}
9 +
10 +```
11 +
12 +## Code
13 +
14 +```javascript
15 +function Component(props) {
16 + const $ = React.unstable_useMemoCache(4);
17 + const c_0 = $[0] !== props.method;
18 + const c_1 = $[1] !== props.a;
19 + const c_2 = $[2] !== props.b;
20 + let t0;
21 + if (c_0 || c_1 || c_2) {
22 + t0 = foo[props.method](...props.a, null, ...props.b);
23 + $[0] = props.method;
24 + $[1] = props.a;
25 + $[2] = props.b;
26 + $[3] = t0;
27 + } else {
28 + t0 = $[3];
29 + }
30 + const x = t0;
31 + return x;
32 +}
33 +
34 +```
35 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/computed-call-spread.js new
+4
@@ -0,0 +1,4 @@
1 +function Component(props) {
2 + const x = foo[props.method](...props.a, null, ...props.b);
3 + return x;
4 +}
compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md
+154 -164
@@ -15,7 +15,6 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
15
16 const g = { b() {}, c: () => {} };
17 new c(...args);
18 - c(...args);
18 const { z, aa = "aa" } = useCustom();
19
20 <Button xlink:href="localhost:3000"></Button>;
@@ -128,251 +127,242 @@ let moduleLocal = false;
127 > 12 | const g = { b() {}, c: () => {} };
128 | ^^^^^^
129 13 | new c(...args);
131 - 14 | c(...args);
132 - 15 | const { z, aa = "aa" } = useCustom();
130 + 14 | const { z, aa = "aa" } = useCustom();
131 + 15 |
132
133 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle SpreadElement arguments in NewExpression
134 11 |
135 12 | const g = { b() {}, c: () => {} };
136 > 13 | new c(...args);
137 | ^^^^^^^
139 - 14 | c(...args);
140 - 15 | const { z, aa = "aa" } = useCustom();
141 - 16 |
142 -
143 -[ReactForget] TodoError: (BuildHIR::lowerExpression) Handle SpreadElement arguments in CallExpression
144 - 12 | const g = { b() {}, c: () => {} };
145 - 13 | new c(...args);
146 -> 14 | c(...args);
147 - | ^^^^^^^
148 - 15 | const { z, aa = "aa" } = useCustom();
149 - 16 |
150 - 17 | <Button xlink:href="localhost:3000"></Button>;
138 + 14 | const { z, aa = "aa" } = useCustom();
139 + 15 |
140 + 16 | <Button xlink:href="localhost:3000"></Button>;
141
142 [ReactForget] TodoError: (BuildHIR::lowerAssignment) Handle AssignmentPattern assignments
143 + 12 | const g = { b() {}, c: () => {} };
144 13 | new c(...args);
154 - 14 | c(...args);
155 -> 15 | const { z, aa = "aa" } = useCustom();
145 +> 14 | const { z, aa = "aa" } = useCustom();
146 | ^^^^^^^^^
157 - 16 |
158 - 17 | <Button xlink:href="localhost:3000"></Button>;
159 - 18 | <Button haha={1}></Button>;
147 + 15 |
148 + 16 | <Button xlink:href="localhost:3000"></Button>;
149 + 17 | <Button haha={1}></Button>;
150
151 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle JSXNamespacedName attribute names in JSXElement
162 - 15 | const { z, aa = "aa" } = useCustom();
163 - 16 |
164 -> 17 | <Button xlink:href="localhost:3000"></Button>;
152 + 14 | const { z, aa = "aa" } = useCustom();
153 + 15 |
154 +> 16 | <Button xlink:href="localhost:3000"></Button>;
155 | ^^^^^^^^^^
166 - 18 | <Button haha={1}></Button>;
167 - 19 | <Button>{/** empty */}</Button>;
168 - 20 | <DesignSystem.Button />;
156 + 17 | <Button haha={1}></Button>;
157 + 18 | <Button>{/** empty */}</Button>;
158 + 19 | <DesignSystem.Button />;
159
160 [ReactForget] TodoError: (BuildHIR::lowerJsxElement) Handle JSXEmptyExpression expressions
171 - 17 | <Button xlink:href="localhost:3000"></Button>;
172 - 18 | <Button haha={1}></Button>;
173 -> 19 | <Button>{/** empty */}</Button>;
161 + 16 | <Button xlink:href="localhost:3000"></Button>;
162 + 17 | <Button haha={1}></Button>;
163 +> 18 | <Button>{/** empty */}</Button>;
164 | ^^^^^^^^^^^^
175 - 20 | <DesignSystem.Button />;
176 - 21 |
177 - 22 | const j = function bar([quz, qux], ...args) {};
165 + 19 | <DesignSystem.Button />;
166 + 20 |
167 + 21 | const j = function bar([quz, qux], ...args) {};
168
169 [ReactForget] TodoError: (BuildHIR::lowerJsxElementName) Handle JSXMemberExpression tags
180 - 18 | <Button haha={1}></Button>;
181 - 19 | <Button>{/** empty */}</Button>;
182 -> 20 | <DesignSystem.Button />;
170 + 17 | <Button haha={1}></Button>;
171 + 18 | <Button>{/** empty */}</Button>;
172 +> 19 | <DesignSystem.Button />;
173 | ^^^^^^^^^^^^^^^^^^^
184 - 21 |
185 - 22 | const j = function bar([quz, qux], ...args) {};
186 - 23 |
174 + 20 |
175 + 21 | const j = function bar([quz, qux], ...args) {};
176 + 22 |
177
178 [ReactForget] TodoError: (BuildHIR::lower) Handle RestElement params
189 - 20 | <DesignSystem.Button />;
190 - 21 |
191 -> 22 | const j = function bar([quz, qux], ...args) {};
179 + 19 | <DesignSystem.Button />;
180 + 20 |
181 +> 21 | const j = function bar([quz, qux], ...args) {};
182 | ^^^^^^^
193 - 23 |
194 - 24 | for (; i < 3; i += 1) {
195 - 25 | x.push(i);
183 + 22 |
184 + 23 | for (; i < 3; i += 1) {
185 + 24 | x.push(i);
186
187 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle non-variable initialization in ForStatement
198 - 22 | const j = function bar([quz, qux], ...args) {};
199 - 23 |
200 -> 24 | for (; i < 3; i += 1) {
188 + 21 | const j = function bar([quz, qux], ...args) {};
189 + 22 |
190 +> 23 | for (; i < 3; i += 1) {
191 | ^
202 - 25 | x.push(i);
203 - 26 | }
204 - 27 | for (; i < 3; ) {
192 + 24 | x.push(i);
193 + 25 | }
194 + 26 | for (; i < 3; ) {
195
196 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle non-variable initialization in ForStatement
207 - 25 | x.push(i);
208 - 26 | }
209 -> 27 | for (; i < 3; ) {
197 + 24 | x.push(i);
198 + 25 | }
199 +> 26 | for (; i < 3; ) {
200 | ^
211 - 28 | break;
212 - 29 | }
213 - 30 | for (;;) {
201 + 27 | break;
202 + 28 | }
203 + 29 | for (;;) {
204
205 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle empty update in ForStatement
216 - 25 | x.push(i);
217 - 26 | }
218 -> 27 | for (; i < 3; ) {
206 + 24 | x.push(i);
207 + 25 | }
208 +> 26 | for (; i < 3; ) {
209 | ^
220 - 28 | break;
221 - 29 | }
222 - 30 | for (;;) {
210 + 27 | break;
211 + 28 | }
212 + 29 | for (;;) {
213
214 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle non-variable initialization in ForStatement
225 - 28 | break;
226 - 29 | }
227 -> 30 | for (;;) {
215 + 27 | break;
216 + 28 | }
217 +> 29 | for (;;) {
218 | ^
229 - 31 | break;
230 - 32 | }
231 - 33 |
219 + 30 | break;
220 + 31 | }
221 + 32 |
222
223 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle empty update in ForStatement
234 - 28 | break;
235 - 29 | }
236 -> 30 | for (;;) {
224 + 27 | break;
225 + 28 | }
226 +> 29 | for (;;) {
227 | ^
238 - 31 | break;
239 - 32 | }
240 - 33 |
228 + 30 | break;
229 + 31 | }
230 + 32 |
231
232 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle empty test in ForStatement
243 - 28 | break;
244 - 29 | }
245 -> 30 | for (;;) {
233 + 27 | break;
234 + 28 | }
235 +> 29 | for (;;) {
236 | ^
247 - 31 | break;
248 - 32 | }
249 - 33 |
237 + 30 | break;
238 + 31 | }
239 + 32 |
240
241 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle tagged template with interpolations
252 - 32 | }
253 - 33 |
254 -> 34 | graphql`
242 + 31 | }
243 + 32 |
244 +> 33 | graphql`
245 | ^
256 - 35 | ${g}
257 - 36 | `;
258 - 37 |
246 + 34 | ${g}
247 + 35 | `;
248 + 36 |
249
250 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle tagged template where cooked value is different from raw value
261 - 36 | `;
262 - 37 |
263 -> 38 | graphql`\\t\n`;
251 + 35 | `;
252 + 36 |
253 +> 37 | graphql`\\t\n`;
254 | ^^^^^^^^^^^^^^
265 - 39 |
266 - 40 | for (const c of [1, 2]) {
267 - 41 | }
255 + 38 |
256 + 39 | for (const c of [1, 2]) {
257 + 40 | }
258
259 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle ForOfStatement statements
270 - 38 | graphql`\\t\n`;
271 - 39 |
272 -> 40 | for (const c of [1, 2]) {
260 + 37 | graphql`\\t\n`;
261 + 38 |
262 +> 39 | for (const c of [1, 2]) {
263 | ^
274 - 41 | }
275 - 42 |
276 - 43 | for (let x in { a: 1 }) {
264 + 40 | }
265 + 41 |
266 + 42 | for (let x in { a: 1 }) {
267
268 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle ForInStatement statements
279 - 41 | }
280 - 42 |
281 -> 43 | for (let x in { a: 1 }) {
269 + 40 | }
270 + 41 |
271 +> 42 | for (let x in { a: 1 }) {
272 | ^
283 - 44 | }
284 - 45 |
285 - 46 | let updateIdentifier = 0;
273 + 43 | }
274 + 44 |
275 + 45 | let updateIdentifier = 0;
276
277 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle prefix UpdateExpression
288 - 45 |
289 - 46 | let updateIdentifier = 0;
290 -> 47 | --updateIdentifier;
278 + 44 |
279 + 45 | let updateIdentifier = 0;
280 +> 46 | --updateIdentifier;
281 | ^^^^^^^^^^^^^^^^^^
292 - 48 | ++updateIdentifier;
293 - 49 | updateIdentifier.y++;
294 - 50 | updateIdentifier.y--;
282 + 47 | ++updateIdentifier;
283 + 48 | updateIdentifier.y++;
284 + 49 | updateIdentifier.y--;
285
286 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle prefix UpdateExpression
297 - 46 | let updateIdentifier = 0;
298 - 47 | --updateIdentifier;
299 -> 48 | ++updateIdentifier;
287 + 45 | let updateIdentifier = 0;
288 + 46 | --updateIdentifier;
289 +> 47 | ++updateIdentifier;
290 | ^^^^^^^^^^^^^^^^^^
301 - 49 | updateIdentifier.y++;
302 - 50 | updateIdentifier.y--;
303 - 51 |
291 + 48 | updateIdentifier.y++;
292 + 49 | updateIdentifier.y--;
293 + 50 |
294
295 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle UpdateExpression with MemberExpression argument
306 - 47 | --updateIdentifier;
307 - 48 | ++updateIdentifier;
308 -> 49 | updateIdentifier.y++;
296 + 46 | --updateIdentifier;
297 + 47 | ++updateIdentifier;
298 +> 48 | updateIdentifier.y++;
299 | ^^^^^^^^^^^^^^^^^^^^
310 - 50 | updateIdentifier.y--;
311 - 51 |
312 - 52 | switch (i) {
300 + 49 | updateIdentifier.y--;
301 + 50 |
302 + 51 | switch (i) {
303
304 [ReactForget] TodoError: (BuildHIR::lowerExpression) Handle UpdateExpression with MemberExpression argument
315 - 48 | ++updateIdentifier;
316 - 49 | updateIdentifier.y++;
317 -> 50 | updateIdentifier.y--;
305 + 47 | ++updateIdentifier;
306 + 48 | updateIdentifier.y++;
307 +> 49 | updateIdentifier.y--;
308 | ^^^^^^^^^^^^^^^^^^^^
319 - 51 |
320 - 52 | switch (i) {
321 - 53 | case 1 + 1: {
309 + 50 |
310 + 51 | switch (i) {
311 + 52 | case 1 + 1: {
312
313 [ReactForget] TodoError: (BuildHIR::lowerStatement) Switch case test values must be identifiers or primitives, compound values are not yet supported
324 - 55 | case foo(): {
325 - 56 | }
326 -> 57 | case x.y: {
314 + 54 | case foo(): {
315 + 55 | }
316 +> 56 | case x.y: {
317 | ^^^
328 - 58 | }
329 - 59 | default: {
330 - 60 | }
318 + 57 | }
319 + 58 | default: {
320 + 59 | }
321
322 [ReactForget] TodoError: (BuildHIR::lowerStatement) Switch case test values must be identifiers or primitives, compound values are not yet supported
333 - 53 | case 1 + 1: {
334 - 54 | }
335 -> 55 | case foo(): {
323 + 52 | case 1 + 1: {
324 + 53 | }
325 +> 54 | case foo(): {
326 | ^^^^^
337 - 56 | }
338 - 57 | case x.y: {
339 - 58 | }
327 + 55 | }
328 + 56 | case x.y: {
329 + 57 | }
330
331 [ReactForget] TodoError: (BuildHIR::lowerStatement) Switch case test values must be identifiers or primitives, compound values are not yet supported
342 - 51 |
343 - 52 | switch (i) {
344 -> 53 | case 1 + 1: {
332 + 50 |
333 + 51 | switch (i) {
334 +> 52 | case 1 + 1: {
335 | ^^^^^
346 - 54 | }
347 - 55 | case foo(): {
348 - 56 | }
336 + 53 | }
337 + 54 | case foo(): {
338 + 55 | }
339
340 [ReactForget] InvalidInputError: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported.
351 - 62 |
352 - 63 | // Cannot assign to globals
353 -> 64 | someUnknownGlobal = true;
341 + 61 |
342 + 62 | // Cannot assign to globals
343 +> 63 | someUnknownGlobal = true;
344 | ^^^^^^^^^^^^^^^^^
355 - 65 | moduleLocal = true;
356 - 66 |
357 - 67 | function component(a) {
345 + 64 | moduleLocal = true;
346 + 65 |
347 + 66 | function component(a) {
348
349 [ReactForget] InvalidInputError: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported.
360 - 63 | // Cannot assign to globals
361 - 64 | someUnknownGlobal = true;
362 -> 65 | moduleLocal = true;
350 + 62 | // Cannot assign to globals
351 + 63 | someUnknownGlobal = true;
352 +> 64 | moduleLocal = true;
353 | ^^^^^^^^^^^
364 - 66 |
365 - 67 | function component(a) {
366 - 68 | // Add support for function declarations once we support `var` hoisting.
354 + 65 |
355 + 66 | function component(a) {
356 + 67 | // Add support for function declarations once we support `var` hoisting.
357
358 [ReactForget] TodoError: (BuildHIR::lowerStatement) Handle FunctionDeclaration statements
369 - 65 | moduleLocal = true;
370 - 66 |
371 -> 67 | function component(a) {
359 + 64 | moduleLocal = true;
360 + 65 |
361 +> 66 | function component(a) {
362 | ^
373 - 68 | // Add support for function declarations once we support `var` hoisting.
374 - 69 | function t() {}
375 - 70 | t();
363 + 67 | // Add support for function declarations once we support `var` hoisting.
364 + 68 | function t() {}
365 + 69 | t();
366 ```
367
368
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.js
-1
@@ -11,7 +11,6 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
11
12 const g = { b() {}, c: () => {} };
13 new c(...args);
14 - c(...args);
14 const { z, aa = "aa" } = useCustom();
15
16 <Button xlink:href="localhost:3000"></Button>;
compiler/forget/src/__tests__/fixtures/compiler/property-call-spread.expect.md new
+33
@@ -0,0 +1,33 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const x = foo.bar(...props.a, null, ...props.b);
7 + return x;
8 +}
9 +
10 +```
11 +
12 +## Code
13 +
14 +```javascript
15 +function Component(props) {
16 + const $ = React.unstable_useMemoCache(3);
17 + const c_0 = $[0] !== props.a;
18 + const c_1 = $[1] !== props.b;
19 + let t0;
20 + if (c_0 || c_1) {
21 + t0 = foo.bar(...props.a, null, ...props.b);
22 + $[0] = props.a;
23 + $[1] = props.b;
24 + $[2] = t0;
25 + } else {
26 + t0 = $[2];
27 + }
28 + const x = t0;
29 + return x;
30 +}
31 +
32 +```
33 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/property-call-spread.js new
+4
@@ -0,0 +1,4 @@
1 +function Component(props) {
2 + const x = foo.bar(...props.a, null, ...props.b);
3 + return x;
4 +}