Skip to content

Commit 5deaf05

Browse files
committed
fix: migrated snippet shadowing prop and let directive removal
1 parent 894b1c3 commit 5deaf05

File tree

6 files changed

+163
-1
lines changed

6 files changed

+163
-1
lines changed

.changeset/ten-vans-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: migrated snippet shadowing prop and let directive removal

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,11 @@ function migrate_slot_usage(node, path, state) {
10971097
let snippet_name = 'children';
10981098
let snippet_props = [];
10991099

1100+
// if we stop the transform because the name is not correct we don't want to
1101+
// remove the let directive and they could come before the name
1102+
let removal_queue = [];
1103+
let slot_name_found = false;
1104+
11001105
for (let attribute of node.attributes) {
11011106
if (
11021107
attribute.type === 'Attribute' &&
@@ -1112,6 +1117,24 @@ function migrate_slot_usage(node, path, state) {
11121117
);
11131118
return;
11141119
}
1120+
if (parent?.type === 'Component' || parent?.type === 'SvelteComponent') {
1121+
for (let attribute of parent.attributes) {
1122+
if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') {
1123+
if (attribute.name === snippet_name) {
1124+
state.str.appendLeft(
1125+
node.start,
1126+
`<!-- @migration-task: migrate this slot by hand, \`${snippet_name}\` would shadow a prop on the parent component -->\n${state.indent}`
1127+
);
1128+
return;
1129+
}
1130+
}
1131+
}
1132+
}
1133+
slot_name_found = true;
1134+
// flush the queue after we found the name
1135+
for (let remove_let of removal_queue) {
1136+
remove_let();
1137+
}
11151138
state.str.remove(attribute.start, attribute.end);
11161139
}
11171140
if (attribute.type === 'LetDirective') {
@@ -1121,7 +1144,21 @@ function migrate_slot_usage(node, path, state) {
11211144
? `: ${state.str.original.substring(/** @type {number} */ (attribute.expression.start), /** @type {number} */ (attribute.expression.end))}`
11221145
: '')
11231146
);
1124-
state.str.remove(attribute.start, attribute.end);
1147+
function remove_let() {
1148+
state.str.remove(attribute.start, attribute.end);
1149+
}
1150+
// if we didn't find the name yet we just add to the queue else we call immediately
1151+
if (slot_name_found) {
1152+
remove_let();
1153+
} else {
1154+
removal_queue.push(remove_let);
1155+
}
1156+
}
1157+
}
1158+
1159+
if (!slot_name_found && removal_queue.length > 0) {
1160+
for (let remove_let of removal_queue) {
1161+
remove_let();
11251162
}
11261163
}
11271164

packages/svelte/tests/migrate/samples/slot-non-identifier/input.svelte

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,31 @@
3636
<svelte:fragment slot="stuff">
3737
cool
3838
</svelte:fragment>
39+
</Comp>
40+
41+
42+
<!-- don't remove the let directive if we don't migrate -->
43+
44+
<Comp>
45+
<div let:shoudl_stay slot="cool:stuff">
46+
cool
47+
</div>
48+
</Comp>
49+
50+
<Comp>
51+
<div let:shoudl_stay slot="cool stuff">
52+
cool
53+
</div>
54+
</Comp>
55+
56+
<Comp>
57+
<svelte:fragment let:shoudl_stay slot="cool:stuff">
58+
cool
59+
</svelte:fragment>
60+
</Comp>
61+
62+
<Comp>
63+
<svelte:fragment let:shoudl_stay slot="cool stuff">
64+
cool
65+
</svelte:fragment>
3966
</Comp>

packages/svelte/tests/migrate/samples/slot-non-identifier/output.svelte

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,35 @@
4444
cool
4545

4646
{/snippet}
47+
</Comp>
48+
49+
50+
<!-- don't remove the let directive if we don't migrate -->
51+
52+
<Comp>
53+
<!-- @migration-task: migrate this slot by hand, `cool:stuff` is an invalid identifier -->
54+
<div let:shoudl_stay slot="cool:stuff">
55+
cool
56+
</div>
57+
</Comp>
58+
59+
<Comp>
60+
<!-- @migration-task: migrate this slot by hand, `cool stuff` is an invalid identifier -->
61+
<div let:shoudl_stay slot="cool stuff">
62+
cool
63+
</div>
64+
</Comp>
65+
66+
<Comp>
67+
<!-- @migration-task: migrate this slot by hand, `cool:stuff` is an invalid identifier -->
68+
<svelte:fragment let:shoudl_stay slot="cool:stuff">
69+
cool
70+
</svelte:fragment>
71+
</Comp>
72+
73+
<Comp>
74+
<!-- @migration-task: migrate this slot by hand, `cool stuff` is an invalid identifier -->
75+
<svelte:fragment let:shoudl_stay slot="cool stuff">
76+
cool
77+
</svelte:fragment>
4778
</Comp>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script>
2+
import Comp from "./Component.svelte";
3+
</script>
4+
5+
<Comp stuff="cool">
6+
<div slot="stuff">
7+
cool
8+
</div>
9+
</Comp>
10+
11+
<Comp stuff="cool">
12+
<svelte:fragment slot="stuff">
13+
cool
14+
</svelte:fragment>
15+
</Comp>
16+
17+
<!-- don't remove the let if we are not migrating -->
18+
19+
<Comp stuff="cool">
20+
<div let:should_stay slot="stuff">
21+
cool
22+
</div>
23+
</Comp>
24+
25+
<Comp stuff="cool">
26+
<svelte:fragment let:should_stay slot="stuff">
27+
cool
28+
</svelte:fragment>
29+
</Comp>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script>
2+
import Comp from "./Component.svelte";
3+
</script>
4+
5+
<Comp stuff="cool">
6+
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
7+
<div slot="stuff">
8+
cool
9+
</div>
10+
</Comp>
11+
12+
<Comp stuff="cool">
13+
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
14+
<svelte:fragment slot="stuff">
15+
cool
16+
</svelte:fragment>
17+
</Comp>
18+
19+
<!-- don't remove the let if we are not migrating -->
20+
21+
<Comp stuff="cool">
22+
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
23+
<div let:should_stay slot="stuff">
24+
cool
25+
</div>
26+
</Comp>
27+
28+
<Comp stuff="cool">
29+
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
30+
<svelte:fragment let:should_stay slot="stuff">
31+
cool
32+
</svelte:fragment>
33+
</Comp>

0 commit comments

Comments
 (0)