Skip to content

Commit 610225a

Browse files
committed
feat: warn when a snippet shadow a prop
1 parent 573b9f1 commit 610225a

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@
3737
## slot_element_deprecated
3838

3939
> Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead.
40+
41+
## snippet_shadowing_prop
42+
43+
> This snippet is shadowing the prop `%prop%` with the same name

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+
w.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' ||

packages/svelte/src/compiler/warnings.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ export const codes = [
9090
"component_name_lowercase",
9191
"element_invalid_self_closing_tag",
9292
"event_directive_deprecated",
93-
"slot_element_deprecated"
93+
"slot_element_deprecated",
94+
"snippet_shadowing_prop"
9495
];
9596

9697
/**
@@ -712,4 +713,13 @@ export function event_directive_deprecated(node, name) {
712713
*/
713714
export function slot_element_deprecated(node) {
714715
w(node, "slot_element_deprecated", "Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead.");
716+
}
717+
718+
/**
719+
* This snippet is shadowing the prop `%prop%` with the same name
720+
* @param {null | NodeLike} node
721+
* @param {string} prop
722+
*/
723+
export function snippet_shadowing_prop(node, prop) {
724+
w(node, "snippet_shadowing_prop", `This snippet is shadowing the prop \`${prop}\` with the same name`);
715725
}
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>
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+
]

0 commit comments

Comments
 (0)