fix: don't transform reassigned state in labeled statement in `$derived`

pull/15725/head
paoloricciuti 1 year ago
parent 475b5dbe83
commit f8bb4a3577

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't transform reassigned state in labeled statement in `$derived`

@ -951,58 +951,60 @@ const instance_script = {
const bindings = ids.map((id) => state.scope.get(id.name));
const reassigned_bindings = bindings.filter((b) => b?.reassigned);
if (
node.body.expression.right.type !== 'Literal' &&
!bindings.some((b) => b?.kind === 'store_sub') &&
node.body.expression.left.type !== 'MemberExpression'
) {
let { start, end } = /** @type {{ start: number, end: number }} */ (
node.body.expression.right
);
if (!bindings.some((b) => b?.kind === 'state')) {
if (
node.body.expression.right.type !== 'Literal' &&
!bindings.some((b) => b?.kind === 'store_sub') &&
node.body.expression.left.type !== 'MemberExpression'
) {
let { start, end } = /** @type {{ start: number, end: number }} */ (
node.body.expression.right
);
check_rune_binding('derived');
check_rune_binding('derived');
// $derived
state.str.update(
/** @type {number} */ (node.start),
/** @type {number} */ (node.body.expression.start),
'let '
);
// $derived
state.str.update(
/** @type {number} */ (node.start),
/** @type {number} */ (node.body.expression.start),
'let '
);
if (node.body.expression.right.type === 'SequenceExpression') {
while (state.str.original[start] !== '(') start -= 1;
while (state.str.original[end - 1] !== ')') end += 1;
}
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(`);
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) {
if (binding && (ids.includes(binding.node) || expression_ids.length === 0)) {
check_rune_binding('state');
const init =
binding.kind === 'state'
? ' = $state()'
: expression_ids.length === 0
? ` = $state(${state.str.original.substring(/** @type {number} */ (node.body.expression.right.start), node.body.expression.right.end)})`
: '';
// implicitly-declared variable which we need to make explicit
state.str.prependLeft(
/** @type {number} */ (node.start),
`let ${binding.node.name}${init};\n${state.indent}`
);
// 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, `)`);
}
}
if (expression_ids.length === 0 && !bindings.some((b) => b?.kind === 'store_sub')) {
state.str.remove(/** @type {number} */ (node.start), /** @type {number} */ (node.end));
return;
} else {
for (const binding of reassigned_bindings) {
if (binding && (ids.includes(binding.node) || expression_ids.length === 0)) {
check_rune_binding('state');
const init =
binding.kind === 'state'
? ' = $state()'
: expression_ids.length === 0
? ` = $state(${state.str.original.substring(/** @type {number} */ (node.body.expression.right.start), node.body.expression.right.end)})`
: '';
// implicitly-declared variable which we need to make explicit
state.str.prependLeft(
/** @type {number} */ (node.start),
`let ${binding.node.name}${init};\n${state.indent}`
);
}
}
if (expression_ids.length === 0 && !bindings.some((b) => b?.kind === 'store_sub')) {
state.str.remove(/** @type {number} */ (node.start), /** @type {number} */ (node.end));
return;
}
}
}
}

@ -0,0 +1,6 @@
<script>
let something = '123';
let foo = false;
$: foo = !!something;
</script>

@ -0,0 +1,10 @@
<script>
import { run } from 'svelte/legacy';
let something = '123';
let foo = $state(false);
run(() => {
foo = !!something;
});
</script>
Loading…
Cancel
Save