fix: loosen restrictions on $state rune for return statements

loosen-state-rune
Dominic Gannaway 8 months ago
parent 776ac3c176
commit 0aa99c63aa

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: loosen restrictions on $state rune for return statements

@ -174,7 +174,9 @@ const runes = {
'invalid-derived-location': () =>
`$derived() can only be used as a variable declaration initializer or a class field`,
'invalid-state-location': () =>
`$state() can only be used as a variable declaration initializer or a class field`,
`$state() can only be used as a variable declaration initializer, a class field or a return statement if passed an object or array`,
'invalid-state-frozen-location': () =>
`$state.frozen() can only be used as a variable declaration initializer or a class field`,
'invalid-effect-location': () => `$effect() can only be used as an expression statement`,
/**
* @param {boolean} is_binding

@ -8,6 +8,7 @@ import {
import { warn } from '../../warnings.js';
import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
import { disallowed_parapgraph_contents, interactive_elements } from '../1-parse/utils/html.js';
import { should_proxy_or_freeze } from '../3-transform/client/utils.js';
import { binding_properties } from '../bindings.js';
import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js';
import { is_custom_element_node } from '../nodes.js';
@ -717,10 +718,23 @@ function validate_call_expression(node, scope, path) {
if (rune === '$state' || rune === '$derived') {
if (parent.type === 'VariableDeclarator') return;
if (
parent.type === 'ReturnStatement' &&
node.arguments.length === 1 &&
node.arguments[0].type !== 'SpreadElement' &&
should_proxy_or_freeze(node.arguments[0])
)
return;
if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location');
}
if (rune === '$state.frozen') {
if (parent.type === 'VariableDeclarator') return;
if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
error(node, 'invalid-state-frozen-location');
}
if (rune === '$effect' || rune === '$effect.pre') {
if (parent.type !== 'ExpressionStatement') {
error(node, 'invalid-effect-location');

@ -154,6 +154,17 @@ export const javascript_visitors_runes = {
return { ...node, body };
},
ReturnStatement(node, { state, visit, next }) {
const rune = get_rune(node.argument, state.scope);
if (rune === '$state' && node.argument?.type === 'CallExpression') {
const value = /** @type {import('estree').Expression} **/ (visit(node.argument.arguments[0]));
return {
...node,
argument: b.call('$.proxy', value)
};
}
next();
},
VariableDeclaration(node, { state, visit }) {
const declarations = [];

Loading…
Cancel
Save