diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index 8c6c3365b0..2cf0129c53 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -490,18 +490,25 @@ function validate_call_expression(node, scope, path) { const rune = get_rune(node, scope); if (rune === null) return; - if (rune === '$props' && path.at(-1)?.type !== 'VariableDeclarator') { + const parent = /** @type {import('#compiler').SvelteNode} */ (path.at(-1)); + + if (rune === '$props') { + if (parent.type === 'VariableDeclarator') return; error(node, 'invalid-props-location'); - } else if ( - (rune === '$state' || rune === '$derived') && - path.at(-1)?.type !== 'VariableDeclarator' && - path.at(-1)?.type !== 'PropertyDefinition' - ) { + } + + if (rune === '$state' || rune === '$derived') { + if (parent.type === 'VariableDeclarator') return; + if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return; error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location'); - } else if (rune === '$effect') { - if (path.at(-1)?.type !== 'ExpressionStatement') { + } + + if (rune === '$effect') { + if (parent.type !== 'ExpressionStatement') { error(node, 'invalid-effect-location'); - } else if (node.arguments.length !== 1) { + } + + if (node.arguments.length !== 1) { error(node, 'invalid-rune-args-length', '$effect', [1]); } } diff --git a/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js new file mode 100644 index 0000000000..b6dca4e40d --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'invalid-state-location', + message: '$state() can only be used as a variable declaration initializer or a class field', + position: process.platform === 'win32' ? [35, 43] : [33, 41] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/class-state-field-static/main.svelte b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/main.svelte new file mode 100644 index 0000000000..8eb861366b --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/main.svelte @@ -0,0 +1,5 @@ +