fix: loosen restrictions on $state rune for return statements

pull/10239/head
Dominic Gannaway 10 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': () => 'invalid-derived-location': () =>
`$derived() can only be used as a variable declaration initializer or a class field`, `$derived() can only be used as a variable declaration initializer or a class field`,
'invalid-state-location': () => '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`, 'invalid-effect-location': () => `$effect() can only be used as an expression statement`,
/** /**
* @param {boolean} is_binding * @param {boolean} is_binding

@ -8,6 +8,7 @@ import {
import { warn } from '../../warnings.js'; import { warn } from '../../warnings.js';
import fuzzymatch from '../1-parse/utils/fuzzymatch.js'; import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
import { disallowed_parapgraph_contents, interactive_elements } from '../1-parse/utils/html.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 { binding_properties } from '../bindings.js';
import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js'; import { ContentEditableBindings, EventModifiers, SVGElements } from '../constants.js';
import { is_custom_element_node } from '../nodes.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 (rune === '$state' || rune === '$derived') {
if (parent.type === 'VariableDeclarator') return; 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; if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location'); 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 (rune === '$effect' || rune === '$effect.pre') {
if (parent.type !== 'ExpressionStatement') { if (parent.type !== 'ExpressionStatement') {
error(node, 'invalid-effect-location'); error(node, 'invalid-effect-location');

@ -154,6 +154,17 @@ export const javascript_visitors_runes = {
return { ...node, body }; 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 }) { VariableDeclaration(node, { state, visit }) {
const declarations = []; const declarations = [];

Loading…
Cancel
Save