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 <rich.harris@vercel.com>
pull/16566/head
ComputerGuy 1 month ago committed by GitHub
parent e7e8a9c7b7
commit d8c3f3d87e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: emit `snippet_invalid_export` instead of `undefined_export` for exported snippets

@ -526,7 +526,6 @@ export function analyze_component(root, source, options) {
has_global: false
},
source,
undefined_exports: new Map(),
snippet_renderers: new Map(),
snippets: new Set(),
async_deriveds: new Set()
@ -787,9 +786,15 @@ export function analyze_component(root, source, options) {
if (node.type === 'ExportNamedDeclaration' && node.specifiers !== null && node.source == null) {
for (const specifier of node.specifiers) {
if (specifier.local.type !== 'Identifier') continue;
const binding = analysis.module.scope.get(specifier.local.name);
if (!binding) e.export_undefined(specifier, specifier.local.name);
const name = specifier.local.name;
const binding = analysis.module.scope.get(name);
if (!binding) {
if ([...analysis.snippets].find((snippet) => snippet.expression.name === name)) {
e.snippet_invalid_export(specifier);
} else {
e.export_undefined(specifier, name);
}
}
}
}
}

@ -35,11 +35,6 @@ export function SnippetBlock(node, context) {
if (can_hoist) {
const binding = /** @type {Binding} */ (context.state.scope.get(name));
context.state.analysis.module.scope.declarations.set(name, binding);
} else {
const undefined_export = context.state.analysis.undefined_exports.get(name);
if (undefined_export) {
e.snippet_invalid_export(undefined_export);
}
}
node.metadata.can_hoist = can_hoist;

@ -95,7 +95,6 @@ export interface ComponentAnalysis extends Analysis {
};
/** @deprecated use `source` from `state.js` instead */
source: string;
undefined_exports: Map<string, Node>;
/**
* Every render tag/component, and whether it could be definitively resolved or not
*/

@ -0,0 +1,10 @@
import { test } from '../../test';
export default test({
error: {
code: 'snippet_invalid_export',
message:
'An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets',
position: [26, 29]
}
});

@ -0,0 +1,11 @@
<script module>
export { foo }
</script>
<script>
let x = 42;
</script>
{#snippet foo()}
{x}
{/snippet}
Loading…
Cancel
Save