From b182a4181d65977a642e0612f2a83395ad6077d9 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 19 Jan 2024 20:39:23 +0000 Subject: [PATCH] loosen further --- .changeset/rotten-eggs-jog.md | 2 +- packages/svelte/src/compiler/errors.js | 2 +- .../src/compiler/phases/2-analyze/validation.js | 4 ++-- .../client/visitors/javascript-runes.js | 16 +++++----------- .../samples/class-state-field-static/_config.js | 3 ++- .../samples/runes-no-rune-each/_config.js | 3 ++- .../runes-wrong-state-placement-2/_config.js | 3 ++- .../runes-wrong-state-placement/_config.js | 3 ++- 8 files changed, 17 insertions(+), 19 deletions(-) diff --git a/.changeset/rotten-eggs-jog.md b/.changeset/rotten-eggs-jog.md index f2b5293fbb..92f3265a9a 100644 --- a/.changeset/rotten-eggs-jog.md +++ b/.changeset/rotten-eggs-jog.md @@ -2,4 +2,4 @@ "svelte": patch --- -fix: loosen restrictions on $state rune for return statements +fix: loosen restrictions on $state rune when passed objects or arrays diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 8bebfa8338..1f87e47184 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -174,7 +174,7 @@ 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, a class field or a return statement if passed an object or array`, + `$state() can only be used as a variable declaration initializer, a class field or if passed an object or array, can be used as an expression`, '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`, diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index 806510feb4..b3bc67c8cb 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -719,12 +719,12 @@ 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'); } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js index 1867d10b23..d75021e1fd 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js @@ -154,17 +154,6 @@ 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 = []; @@ -373,6 +362,11 @@ export const javascript_visitors_runes = { return transform_inspect_rune(node, context); } + if (rune === '$state') { + const value = /** @type {import('estree').Expression} **/ (context.visit(node.arguments[0])); + return b.call('$.proxy', value); + } + context.next(); } }; 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 index 3f35ed8759..7e4670094a 100644 --- 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 @@ -3,7 +3,8 @@ import { test } from '../../test'; export default test({ error: { code: 'invalid-state-location', - message: '$state() can only be used as a variable declaration initializer, a class field or a return statement if passed an object or array', + message: + '$state() can only be used as a variable declaration initializer, a class field or if passed an object or array, can be used as an expression', position: [33, 41] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/runes-no-rune-each/_config.js b/packages/svelte/tests/compiler-errors/samples/runes-no-rune-each/_config.js index 16deeaf1b7..678d7a2a26 100644 --- a/packages/svelte/tests/compiler-errors/samples/runes-no-rune-each/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/runes-no-rune-each/_config.js @@ -3,6 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'invalid-state-location', - message: '$state() can only be used as a variable declaration initializer, a class field or a return statement if passed an object or array' + message: + '$state() can only be used as a variable declaration initializer, a class field or if passed an object or array, can be used as an expression' } }); diff --git a/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement-2/_config.js b/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement-2/_config.js index 16deeaf1b7..678d7a2a26 100644 --- a/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement-2/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement-2/_config.js @@ -3,6 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'invalid-state-location', - message: '$state() can only be used as a variable declaration initializer, a class field or a return statement if passed an object or array' + message: + '$state() can only be used as a variable declaration initializer, a class field or if passed an object or array, can be used as an expression' } }); diff --git a/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement/_config.js b/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement/_config.js index 16deeaf1b7..678d7a2a26 100644 --- a/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/runes-wrong-state-placement/_config.js @@ -3,6 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'invalid-state-location', - message: '$state() can only be used as a variable declaration initializer, a class field or a return statement if passed an object or array' + message: + '$state() can only be used as a variable declaration initializer, a class field or if passed an object or array, can be used as an expression' } });