From 17bf6db5419a312577687dcca69a13a2c4ad478f Mon Sep 17 00:00:00 2001 From: Nguyen Tran <88808276+ngtr6788@users.noreply.github.com> Date: Thu, 4 May 2023 07:19:10 -0400 Subject: [PATCH] fix: Array rest property fix (#8553) Fixes #8552 --- src/compiler/compile/Component.ts | 18 ++++++---- .../array-rest-is-array-or-object/_config.js | 12 +++++++ .../array-rest-is-array-or-object/main.svelte | 15 ++++++++ .../samples/destructured-props-4/A.svelte | 25 +++++++++++++ .../samples/destructured-props-4/_config.js | 9 +++++ .../samples/destructured-props-4/main.svelte | 7 ++++ .../samples/destructured-props-5/A.svelte | 23 ++++++++++++ .../samples/destructured-props-5/_config.js | 19 ++++++++++ .../samples/destructured-props-5/main.svelte | 36 +++++++++++++++++++ 9 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 test/runtime/samples/array-rest-is-array-or-object/_config.js create mode 100644 test/runtime/samples/array-rest-is-array-or-object/main.svelte create mode 100644 test/runtime/samples/destructured-props-4/A.svelte create mode 100644 test/runtime/samples/destructured-props-4/_config.js create mode 100644 test/runtime/samples/destructured-props-4/main.svelte create mode 100644 test/runtime/samples/destructured-props-5/A.svelte create mode 100644 test/runtime/samples/destructured-props-5/_config.js create mode 100644 test/runtime/samples/destructured-props-5/main.svelte diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index e87cf6218a..a756f8e3c4 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -25,7 +25,7 @@ import TemplateScope from './nodes/shared/TemplateScope'; import fuzzymatch from '../utils/fuzzymatch'; import get_object from './utils/get_object'; import Slot from './nodes/Slot'; -import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression } from 'estree'; +import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression, Pattern, Expression } from 'estree'; import add_to_set from './utils/add_to_set'; import check_graph_for_cycles from './utils/check_graph_for_cycles'; import { print, b } from 'code-red'; @@ -1034,7 +1034,7 @@ export default class Component { const inserts = []; const props = []; - function add_new_props(exported, local, default_value) { + function add_new_props(exported: Identifier, local: Pattern, default_value: Expression) { props.push({ type: 'Property', method: false, @@ -1064,7 +1064,7 @@ export default class Component { for (let index = 0; index < node.declarations.length; index++) { const declarator = node.declarations[index]; if (declarator.id.type !== 'Identifier') { - function get_new_name(local) { + function get_new_name(local: Identifier): Identifier { const variable = component.var_lookup.get(local.name); if (variable.subscribable) { inserts.push(get_insert(variable)); @@ -1078,7 +1078,7 @@ export default class Component { return local; } - function rename_identifiers(param: Node) { + function rename_identifiers(param: Pattern) { switch (param.type) { case 'ObjectPattern': { const handle_prop = (prop: Property | RestElement) => { @@ -1087,7 +1087,7 @@ export default class Component { } else if (prop.value.type === 'Identifier') { prop.value = get_new_name(prop.value); } else { - rename_identifiers(prop.value); + rename_identifiers(prop.value as Pattern); } }; @@ -1095,7 +1095,7 @@ export default class Component { break; } case 'ArrayPattern': { - const handle_element = (element: Node, index: number, array: Node[]) => { + const handle_element = (element: Pattern | null, index: number, array: Array) => { if (element) { if (element.type === 'Identifier') { array[index] = get_new_name(element); @@ -1110,7 +1110,11 @@ export default class Component { } case 'RestElement': - param.argument = get_new_name(param.argument); + if (param.argument.type === 'Identifier') { + param.argument = get_new_name(param.argument); + } else { + rename_identifiers(param.argument); + } break; case 'AssignmentPattern': diff --git a/test/runtime/samples/array-rest-is-array-or-object/_config.js b/test/runtime/samples/array-rest-is-array-or-object/_config.js new file mode 100644 index 0000000000..c971e109ce --- /dev/null +++ b/test/runtime/samples/array-rest-is-array-or-object/_config.js @@ -0,0 +1,12 @@ +export default { + html: ` +

1

+

2

+

3

+

5

+

10

+

20

+

30

+

6

+ ` +}; diff --git a/test/runtime/samples/array-rest-is-array-or-object/main.svelte b/test/runtime/samples/array-rest-is-array-or-object/main.svelte new file mode 100644 index 0000000000..fb3a5b7d85 --- /dev/null +++ b/test/runtime/samples/array-rest-is-array-or-object/main.svelte @@ -0,0 +1,15 @@ + + +

{first}

+

{second}

+

{third}

+

{fifth}

+ +

{one}

+

{two}

+

{three}

+

{length}

+ diff --git a/test/runtime/samples/destructured-props-4/A.svelte b/test/runtime/samples/destructured-props-4/A.svelte new file mode 100644 index 0000000000..ab5e6b7689 --- /dev/null +++ b/test/runtime/samples/destructured-props-4/A.svelte @@ -0,0 +1,25 @@ + + +
+a: {a}, +b: {typeof b}, +c: {c}, +d_one: {d_one}, +d_three: {$d_three}, +length: {length}, +f: {f}, +g: {g}, +e: {typeof e}, +e_one: {e_one}, +A: {A}, +C: {C} +
+
{JSON.stringify(THING)}
diff --git a/test/runtime/samples/destructured-props-4/_config.js b/test/runtime/samples/destructured-props-4/_config.js new file mode 100644 index 0000000000..2c48ac5b3a --- /dev/null +++ b/test/runtime/samples/destructured-props-4/_config.js @@ -0,0 +1,9 @@ +export default { + html: ` +
a: 1, b: undefined, c: 2, d_one: 3, d_three: 5, length: 2, f: undefined, g: 9, e: undefined, e_one: 6, A: 1, C: 2
+
{"a":1,"b":{"c":2,"d":[3,4,{},6,7]},"e":[6],"h":8}
+
+
a: a, b: undefined, c: 2, d_one: d_one, d_three: 5, length: 7, f: f, g: g, e: undefined, e_one: 6, A: 1, C: 2
+
{"a":1,"b":{"c":2,"d":[3,4,{},6,7]},"e":[6],"h":8}
+ ` +}; diff --git a/test/runtime/samples/destructured-props-4/main.svelte b/test/runtime/samples/destructured-props-4/main.svelte new file mode 100644 index 0000000000..cc1a31f542 --- /dev/null +++ b/test/runtime/samples/destructured-props-4/main.svelte @@ -0,0 +1,7 @@ + + + +
+
diff --git a/test/runtime/samples/destructured-props-5/A.svelte b/test/runtime/samples/destructured-props-5/A.svelte new file mode 100644 index 0000000000..898ce5aa3d --- /dev/null +++ b/test/runtime/samples/destructured-props-5/A.svelte @@ -0,0 +1,23 @@ + + +
+ x: {x}, list_two_a: {list_two_a}, list_two_b: {list_two_b}, y: {y}, l: {l}, m: {m}, + n: {n}, o: {o}, p: {p}, q: {$q}, r: {$r}, s: {s} +
+
{JSON.stringify(LIST)}
diff --git a/test/runtime/samples/destructured-props-5/_config.js b/test/runtime/samples/destructured-props-5/_config.js new file mode 100644 index 0000000000..6c8ca89216 --- /dev/null +++ b/test/runtime/samples/destructured-props-5/_config.js @@ -0,0 +1,19 @@ +export default { + html: ` +
x: 1, list_two_a: 4, list_two_b: 5, y: 3, l: 1, m: 2, n: 4, o: 5, p: 5, q: 6, r: 7, s: 1
+
[1,2,3,{"a":4},[5,{},{},8]]
+
x: 1, list_two_a: 4, list_two_b: 5, y: 3, l: l, m: m, n: n, o: o, p: p, q: q, r: r, s: s
+
[1,2,3,{"a":4},[5,{},{},8]]
+ `, + + async test({ component, assert, target }) { + await component.update(); + + assert.htmlEqual(target.innerHTML, ` +
x: 1, list_two_a: 4, list_two_b: 5, y: 3, l: 1, m: 2, n: 4, o: 5, p: 5, q: 6, r: 7, s: 1
+
[1,2,3,{"a":4},[5,{},{},8]]
+
x: 1, list_two_a: 4, list_two_b: 5, y: 3, l: LL, m: MM, n: NN, o: OO, p: PP, q: QQ, r: RR, s: SS
+
[1,2,3,{"a":4},[5,{},{},8]]
+ `); + } +}; diff --git a/test/runtime/samples/destructured-props-5/main.svelte b/test/runtime/samples/destructured-props-5/main.svelte new file mode 100644 index 0000000000..a8b9e8a704 --- /dev/null +++ b/test/runtime/samples/destructured-props-5/main.svelte @@ -0,0 +1,36 @@ + + +
+
+