fix: correctly migrate sequence expressions (#13291)

* fix: correctly migrate sequence expressions

* remove unwanted parens

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/13293/head
Paolo Ricciuti 2 months ago committed by GitHub
parent 09527fd190
commit e3c56fab4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: correctly migrate sequence expressions

@ -368,8 +368,15 @@ const instance_script = {
// state
if (declarator.init) {
state.str.prependLeft(/** @type {number} */ (declarator.init.start), '$state(');
state.str.appendRight(/** @type {number} */ (declarator.init.end), ')');
let { start, end } = /** @type {{ start: number, end: number }} */ (declarator.init);
if (declarator.init.type === 'SequenceExpression') {
while (state.str.original[start] !== '(') start -= 1;
while (state.str.original[end - 1] !== ')') end += 1;
}
state.str.prependLeft(start, '$state(');
state.str.appendRight(end, ')');
} else {
state.str.prependLeft(
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
@ -416,25 +423,30 @@ const instance_script = {
const bindings = ids.map((id) => state.scope.get(id.name));
const reassigned_bindings = bindings.filter((b) => b?.reassigned);
if (reassigned_bindings.length === 0 && !bindings.some((b) => b?.kind === 'store_sub')) {
let { start, end } = /** @type {{ start: number, end: number }} */ (
node.body.expression.right
);
// $derived
state.str.update(
/** @type {number} */ (node.start),
/** @type {number} */ (node.body.expression.start),
'let '
);
state.str.prependRight(
/** @type {number} */ (node.body.expression.right.start),
'$derived('
);
if (node.body.expression.right.end !== node.end) {
state.str.update(
/** @type {number} */ (node.body.expression.right.end),
/** @type {number} */ (node.end),
');'
);
} else {
state.str.appendLeft(/** @type {number} */ (node.end), ');');
if (node.body.expression.right.type === 'SequenceExpression') {
while (state.str.original[start] !== '(') start -= 1;
while (state.str.original[end - 1] !== ')') end += 1;
}
state.str.prependRight(start, `$derived(`);
// in a case like `$: ({ a } = b())`, there's already a trailing parenthesis.
// otherwise, we need to add one
if (state.str.original[/** @type {number} */ (node.body.start)] !== '(') {
state.str.appendLeft(end, `)`);
}
return;
} else {
for (const binding of reassigned_bindings) {

@ -1,7 +0,0 @@
<script>
let count = 0;
$: doubled = count * 2
$: ({ quadrupled } = { quadrupled: count * 4 })
</script>
{count} / {doubled} / {quadrupled}

@ -1,7 +0,0 @@
<script>
let count = 0;
let doubled = $derived(count * 2);
let { quadrupled } = $derived({ quadrupled: count * 4 });
</script>
{count} / {doubled} / {quadrupled}

@ -1,7 +1,11 @@
<script>
let count = 0;
// semicolon at the end
$: doubled = count * 2;
$: ({ quadrupled } = { quadrupled: count * 4 });
// no semicolon at the end
$: time_8 = count * 8
$: ({ time_16 } = { time_16: count * 16 })
</script>
{count} / {doubled} / {quadrupled}
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}

@ -1,7 +1,11 @@
<script>
let count = 0;
// semicolon at the end
let doubled = $derived(count * 2);
let { quadrupled } = $derived({ quadrupled: count * 4 });
// no semicolon at the end
let time_8 = $derived(count * 8)
let { time_16 } = $derived({ time_16: count * 16 })
</script>
{count} / {doubled} / {quadrupled}
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}

@ -0,0 +1,14 @@
<script>
let count = (void 0, 0);
// semicolon at the end
$: doubled = (void 0, count * 2);
$: ({ quadrupled } = (void 0, { quadrupled: count * 4 }));
// no semicolon at the end
$: time_8 = (void 0, count * 8)
$: ({ time_16 } = (void 0, { time_16: count * 16 }))
</script>
<!-- reassign to migrate to state -->
<button onclick={()=> count++}></button>
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}

@ -0,0 +1,14 @@
<script>
let count = $state((void 0, 0));
// semicolon at the end
let doubled = $derived((void 0, count * 2));
let { quadrupled } = $derived((void 0, { quadrupled: count * 4 }));
// no semicolon at the end
let time_8 = $derived((void 0, count * 8))
let { time_16 } = $derived((void 0, { time_16: count * 16 }))
</script>
<!-- reassign to migrate to state -->
<button onclick={()=> count++}></button>
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
Loading…
Cancel
Save