Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ten-vans-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: migrated snippet shadowing prop and let directive removal
30 changes: 29 additions & 1 deletion packages/svelte/src/compiler/migrate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,10 @@ function migrate_slot_usage(node, path, state) {
let snippet_name = 'children';
let snippet_props = [];

// if we stop the transform because the name is not correct we don't want to
// remove the let directive and they could come before the name
let removal_queue = [];

for (let attribute of node.attributes) {
if (
attribute.type === 'Attribute' &&
Expand All @@ -1112,6 +1116,23 @@ function migrate_slot_usage(node, path, state) {
);
return;
}
if (parent?.type === 'Component' || parent?.type === 'SvelteComponent') {
for (let attribute of parent.attributes) {
if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') {
if (attribute.name === snippet_name) {
state.str.appendLeft(
node.start,
`<!-- @migration-task: migrate this slot by hand, \`${snippet_name}\` would shadow a prop on the parent component -->\n${state.indent}`
);
return;
}
}
}
}
// flush the queue after we found the name
for (let remove_let of removal_queue) {
remove_let();
}
state.str.remove(attribute.start, attribute.end);
}
if (attribute.type === 'LetDirective') {
Expand All @@ -1121,7 +1142,14 @@ function migrate_slot_usage(node, path, state) {
? `: ${state.str.original.substring(/** @type {number} */ (attribute.expression.start), /** @type {number} */ (attribute.expression.end))}`
: '')
);
state.str.remove(attribute.start, attribute.end);
// we just add to the queue to remove them after we found if we need to migrate or we bail
removal_queue.push(() => state.str.remove(attribute.start, attribute.end));
}
}

if (removal_queue.length > 0) {
for (let remove_let of removal_queue) {
remove_let();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,31 @@
<svelte:fragment slot="stuff">
cool
</svelte:fragment>
</Comp>


<!-- don't remove the let directive if we don't migrate -->

<Comp>
<div let:should_stay slot="cool:stuff">
cool
</div>
</Comp>

<Comp>
<div let:should_stay slot="cool stuff">
cool
</div>
</Comp>

<Comp>
<svelte:fragment let:should_stay slot="cool:stuff">
cool
</svelte:fragment>
</Comp>

<Comp>
<svelte:fragment let:should_stay slot="cool stuff">
cool
</svelte:fragment>
</Comp>
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,35 @@
cool

{/snippet}
</Comp>


<!-- don't remove the let directive if we don't migrate -->

<Comp>
<!-- @migration-task: migrate this slot by hand, `cool:stuff` is an invalid identifier -->
<div let:should_stay slot="cool:stuff">
cool
</div>
</Comp>

<Comp>
<!-- @migration-task: migrate this slot by hand, `cool stuff` is an invalid identifier -->
<div let:should_stay slot="cool stuff">
cool
</div>
</Comp>

<Comp>
<!-- @migration-task: migrate this slot by hand, `cool:stuff` is an invalid identifier -->
<svelte:fragment let:should_stay slot="cool:stuff">
cool
</svelte:fragment>
</Comp>

<Comp>
<!-- @migration-task: migrate this slot by hand, `cool stuff` is an invalid identifier -->
<svelte:fragment let:should_stay slot="cool stuff">
cool
</svelte:fragment>
</Comp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script>
import Comp from "./Component.svelte";
</script>

<Comp stuff="cool">
<div slot="stuff">
cool
</div>
</Comp>

<Comp stuff="cool">
<svelte:fragment slot="stuff">
cool
</svelte:fragment>
</Comp>

<!-- don't remove the let if we are not migrating -->

<Comp stuff="cool">
<div let:should_stay slot="stuff">
cool
</div>
</Comp>

<Comp stuff="cool">
<svelte:fragment let:should_stay slot="stuff">
cool
</svelte:fragment>
</Comp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script>
import Comp from "./Component.svelte";
</script>

<Comp stuff="cool">
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
<div slot="stuff">
cool
</div>
</Comp>

<Comp stuff="cool">
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
<svelte:fragment slot="stuff">
cool
</svelte:fragment>
</Comp>

<!-- don't remove the let if we are not migrating -->

<Comp stuff="cool">
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
<div let:should_stay slot="stuff">
cool
</div>
</Comp>

<Comp stuff="cool">
<!-- @migration-task: migrate this slot by hand, `stuff` would shadow a prop on the parent component -->
<svelte:fragment let:should_stay slot="stuff">
cool
</svelte:fragment>
</Comp>