Skip to content

Commit 9674278

Browse files
committed
feat: update error message for snippet binding and assignments
1 parent f90639d commit 9674278

File tree

10 files changed

+48
-1
lines changed

10 files changed

+48
-1
lines changed

.changeset/wicked-wasps-allow.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: update error message for snippet binding and assignments

packages/svelte/src/compiler/errors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ const runes = {
214214
'duplicate-props-rune': () => `Cannot use $props() more than once`,
215215
'invalid-each-assignment': () =>
216216
`Cannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. 'array[i] = value' instead of 'entry = value')`,
217+
'invalid-snippet-assignment': () =>
218+
`Cannot reassign or bind to snippet function argument in runes mode`,
217219
'invalid-derived-call': () => `$derived.call(...) has been replaced with $derived.by(...)`,
218220
'conflicting-property-name': () =>
219221
`Cannot have a property and a component export with the same name`

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ const validation = {
353353
error(node, 'invalid-each-assignment');
354354
}
355355

356+
if (context.state.analysis.runes && binding.kind === 'snippet') {
357+
error(node, 'invalid-snippet-assignment');
358+
}
359+
356360
// TODO handle mutations of non-state/props in runes mode
357361
}
358362

@@ -1022,6 +1026,10 @@ function validate_assignment(node, argument, state) {
10221026
if (binding?.kind === 'each') {
10231027
error(node, 'invalid-each-assignment');
10241028
}
1029+
1030+
if (binding?.kind === 'snippet') {
1031+
error(node, 'invalid-snippet-assignment');
1032+
}
10251033
}
10261034

10271035
let object = /** @type {import('estree').Expression | import('estree').Super} */ (argument);

packages/svelte/src/compiler/phases/scope.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
649649

650650
for (const param of node.parameters) {
651651
for (const id of extract_identifiers(param)) {
652-
child_scope.declare(id, 'each', 'let');
652+
child_scope.declare(id, 'snippet', 'let');
653653
}
654654
}
655655

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ export interface Binding {
254254
* - `state`: A state variable
255255
* - `derived`: A derived variable
256256
* - `each`: An each block context variable
257+
* - `snippet`: A snippet block context variable
257258
* - `store_sub`: A $store value
258259
* - `legacy_reactive`: A `$:` declaration
259260
* - `legacy_reactive_import`: An imported binding that is mutated inside the component
@@ -267,6 +268,7 @@ export interface Binding {
267268
| 'frozen_state'
268269
| 'derived'
269270
| 'each'
271+
| 'snippet'
270272
| 'store_sub'
271273
| 'legacy_reactive'
272274
| 'legacy_reactive_import';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'invalid-snippet-assignment',
6+
message:
7+
"Cannot reassign or bind to snippet function argument in runes mode"
8+
}
9+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<svelte:options runes />
2+
3+
{#snippet foo(value)}
4+
<input bind:value={value}>
5+
{/snippet}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'invalid-snippet-assignment',
6+
message:
7+
"Cannot reassign or bind to snippet function argument in runes mode"
8+
}
9+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<svelte:options runes />
2+
3+
{#snippet foo(value)}
4+
<button onclick={() => value += 1}>click</button>
5+
{/snippet}

packages/svelte/types/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ declare module 'svelte/compiler' {
719719
* - `state`: A state variable
720720
* - `derived`: A derived variable
721721
* - `each`: An each block context variable
722+
* - `snippet`: A snippet block context variable
722723
* - `store_sub`: A $store value
723724
* - `legacy_reactive`: A `$:` declaration
724725
* - `legacy_reactive_import`: An imported binding that is mutated inside the component
@@ -732,6 +733,7 @@ declare module 'svelte/compiler' {
732733
| 'frozen_state'
733734
| 'derived'
734735
| 'each'
736+
| 'snippet'
735737
| 'store_sub'
736738
| 'legacy_reactive'
737739
| 'legacy_reactive_import';

0 commit comments

Comments
 (0)