diff --git a/.changeset/odd-jobs-taste.md b/.changeset/odd-jobs-taste.md new file mode 100644 index 0000000000..5e2b097815 --- /dev/null +++ b/.changeset/odd-jobs-taste.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: wrap props in deriveds more conservatively in legacy mode diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index 5a0adfc40c..a62666e180 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -1263,8 +1263,9 @@ const common_visitors = { }, CallExpression(node, context) { if ( - context.state.expression?.type === 'ExpressionTag' || - (context.state.expression?.type === 'SpreadAttribute' && !is_known_safe_call(node, context)) + (context.state.expression?.type === 'ExpressionTag' || + context.state.expression?.type === 'SpreadAttribute') && + !is_known_safe_call(node, context) ) { context.state.expression.metadata.contains_call_expression = true; } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 082a6c4dee..ad36e02ddb 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -719,11 +719,10 @@ function serialize_inline_component(node, component_name, context) { const should_wrap_in_derived = Array.isArray(attribute.value) && attribute.value.some((n) => { - return ( - n.type === 'ExpressionTag' && - n.expression.type !== 'Identifier' && - n.expression.type !== 'MemberExpression' - ); + if (n.type !== 'ExpressionTag') return false; + return context.state.analysis.runes + ? n.metadata.contains_call_expression + : n.expression.type !== 'Identifier'; }); if (should_wrap_in_derived) { diff --git a/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/Child.svelte b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/Child.svelte new file mode 100644 index 0000000000..3b4b540cc9 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/Child.svelte @@ -0,0 +1,7 @@ + + + diff --git a/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/_config.js b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/_config.js new file mode 100644 index 0000000000..b1bb9e5d3c --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + test({ assert, logs, target }) { + assert.deepEqual(logs, ['x', 42]); + + const btn = target.querySelector('button'); + flushSync(() => btn?.click()); + + assert.deepEqual(logs, ['x', 42]); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/main.svelte b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/main.svelte new file mode 100644 index 0000000000..5845557173 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-prop-derived/main.svelte @@ -0,0 +1,9 @@ + + + + +