Support ObjectPattern within RestElement
Supports ObjectPattern within RestElement, the `...{y}` in `const [x, ...{y}] = z`
Joe Savona committed
Sep 11, 2023 at 13:03 UTC
911c9884536afe0333c3d88d93a591e14efe88ba
3 files changed
+89
-21
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+24
-21
@@ -2910,28 +2910,31 @@ function lowerAssignment(
2910
}
2911
if (element.isRestElement()) {
2912
const argument = element.get("argument");
2913
- if (!argument.isIdentifier()) {
2914
- builder.errors.push({
2915
- reason: `(BuildHIR::lowerAssignment) Handle ${argument.node.type} rest element in ArrayPattern`,
2916
- severity: ErrorSeverity.Todo,
2917
- loc: element.node.loc ?? null,
2918
- suggestions: null,
2913
+ if (argument.isIdentifier()) {
2914
+ const identifier = lowerIdentifierForAssignment(
2915
+ builder,
2916
+ element.node.loc ?? GeneratedSource,
2917
+ kind,
2918
+ argument
2919
+ );
2920
+ if (identifier === null) {
2921
+ continue;
2922
+ }
2923
+ items.push({
2924
+ kind: "Spread",
2925
+ place: identifier,
2926
});
2920
- continue;
2921
- }
2922
- const identifier = lowerIdentifierForAssignment(
2923
- builder,
2924
- element.node.loc ?? GeneratedSource,
2925
- kind,
2926
- argument
2927
- );
2928
- if (identifier === null) {
2929
- continue;
2927
+ } else {
2928
+ const temp = buildTemporaryPlace(
2929
+ builder,
2930
+ element.node.loc ?? GeneratedSource
2931
+ );
2932
+ items.push({
2933
+ kind: "Spread",
2934
+ place: { ...temp },
2935
+ });
2936
+ followups.push({ place: temp, path: argument as NodePath<t.LVal> }); // TODO remove type cast
2937
}
2931
- items.push({
2932
- kind: "Spread",
2933
- place: identifier,
2934
- });
2938
} else if (element.isIdentifier()) {
2939
const identifier = lowerIdentifierForAssignment(
2940
builder,
@@ -2980,7 +2983,7 @@ function lowerAssignment(
2983
const argument = property.get("argument");
2984
if (!argument.isIdentifier()) {
2985
builder.errors.push({
2983
- reason: `(BuildHIR::lowerAssignment) Handle ${argument.node.type} rest element in ArrayPattern`,
2986
+ reason: `(BuildHIR::lowerAssignment) Handle ${argument.node.type} rest element in ObjectPattern`,
2987
severity: ErrorSeverity.Todo,
2988
loc: argument.node.loc ?? null,
2989
suggestions: null,
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/destructuring-object-pattern-within-rest.expect.md
new
+56
@@ -0,0 +1,56 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function Component(props) {
6
+ const [y, ...{ z }] = props.value;
7
+ return [y, z];
8
+}
9
+
10
+export const FIXTURE_ENTRYPOINT = {
11
+ fn: Component,
12
+ params: [{ value: ["y", { z: "z!" }] }],
13
+};
14
+
15
+```
16
+
17
+## Code
18
+
19
+```javascript
20
+import { unstable_useMemoCache as useMemoCache } from "react";
21
+function Component(props) {
22
+ const $ = useMemoCache(6);
23
+ const c_0 = $[0] !== props.value;
24
+ let t0;
25
+ let y;
26
+ if (c_0) {
27
+ [y, ...t0] = props.value;
28
+ $[0] = props.value;
29
+ $[1] = t0;
30
+ $[2] = y;
31
+ } else {
32
+ t0 = $[1];
33
+ y = $[2];
34
+ }
35
+ const { z } = t0;
36
+ const c_3 = $[3] !== y;
37
+ const c_4 = $[4] !== z;
38
+ let t1;
39
+ if (c_3 || c_4) {
40
+ t1 = [y, z];
41
+ $[3] = y;
42
+ $[4] = z;
43
+ $[5] = t1;
44
+ } else {
45
+ t1 = $[5];
46
+ }
47
+ return t1;
48
+}
49
+
50
+export const FIXTURE_ENTRYPOINT = {
51
+ fn: Component,
52
+ params: [{ value: ["y", { z: "z!" }] }],
53
+};
54
+
55
+```
56
+
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/destructuring-object-pattern-within-rest.js
new
+9
@@ -0,0 +1,9 @@
1
+function Component(props) {
2
+ const [y, ...{ z }] = props.value;
3
+ return [y, z];
4
+}
5
+
6
+export const FIXTURE_ENTRYPOINT = {
7
+ fn: Component,
8
+ params: [{ value: ["y", { z: "z!" }] }],
9
+};