Skip to content

Commit d8c3f3d

Browse files
fix: emit snippet_invalid_export instead of undefined_export for exported snippets (#16539)
* fix: emit `snippet_invalid_export` instead of `undefined_export` for exported snippets * try this * this should work * remove some junk (this never did anything) * add test --------- Co-authored-by: Rich Harris <[email protected]>
1 parent e7e8a9c commit d8c3f3d

File tree

6 files changed

+35
-10
lines changed

6 files changed

+35
-10
lines changed

.changeset/thick-snakes-look.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: emit `snippet_invalid_export` instead of `undefined_export` for exported snippets

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,6 @@ export function analyze_component(root, source, options) {
526526
has_global: false
527527
},
528528
source,
529-
undefined_exports: new Map(),
530529
snippet_renderers: new Map(),
531530
snippets: new Set(),
532531
async_deriveds: new Set()
@@ -787,9 +786,15 @@ export function analyze_component(root, source, options) {
787786
if (node.type === 'ExportNamedDeclaration' && node.specifiers !== null && node.source == null) {
788787
for (const specifier of node.specifiers) {
789788
if (specifier.local.type !== 'Identifier') continue;
790-
791-
const binding = analysis.module.scope.get(specifier.local.name);
792-
if (!binding) e.export_undefined(specifier, specifier.local.name);
789+
const name = specifier.local.name;
790+
const binding = analysis.module.scope.get(name);
791+
if (!binding) {
792+
if ([...analysis.snippets].find((snippet) => snippet.expression.name === name)) {
793+
e.snippet_invalid_export(specifier);
794+
} else {
795+
e.export_undefined(specifier, name);
796+
}
797+
}
793798
}
794799
}
795800
}

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ export function SnippetBlock(node, context) {
3535
if (can_hoist) {
3636
const binding = /** @type {Binding} */ (context.state.scope.get(name));
3737
context.state.analysis.module.scope.declarations.set(name, binding);
38-
} else {
39-
const undefined_export = context.state.analysis.undefined_exports.get(name);
40-
if (undefined_export) {
41-
e.snippet_invalid_export(undefined_export);
42-
}
4338
}
4439

4540
node.metadata.can_hoist = can_hoist;

packages/svelte/src/compiler/phases/types.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ export interface ComponentAnalysis extends Analysis {
9595
};
9696
/** @deprecated use `source` from `state.js` instead */
9797
source: string;
98-
undefined_exports: Map<string, Node>;
9998
/**
10099
* Every render tag/component, and whether it could be definitively resolved or not
101100
*/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'snippet_invalid_export',
6+
message:
7+
'An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets',
8+
position: [26, 29]
9+
}
10+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script module>
2+
export { foo }
3+
</script>
4+
5+
<script>
6+
let x = 42;
7+
</script>
8+
9+
{#snippet foo()}
10+
{x}
11+
{/snippet}

0 commit comments

Comments
 (0)