Skip to content

Commit 87a420f

Browse files
feat: error when snippet shadows a prop (#11631)
Closes #11603
1 parent 573b9f1 commit 87a420f

File tree

6 files changed

+56
-2
lines changed

6 files changed

+56
-2
lines changed

.changeset/warm-cherries-shake.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+
feat: error when snippet shadow a prop

packages/svelte/messages/compile-errors/template.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@
240240

241241
> snippets do not support rest parameters; use an array instead
242242
243+
## snippet_shadowing_prop
244+
245+
> This snippet is shadowing the prop `%prop%` with the same name
246+
243247
## style_directive_invalid_modifier
244248

245249
> `style:` directive can only use the `important` modifier

packages/svelte/src/compiler/errors.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,16 @@ export function snippet_invalid_rest_parameter(node) {
10761076
e(node, "snippet_invalid_rest_parameter", "snippets do not support rest parameters; use an array instead");
10771077
}
10781078

1079+
/**
1080+
* This snippet is shadowing the prop `%prop%` with the same name
1081+
* @param {null | number | NodeLike} node
1082+
* @param {string} prop
1083+
* @returns {never}
1084+
*/
1085+
export function snippet_shadowing_prop(node, prop) {
1086+
e(node, "snippet_shadowing_prop", `This snippet is shadowing the prop \`${prop}\` with the same name`);
1087+
}
1088+
10791089
/**
10801090
* `style:` directive can only use the `important` modifier
10811091
* @param {null | number | NodeLike} node

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,11 +624,23 @@ const validation = {
624624

625625
context.next({ ...context.state, parent_element: null });
626626

627-
if (node.expression.name !== 'children') return;
628-
629627
const { path } = context;
630628
const parent = path.at(-2);
631629
if (!parent) return;
630+
631+
if (
632+
parent.type === 'Component' &&
633+
parent.attributes.some(
634+
(attribute) =>
635+
(attribute.type === 'Attribute' || attribute.type === 'BindDirective') &&
636+
attribute.name === node.expression.name
637+
)
638+
) {
639+
e.snippet_shadowing_prop(node, node.expression.name);
640+
}
641+
642+
if (node.expression.name !== 'children') return;
643+
632644
if (
633645
parent.type === 'Component' ||
634646
parent.type === 'SvelteComponent' ||
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "snippet_shadowing_prop",
4+
"message": "This snippet is shadowing the prop `title` with the same name",
5+
"start": {
6+
"column": 1,
7+
"line": 6
8+
},
9+
"end": {
10+
"column": 11,
11+
"line": 8
12+
}
13+
}
14+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
import Component from "./Component.svelte";
3+
</script>
4+
5+
<Component title="">
6+
{#snippet title()}
7+
title
8+
{/snippet}
9+
</Component>

0 commit comments

Comments
 (0)