From 90baec16e68879a2eb1d898f706a34234bae4101 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 6 Jun 2025 19:12:48 -0400 Subject: [PATCH] WIP --- .../phases/2-analyze/visitors/AssignmentExpression.js | 4 ++++ .../compiler/phases/2-analyze/visitors/MemberExpression.js | 5 +++-- .../compiler/phases/2-analyze/visitors/UpdateExpression.js | 4 ++++ .../phases/3-transform/client/visitors/shared/utils.js | 7 ++++++- packages/svelte/src/compiler/phases/nodes.js | 4 +++- packages/svelte/src/compiler/types/index.d.ts | 4 ++++ 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js index 673c79f2df..39358f72fc 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js @@ -23,5 +23,9 @@ export function AssignmentExpression(node, context) { } } + if (context.state.expression) { + context.state.expression.has_assignment = true; + } + context.next(); } diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/MemberExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/MemberExpression.js index 245a164c71..0a3b386198 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/MemberExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/MemberExpression.js @@ -15,8 +15,9 @@ export function MemberExpression(node, context) { } } - if (context.state.expression && !is_pure(node, context)) { - context.state.expression.has_state = true; + if (context.state.expression) { + context.state.expression.has_member_expression = true; + context.state.expression.has_state ||= !is_pure(node, context); } if (!is_safe_identifier(node, context.state.scope)) { diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/UpdateExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/UpdateExpression.js index 13f4b9019e..ed48e026ac 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/UpdateExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/UpdateExpression.js @@ -21,5 +21,9 @@ export function UpdateExpression(node, context) { } } + if (context.state.expression) { + context.state.expression.has_assignment = true; + } + context.next(); } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js index cce6f15396..3b11341712 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js @@ -442,6 +442,12 @@ function is_pure_expression(expression) { * @param {ExpressionMetadata} metadata */ export function build_legacy_expression_2(context, expression, metadata) { + const value = /** @type {Expression} */ (context.visit(expression)); + + if (!metadata.has_call && !metadata.has_member_expression && !metadata.has_assignment) { + return value; + } + const sequence = b.sequence([]); for (const binding of metadata.dependencies) { @@ -460,7 +466,6 @@ export function build_legacy_expression_2(context, expression, metadata) { sequence.expressions.push(getter); } - const value = /** @type {Expression} */ (context.visit(expression)); sequence.expressions.push(b.call('$.untrack', b.thunk(value))); return sequence; diff --git a/packages/svelte/src/compiler/phases/nodes.js b/packages/svelte/src/compiler/phases/nodes.js index 2043747ed0..954f232424 100644 --- a/packages/svelte/src/compiler/phases/nodes.js +++ b/packages/svelte/src/compiler/phases/nodes.js @@ -63,7 +63,9 @@ export function create_expression_metadata() { return { dependencies: new Set(), has_state: false, - has_call: false + has_call: false, + has_member_expression: false, + has_assignment: false }; } diff --git a/packages/svelte/src/compiler/types/index.d.ts b/packages/svelte/src/compiler/types/index.d.ts index fdd6024726..5bcc99e147 100644 --- a/packages/svelte/src/compiler/types/index.d.ts +++ b/packages/svelte/src/compiler/types/index.d.ts @@ -285,6 +285,10 @@ export interface ExpressionMetadata { has_state: boolean; /** True if the expression involves a call expression (often, it will need to be wrapped in a derived) */ has_call: boolean; + /** True if the expression includes a member expression */ + has_member_expression: boolean; + /** True if the expression includes an assignment or an update */ + has_assignment: boolean; } export interface StateField {