Skip to content

Commit e3c56fa

Browse files
fix: correctly migrate sequence expressions (#13291)
* fix: correctly migrate sequence expressions * remove unwanted parens --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 09527fd commit e3c56fa

File tree

8 files changed

+69
-30
lines changed

8 files changed

+69
-30
lines changed

.changeset/brave-candles-serve.md

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: correctly migrate sequence expressions

packages/svelte/src/compiler/migrate/index.js

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,15 @@ const instance_script = {
368368

369369
// state
370370
if (declarator.init) {
371-
state.str.prependLeft(/** @type {number} */ (declarator.init.start), '$state(');
372-
state.str.appendRight(/** @type {number} */ (declarator.init.end), ')');
371+
let { start, end } = /** @type {{ start: number, end: number }} */ (declarator.init);
372+
373+
if (declarator.init.type === 'SequenceExpression') {
374+
while (state.str.original[start] !== '(') start -= 1;
375+
while (state.str.original[end - 1] !== ')') end += 1;
376+
}
377+
378+
state.str.prependLeft(start, '$state(');
379+
state.str.appendRight(end, ')');
373380
} else {
374381
state.str.prependLeft(
375382
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
@@ -416,25 +423,30 @@ const instance_script = {
416423
const bindings = ids.map((id) => state.scope.get(id.name));
417424
const reassigned_bindings = bindings.filter((b) => b?.reassigned);
418425
if (reassigned_bindings.length === 0 && !bindings.some((b) => b?.kind === 'store_sub')) {
426+
let { start, end } = /** @type {{ start: number, end: number }} */ (
427+
node.body.expression.right
428+
);
429+
419430
// $derived
420431
state.str.update(
421432
/** @type {number} */ (node.start),
422433
/** @type {number} */ (node.body.expression.start),
423434
'let '
424435
);
425-
state.str.prependRight(
426-
/** @type {number} */ (node.body.expression.right.start),
427-
'$derived('
428-
);
429-
if (node.body.expression.right.end !== node.end) {
430-
state.str.update(
431-
/** @type {number} */ (node.body.expression.right.end),
432-
/** @type {number} */ (node.end),
433-
');'
434-
);
435-
} else {
436-
state.str.appendLeft(/** @type {number} */ (node.end), ');');
436+
437+
if (node.body.expression.right.type === 'SequenceExpression') {
438+
while (state.str.original[start] !== '(') start -= 1;
439+
while (state.str.original[end - 1] !== ')') end += 1;
437440
}
441+
442+
state.str.prependRight(start, `$derived(`);
443+
444+
// in a case like `$: ({ a } = b())`, there's already a trailing parenthesis.
445+
// otherwise, we need to add one
446+
if (state.str.original[/** @type {number} */ (node.body.start)] !== '(') {
447+
state.str.appendLeft(end, `)`);
448+
}
449+
438450
return;
439451
} else {
440452
for (const binding of reassigned_bindings) {

packages/svelte/tests/migrate/samples/derivations-no-colon/input.svelte

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/svelte/tests/migrate/samples/derivations-no-colon/output.svelte

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<script>
22
let count = 0;
3+
// semicolon at the end
34
$: doubled = count * 2;
45
$: ({ quadrupled } = { quadrupled: count * 4 });
6+
// no semicolon at the end
7+
$: time_8 = count * 8
8+
$: ({ time_16 } = { time_16: count * 16 })
59
</script>
610

7-
{count} / {doubled} / {quadrupled}
11+
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<script>
22
let count = 0;
3+
// semicolon at the end
34
let doubled = $derived(count * 2);
45
let { quadrupled } = $derived({ quadrupled: count * 4 });
6+
// no semicolon at the end
7+
let time_8 = $derived(count * 8)
8+
let { time_16 } = $derived({ time_16: count * 16 })
59
</script>
610

7-
{count} / {doubled} / {quadrupled}
11+
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
let count = (void 0, 0);
3+
// semicolon at the end
4+
$: doubled = (void 0, count * 2);
5+
$: ({ quadrupled } = (void 0, { quadrupled: count * 4 }));
6+
// no semicolon at the end
7+
$: time_8 = (void 0, count * 8)
8+
$: ({ time_16 } = (void 0, { time_16: count * 16 }))
9+
</script>
10+
11+
<!-- reassign to migrate to state -->
12+
<button onclick={()=> count++}></button>
13+
14+
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
let count = $state((void 0, 0));
3+
// semicolon at the end
4+
let doubled = $derived((void 0, count * 2));
5+
let { quadrupled } = $derived((void 0, { quadrupled: count * 4 }));
6+
// no semicolon at the end
7+
let time_8 = $derived((void 0, count * 8))
8+
let { time_16 } = $derived((void 0, { time_16: count * 16 }))
9+
</script>
10+
11+
<!-- reassign to migrate to state -->
12+
<button onclick={()=> count++}></button>
13+
14+
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}

0 commit comments

Comments
 (0)