Skip to content

Commit 8d0114b

Browse files
committed
fix: only use iterator destructuring logic if there's an array pattern
1 parent add0c6a commit 8d0114b

File tree

5 files changed

+130
-13
lines changed

5 files changed

+130
-13
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: only use iterator destructuring logic if there's an array pattern

packages/svelte/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { CallExpression, Expression, Identifier, Literal, VariableDeclaration, VariableDeclarator } from 'estree' */
1+
/** @import { CallExpression, Expression, Identifier, Literal, VariableDeclaration, VariableDeclarator, ObjectPattern, ArrayPattern } from 'estree' */
22
/** @import { Binding } from '#compiler' */
33
/** @import { ComponentClientTransformState, ComponentContext } from '../types' */
44
import { dev } from '../../../../state.js';
@@ -8,6 +8,7 @@ import * as assert from '../../../../utils/assert.js';
88
import { get_rune } from '../../../scope.js';
99
import { get_prop_source, is_prop_source, is_state_source, should_proxy } from '../utils.js';
1010
import { is_hoisted_function } from '../../utils.js';
11+
import { walk } from 'zimmerframe';
1112

1213
/**
1314
* @param {VariableDeclaration} node
@@ -170,9 +171,7 @@ export function VariableDeclaration(node, context) {
170171
)
171172
);
172173
} else {
173-
const [pattern, replacements] = build_pattern(declarator.id, context.state.scope);
174174
const init = /** @type {CallExpression} */ (declarator.init);
175-
176175
/** @type {Identifier} */
177176
let id;
178177
let rhs = value;
@@ -188,17 +187,55 @@ export function VariableDeclaration(node, context) {
188187
);
189188
}
190189

191-
for (let i = 0; i < replacements.size; i++) {
192-
const [original, replacement] = [...replacements][i];
193-
declarations.push(
194-
b.declarator(
195-
original,
196-
b.call(
197-
'$.derived',
198-
b.arrow([], b.block([b.let(pattern, rhs), b.return(replacement)]))
199-
)
200-
)
190+
/**
191+
*
192+
* @param {ObjectPattern} object_pattern
193+
* @returns
194+
*/
195+
function has_destructured_array(object_pattern) {
196+
let has_array = false;
197+
walk(
198+
/** @type {ObjectPattern | ArrayPattern} */ (object_pattern),
199+
{},
200+
{
201+
ArrayPattern(_, context) {
202+
has_array = true;
203+
context.stop();
204+
}
205+
}
201206
);
207+
return has_array;
208+
}
209+
210+
if (
211+
// if the declarator is an array patter or if it's an object pattern with an array pattern inside
212+
// we want to use this method to account for possible iterators in the derived value
213+
declarator.id.type === 'ArrayPattern' ||
214+
(declarator.id.type === 'ObjectPattern' && has_destructured_array(declarator.id))
215+
) {
216+
const [pattern, replacements] = build_pattern(declarator.id, context.state.scope);
217+
218+
for (let i = 0; i < replacements.size; i++) {
219+
const [original, replacement] = [...replacements][i];
220+
declarations.push(
221+
b.declarator(
222+
original,
223+
b.call(
224+
'$.derived',
225+
b.arrow([], b.block([b.let(pattern, rhs), b.return(replacement)]))
226+
)
227+
)
228+
);
229+
}
230+
} else {
231+
const bindings = extract_paths(declarator.id);
232+
233+
for (let i = 0; i < bindings.length; i++) {
234+
const binding = bindings[i];
235+
declarations.push(
236+
b.declarator(binding.node, b.call('$.derived', b.thunk(binding.expression(rhs))))
237+
);
238+
}
202239
}
203240
}
204241
continue;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'svelte/internal/disclose-version';
2+
import * as $ from 'svelte/internal/client';
3+
4+
export default function Destructure_derived_arrays($$anchor) {
5+
let $$d = $.derived(() => ({})),
6+
a = $.derived(() => $.get($$d).a),
7+
b = $.derived(() => $.get($$d).b),
8+
c = $.derived(() => $.get($$d).c);
9+
10+
let $$d_1 = $.derived(() => []),
11+
d = $.derived(() => {
12+
let [$$1, $$2, $$3] = $.get($$d_1);
13+
14+
return $$1;
15+
}),
16+
e = $.derived(() => {
17+
let [$$1, $$2, $$3] = $.get($$d_1);
18+
19+
return $$2;
20+
}),
21+
f = $.derived(() => {
22+
let [$$1, $$2, $$3] = $.get($$d_1);
23+
24+
return $$3;
25+
});
26+
27+
let $$d_2 = $.derived(() => []),
28+
g = $.derived(() => {
29+
let { g: $$4, h: $$5, i: [$$6] } = $.get($$d_2);
30+
31+
return $$4;
32+
}),
33+
h = $.derived(() => {
34+
let { g: $$4, h: $$5, i: [$$6] } = $.get($$d_2);
35+
36+
return $$5;
37+
}),
38+
j = $.derived(() => {
39+
let { g: $$4, h: $$5, i: [$$6] } = $.get($$d_2);
40+
41+
return $$6;
42+
});
43+
44+
let $$d_3 = $.derived(() => []),
45+
k = $.derived(() => {
46+
let { k: $$7, l: $$8, m: { n: [$$9] } } = $.get($$d_3);
47+
48+
return $$7;
49+
}),
50+
l = $.derived(() => {
51+
let { k: $$7, l: $$8, m: { n: [$$9] } } = $.get($$d_3);
52+
53+
return $$8;
54+
}),
55+
o = $.derived(() => {
56+
let { k: $$7, l: $$8, m: { n: [$$9] } } = $.get($$d_3);
57+
58+
return $$9;
59+
});
60+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as $ from 'svelte/internal/server';
2+
3+
export default function Destructure_derived_arrays($$payload) {
4+
let { a, b, c } = {};
5+
let [d, e, f] = [];
6+
let { g, h, i: [j] } = [];
7+
let { k, l, m: { n: [o] } } = [];
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
let { a, b, c } = $derived({});
3+
let [d, e, f] = $derived([]);
4+
let { g, h, i: [j] } = $derived([]);
5+
let { k, l, m: { n: [o] } } = $derived([]);
6+
</script>
7+

0 commit comments

Comments
 (0)