fix: error at compile time on duplicate snippet/declaration tag definitions (#18351)

pull/18346/head
Simon H 1 month ago committed by GitHub
parent 56013a2c01
commit 5b8db1be35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: error at compile time on duplicate snippet/declaration tag definitions

@ -2,6 +2,7 @@
/** @import { Context } from '../types' */
import * as b from '#compiler/builders';
import * as e from '../../../errors.js';
import { extract_identifiers } from '../../../utils/ast.js';
/**
* @param {AST.DeclarationTag} node
@ -12,6 +13,16 @@ export function DeclarationTag(node, context) {
e.declaration_tag_no_legacy_mode(node);
}
const is_top_level = context.path.length === 1 && context.path[0].type === 'Fragment';
if (is_top_level) {
const duplicate = node.declaration.declarations
.flatMap((declaration) => extract_identifiers(declaration.id))
.find((id) => context.state.analysis.instance.scope.declarations.has(id.name));
if (duplicate) {
e.declaration_duplicate(duplicate, duplicate.name);
}
}
context.visit(node.declaration, {
...context.state,
in_declaration_tag: true,

@ -25,19 +25,24 @@ export function SnippetBlock(node, context) {
context.next({ ...context.state, parent_element: null });
const can_hoist =
context.path.length === 1 &&
context.path[0].type === 'Fragment' &&
can_hoist_snippet(context.state.scope, context.state.scopes);
const is_top_level = context.path.length === 1 && context.path[0].type === 'Fragment';
const name = node.expression.name;
if (is_top_level) {
const name = node.expression.name;
if (can_hoist) {
const binding = /** @type {Binding} */ (context.state.scope.get(name));
context.state.analysis.module.scope.declarations.set(name, binding);
}
if (context.state.analysis.instance.scope.declarations.has(name)) {
e.declaration_duplicate(node.expression, name);
}
node.metadata.can_hoist =
is_top_level && can_hoist_snippet(context.state.scope, context.state.scopes);
node.metadata.can_hoist = can_hoist;
if (node.metadata.can_hoist) {
const name = node.expression.name;
const binding = /** @type {Binding} */ (context.state.scope.get(name));
context.state.analysis.module.scope.declarations.set(name, binding);
}
}
const { path } = context;
const parent = path.at(-2);

@ -0,0 +1,14 @@
[
{
"code": "declaration_duplicate",
"message": "`foo` has already been declared",
"start": {
"line": 5,
"column": 5
},
"end": {
"line": 5,
"column": 8
}
}
]

@ -0,0 +1,5 @@
<script>
let foo = 'bar';
</script>
{let foo = 'baz'}

@ -0,0 +1,14 @@
[
{
"code": "declaration_duplicate",
"message": "`foo` has already been declared",
"start": {
"line": 5,
"column": 10
},
"end": {
"line": 5,
"column": 13
}
}
]

@ -0,0 +1,5 @@
<script>
let foo = 'bar';
</script>
{#snippet foo()}baz{/snippet}
Loading…
Cancel
Save