Skip to content

Commit dc8ab17

Browse files
committed
fix: correct migration of uninitialised state
1 parent 0598f2b commit dc8ab17

File tree

6 files changed

+67
-25
lines changed

6 files changed

+67
-25
lines changed

.changeset/neat-rabbits-divide.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: correct migration of uninitialised state

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

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -549,23 +549,27 @@ const instance_script = {
549549
let labeled_statement;
550550

551551
// Analyze declaration bindings to see if they're exclusively updated within a single reactive statement
552-
const possible_derived = bindings.every((binding) =>
553-
binding.references.every((reference) => {
554-
const declaration = reference.path.find((el) => el.type === 'VariableDeclaration');
555-
const assignment = reference.path.find((el) => el.type === 'AssignmentExpression');
556-
const update = reference.path.find((el) => el.type === 'UpdateExpression');
557-
const labeled = reference.path.find(
558-
(el) => el.type === 'LabeledStatement' && el.label.name === '$'
559-
);
552+
const possible_derived = bindings.every(
553+
(binding) =>
554+
binding.initial !== null &&
555+
binding.references.every((reference) => {
556+
const declaration = reference.path.find((el) => el.type === 'VariableDeclaration');
557+
const assignment = reference.path.find((el) => el.type === 'AssignmentExpression');
558+
const update = reference.path.find((el) => el.type === 'UpdateExpression');
559+
const labeled = reference.path.find(
560+
(el) => el.type === 'LabeledStatement' && el.label.name === '$'
561+
);
560562

561-
if (assignment && labeled) {
562-
if (assignment_in_labeled) return false;
563-
assignment_in_labeled = /** @type {AssignmentExpression} */ (assignment);
564-
labeled_statement = /** @type {LabeledStatement} */ (labeled);
565-
}
563+
if (assignment && labeled) {
564+
if (assignment_in_labeled) return false;
565+
assignment_in_labeled = /** @type {AssignmentExpression} */ (assignment);
566+
labeled_statement = /** @type {LabeledStatement} */ (labeled);
567+
}
566568

567-
return !update && (declaration || (labeled && assignment) || (!labeled && !assignment));
568-
})
569+
return (
570+
!update && (declaration || (labeled && assignment) || (!labeled && !assignment))
571+
);
572+
})
569573
);
570574

571575
const labeled_has_single_assignment =

packages/svelte/tests/migrate/samples/reactive-statements-reorder-with-comments/output.svelte

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
77
88
// triple
9-
// update triple
10-
let triple = $derived(count * 3)
11-
// trailing comment
12-
// in triple;
9+
let triple = $state();
1310
1411
function increment() {
1512
count += 1;
@@ -19,7 +16,12 @@
1916
run(() => {
2017
console.log({ count, double });
2118
});
22-
19+
run(() => {
20+
// update triple
21+
triple = count * 3;
22+
// trailing comment
23+
// in triple
24+
});
2325
</script>
2426

2527
<button onclick={increment}>

packages/svelte/tests/migrate/samples/single-assignment-labeled/output.svelte

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
import { run } from 'svelte/legacy';
33
44
let count = $state(0);
5-
let double = $derived(count * 2);
6-
5+
let double = $state();
6+
run(() => {
7+
double = count * 2;
8+
});
79
810
let quadruple = $state();
911
run(() => {
@@ -41,10 +43,13 @@
4143
evenmore_doubled = evenmore * 2;
4244
});
4345
44-
let almost_infinity = $derived(count * 128);
45-
46+
let almost_infinity = $state();
47+
run(() => {
48+
almost_infinity = count * 128;
49+
});
4650
47-
let should_be_state = $state(42);
51+
let should_be_state = $state();
52+
let should_be_state = $state();
4853
4954
let should_be_state_too = $state(42);
5055
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
let bounds: DOMRect | undefined;
3+
$: position = calculatePosition(bounds);
4+
5+
const openDropdown = () => {
6+
bounds = getInputPosition();
7+
};
8+
9+
const getInputPosition = () => {};
10+
const calculatePosition = (boundary?: DOMRect) => ({});
11+
</script>
12+
13+
<div style:top={position.top}></div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
let bounds: DOMRect | undefined = $state();
3+
4+
const openDropdown = () => {
5+
bounds = getInputPosition();
6+
};
7+
8+
const getInputPosition = () => {};
9+
const calculatePosition = (boundary?: DOMRect) => ({});
10+
let position = $derived(calculatePosition(bounds));
11+
</script>
12+
13+
<div style:top={position.top}></div>

0 commit comments

Comments
 (0)