Skip to content

Commit 7da3de0

Browse files
committed
fix: migrate labeled statements with no identifiers to state
1 parent ef4b317 commit 7da3de0

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

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

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { VariableDeclarator, Node, Identifier, AssignmentExpression, LabeledStatement } from 'estree' */
1+
/** @import { VariableDeclarator, Node, Identifier, AssignmentExpression, LabeledStatement, ExpressionStatement } from 'estree' */
22
/** @import { Visitors } from 'zimmerframe' */
33
/** @import { ComponentAnalysis } from '../phases/types.js' */
44
/** @import { Scope, ScopeRoot } from '../phases/scope.js' */
@@ -10,7 +10,7 @@ import { regex_valid_component_name } from '../phases/1-parse/state/element.js';
1010
import { analyze_component } from '../phases/2-analyze/index.js';
1111
import { get_rune } from '../phases/scope.js';
1212
import { reset, reset_warning_filter } from '../state.js';
13-
import { extract_identifiers } from '../utils/ast.js';
13+
import { extract_identifiers, extract_all_identifiers_from_expression } from '../utils/ast.js';
1414
import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
1515
import { determine_slot } from '../utils/slot.js';
1616
import { validate_component_options } from '../validate-options.js';
@@ -493,16 +493,33 @@ const instance_script = {
493493
);
494494

495495
const labeled_has_single_assignment =
496-
(labeled_statement?.body.type === 'BlockStatement' &&
497-
labeled_statement.body.body.length === 1) ||
498-
(labeled_statement?.body.type === 'ExpressionStatement' &&
499-
labeled_statement.body.expression.type === 'AssignmentExpression');
496+
labeled_statement?.body.type === 'BlockStatement' &&
497+
labeled_statement.body.body.length === 1;
498+
499+
const is_expression_assignment =
500+
labeled_statement?.body.type === 'ExpressionStatement' &&
501+
labeled_statement.body.expression.type === 'AssignmentExpression';
502+
503+
let should_be_state = false;
504+
505+
if (is_expression_assignment) {
506+
const body = /**@type {ExpressionStatement}*/ (labeled_statement?.body);
507+
const expression = /**@type {AssignmentExpression}*/ (body.expression);
508+
const [, ids] = extract_all_identifiers_from_expression(expression.right);
509+
if (ids.length === 0) {
510+
should_be_state = true;
511+
state.derived_labeled_statements.add(
512+
/** @type {LabeledStatement} */ (labeled_statement)
513+
);
514+
}
515+
}
500516

501517
if (
518+
!should_be_state &&
502519
possible_derived &&
503520
assignment_in_labeled &&
504521
labeled_statement &&
505-
labeled_has_single_assignment
522+
(labeled_has_single_assignment || is_expression_assignment)
506523
) {
507524
state.str.appendRight(
508525
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
@@ -530,7 +547,30 @@ const instance_script = {
530547
} else {
531548
state.str.prependLeft(
532549
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
533-
' = $state()'
550+
' = $state('
551+
);
552+
if (should_be_state) {
553+
state.str.appendRight(
554+
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
555+
state.str
556+
.snip(
557+
/** @type {number} */ (
558+
/** @type {AssignmentExpression} */ (assignment_in_labeled).right.start
559+
),
560+
/** @type {number} */ (
561+
/** @type {AssignmentExpression} */ (assignment_in_labeled).right.end
562+
)
563+
)
564+
.toString()
565+
);
566+
state.str.remove(
567+
/** @type {number} */ (/** @type {LabeledStatement} */ (labeled_statement).start),
568+
/** @type {number} */ (/** @type {LabeledStatement} */ (labeled_statement).end)
569+
);
570+
}
571+
state.str.appendRight(
572+
/** @type {number} */ (declarator.id.typeAnnotation?.end ?? declarator.id.end),
573+
')'
534574
);
535575
}
536576
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
4444
let almost_infinity;
4545
$: almost_infinity = count * 128;
46+
47+
let should_be_state;
48+
$: should_be_state = 42;
49+
50+
$: should_be_state_too = 42;
4651
</script>
4752

4853
<button on:click={()=>{

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
4444
let almost_infinity = $derived(count * 128);
4545
46+
47+
let should_be_state = $state(42);
48+
49+
50+
let should_be_state_too = $derived(42);
4651
</script>
4752

4853
<button onclick={()=>{

0 commit comments

Comments
 (0)