Skip to content

Commit

Permalink
fix: add top level snippets to instance scope (#9467)
Browse files Browse the repository at this point in the history
fixes #9460
  • Loading branch information
dummdidumm authored Nov 17, 2023
1 parent 1beb5e8 commit 4418ba6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-sheep-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: add top level snippets to instance scope
28 changes: 11 additions & 17 deletions packages/svelte/src/compiler/phases/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
next({ scope });
};

/**
* @type {import('zimmerframe').Visitor<import('#compiler').SvelteNode, State, import('#compiler').SvelteNode>}
*/
const CreateBlock = (node, { state, next }) => {
const scope = state.scope.child();
scopes.set(node, scope);
next({ scope });
};

/**
* @param {import('#compiler').ElementLike} node
* @param {Scope} parent
Expand Down Expand Up @@ -566,18 +557,24 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
},

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

const scope = state.scope.child();
scopes.set(node, scope);
const child_scope = state.scope.child();
scopes.set(node, child_scope);

if (node.context) {
for (const id of extract_identifiers(node.context)) {
scope.declare(id, 'each', 'let');
child_scope.declare(id, 'each', 'let');
}
}

context.next({ scope });
context.next({ scope: child_scope });
},

Fragment: (node, context) => {
Expand All @@ -586,9 +583,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
context.next({ scope });
},

// TODO this will be unnecessary when we switch to fragments
IfBlock: CreateBlock,

BindDirective(node, context) {
updates.push([
context.state.scope,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ok, test } from '../../test';

export default test({
test({ target }) {
const button = target.querySelector('button');
ok(button);
button.click();
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
function log() {
// Test that the log function is not hoisted. If it was, this would make the test
// pass still, but Vitest would error because it sees that there are unhandled errors
snippet;
}
</script>

{#snippet snippet()}Hello{/snippet}

<button on:click={log}>
log snippet
</button>

1 comment on commit 4418ba6

@vercel
Copy link

@vercel vercel bot commented on 4418ba6 Nov 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

svelte-5-preview – ./sites/svelte-5-preview

svelte-5-preview.vercel.app
svelte-5-preview-svelte.vercel.app
svelte-octane.vercel.app
svelte-5-preview-git-main-svelte.vercel.app

Please sign in to comment.