Skip to content

Commit 66e30d3

Browse files
authored
fix: ensure snippet hoisting works in the correct scope (#14642)
* fix: ensure snippet hoisting works in the correct scope * fix bug * revert * revert
1 parent 9cfd2e2 commit 66e30d3

File tree

7 files changed

+44
-6
lines changed

7 files changed

+44
-6
lines changed

.changeset/chatty-windows-own.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: ensure snippet hoisting works in the correct scope

packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ function can_hoist_snippet(scope, scopes, visited = new Set()) {
9999
if (binding.initial?.type === 'SnippetBlock') {
100100
if (visited.has(binding)) continue;
101101
visited.add(binding);
102+
const snippet_scope = /** @type {Scope} */ (scopes.get(binding.initial));
102103

103-
if (can_hoist_snippet(binding.scope, scopes, visited)) {
104+
if (can_hoist_snippet(snippet_scope, scopes, visited)) {
104105
continue;
105106
}
106107
}

packages/svelte/src/compiler/phases/scope.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -628,12 +628,8 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
628628

629629
SnippetBlock(node, context) {
630630
const state = context.state;
631-
// Special-case for root-level snippets: they become part of the instance scope
632-
const is_top_level = !context.path.at(-2);
633631
let scope = state.scope;
634-
if (is_top_level) {
635-
scope = /** @type {Scope} */ (parent);
636-
}
632+
637633
scope.declare(node.expression, 'normal', 'function', node);
638634

639635
const child_scope = state.scope.child();
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: 'a'
5+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
let abc = 'a'
3+
</script>
4+
5+
{@render b()}
6+
7+
{#snippet a()}
8+
{abc}
9+
{/snippet}
10+
11+
{#snippet b()}
12+
{@render a()}
13+
{/snippet}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: '<h1>Hello world!</h1>'
5+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script module>
2+
export { foo }
3+
</script>
4+
5+
<script>
6+
let name = 'world';
7+
</script>
8+
9+
<h1>Hello {name}!</h1>
10+
11+
{#snippet foo()}
12+
oo
13+
{/snippet}

0 commit comments

Comments
 (0)