feat: update error message for snippet binding and assignments (#11168)

* feat: update error message for snippet binding and assignments

* make invalid-snippet-assignment apply in non-runes mode too

* update tests

* update types

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/11162/head
Tan Li Hau 9 months ago committed by GitHub
parent d1976c07ff
commit a092899843
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
feat: update error message for snippet binding and assignments

@ -214,6 +214,7 @@ const runes = {
'duplicate-props-rune': () => `Cannot use $props() more than once`,
'invalid-each-assignment': () =>
`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')`,
'invalid-snippet-assignment': () => `Cannot reassign or bind to snippet parameter`,
'invalid-derived-call': () => `$derived.call(...) has been replaced with $derived.by(...)`,
'conflicting-property-name': () =>
`Cannot have a property and a component export with the same name`

@ -352,6 +352,10 @@ const validation = {
if (context.state.analysis.runes && binding.kind === 'each') {
error(node, 'invalid-each-assignment');
}
if (binding.kind === 'snippet') {
error(node, 'invalid-snippet-assignment');
}
}
if (node.name === 'group') {
@ -1011,8 +1015,10 @@ function validate_no_const_assignment(node, argument, scope, is_binding) {
function validate_assignment(node, argument, state) {
validate_no_const_assignment(node, argument, state.scope, false);
if (state.analysis.runes && argument.type === 'Identifier') {
if (argument.type === 'Identifier') {
const binding = state.scope.get(argument.name);
if (state.analysis.runes) {
if (binding?.kind === 'derived') {
error(node, 'invalid-derived-assignment');
}
@ -1022,6 +1028,11 @@ function validate_assignment(node, argument, state) {
}
}
if (binding?.kind === 'snippet') {
error(node, 'invalid-snippet-assignment');
}
}
let object = /** @type {import('estree').Expression | import('estree').Super} */ (argument);
/** @type {import('estree').Expression | import('estree').PrivateIdentifier | null} */

@ -649,7 +649,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
for (const param of node.parameters) {
for (const id of extract_identifiers(param)) {
child_scope.declare(id, 'each', 'let');
child_scope.declare(id, 'snippet', 'let');
}
}

@ -253,7 +253,8 @@ export interface Binding {
* - `rest_prop`: A rest prop
* - `state`: A state variable
* - `derived`: A derived variable
* - `each`: An each block context variable
* - `each`: An each block parameter
* - `snippet`: A snippet parameter
* - `store_sub`: A $store value
* - `legacy_reactive`: A `$:` declaration
* - `legacy_reactive_import`: An imported binding that is mutated inside the component
@ -267,6 +268,7 @@ export interface Binding {
| 'frozen_state'
| 'derived'
| 'each'
| 'snippet'
| 'store_sub'
| 'legacy_reactive'
| 'legacy_reactive_import';

@ -0,0 +1,8 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-snippet-assignment',
message: 'Cannot reassign or bind to snippet parameter'
}
});

@ -0,0 +1,3 @@
{#snippet foo(value)}
<input bind:value={value}>
{/snippet}

@ -0,0 +1,8 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-snippet-assignment',
message: 'Cannot reassign or bind to snippet parameter'
}
});

@ -0,0 +1,3 @@
{#snippet foo(value)}
<button onclick={() => value += 1}>click</button>
{/snippet}

@ -718,7 +718,8 @@ declare module 'svelte/compiler' {
* - `rest_prop`: A rest prop
* - `state`: A state variable
* - `derived`: A derived variable
* - `each`: An each block context variable
* - `each`: An each block parameter
* - `snippet`: A snippet parameter
* - `store_sub`: A $store value
* - `legacy_reactive`: A `$:` declaration
* - `legacy_reactive_import`: An imported binding that is mutated inside the component
@ -732,6 +733,7 @@ declare module 'svelte/compiler' {
| 'frozen_state'
| 'derived'
| 'each'
| 'snippet'
| 'store_sub'
| 'legacy_reactive'
| 'legacy_reactive_import';

Loading…
Cancel
Save