From dc8ab171f87c6e91b530196377c0bc384c17a515 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 18 Oct 2024 15:42:01 +0100 Subject: [PATCH 1/2] fix: correct migration of uninitialised state --- .changeset/neat-rabbits-divide.md | 5 +++ packages/svelte/src/compiler/migrate/index.js | 34 +++++++++++-------- .../output.svelte | 12 ++++--- .../single-assignment-labeled/output.svelte | 15 +++++--- .../samples/state-no-initial/input.svelte | 13 +++++++ .../samples/state-no-initial/output.svelte | 13 +++++++ 6 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 .changeset/neat-rabbits-divide.md create mode 100644 packages/svelte/tests/migrate/samples/state-no-initial/input.svelte create mode 100644 packages/svelte/tests/migrate/samples/state-no-initial/output.svelte diff --git a/.changeset/neat-rabbits-divide.md b/.changeset/neat-rabbits-divide.md new file mode 100644 index 000000000000..ffe57a6f1804 --- /dev/null +++ b/.changeset/neat-rabbits-divide.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: correct migration of uninitialised state diff --git a/packages/svelte/src/compiler/migrate/index.js b/packages/svelte/src/compiler/migrate/index.js index 69c840aedbac..dc9ce0dbfb0d 100644 --- a/packages/svelte/src/compiler/migrate/index.js +++ b/packages/svelte/src/compiler/migrate/index.js @@ -549,23 +549,27 @@ const instance_script = { let labeled_statement; // Analyze declaration bindings to see if they're exclusively updated within a single reactive statement - const possible_derived = bindings.every((binding) => - binding.references.every((reference) => { - const declaration = reference.path.find((el) => el.type === 'VariableDeclaration'); - const assignment = reference.path.find((el) => el.type === 'AssignmentExpression'); - const update = reference.path.find((el) => el.type === 'UpdateExpression'); - const labeled = reference.path.find( - (el) => el.type === 'LabeledStatement' && el.label.name === '$' - ); + const possible_derived = bindings.every( + (binding) => + binding.initial !== null && + binding.references.every((reference) => { + const declaration = reference.path.find((el) => el.type === 'VariableDeclaration'); + const assignment = reference.path.find((el) => el.type === 'AssignmentExpression'); + const update = reference.path.find((el) => el.type === 'UpdateExpression'); + const labeled = reference.path.find( + (el) => el.type === 'LabeledStatement' && el.label.name === '$' + ); - if (assignment && labeled) { - if (assignment_in_labeled) return false; - assignment_in_labeled = /** @type {AssignmentExpression} */ (assignment); - labeled_statement = /** @type {LabeledStatement} */ (labeled); - } + if (assignment && labeled) { + if (assignment_in_labeled) return false; + assignment_in_labeled = /** @type {AssignmentExpression} */ (assignment); + labeled_statement = /** @type {LabeledStatement} */ (labeled); + } - return !update && (declaration || (labeled && assignment) || (!labeled && !assignment)); - }) + return ( + !update && (declaration || (labeled && assignment) || (!labeled && !assignment)) + ); + }) ); const labeled_has_single_assignment = diff --git a/packages/svelte/tests/migrate/samples/reactive-statements-reorder-with-comments/output.svelte b/packages/svelte/tests/migrate/samples/reactive-statements-reorder-with-comments/output.svelte index 48a3378d515c..af4048137904 100644 --- a/packages/svelte/tests/migrate/samples/reactive-statements-reorder-with-comments/output.svelte +++ b/packages/svelte/tests/migrate/samples/reactive-statements-reorder-with-comments/output.svelte @@ -6,10 +6,7 @@ // triple - // update triple - let triple = $derived(count * 3) - // trailing comment - // in triple; + let triple = $state(); function increment() { count += 1; @@ -19,7 +16,12 @@ run(() => { console.log({ count, double }); }); - + run(() => { + // update triple + triple = count * 3; + // trailing comment + // in triple + });