Skip to content

Commit 9c6028b

Browse files
committed
dedupe repeated code
1 parent 578b5df commit 9c6028b

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

packages/svelte/src/compiler/phases/3-transform/client/visitors/BindDirective.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { is_text_attribute } from '../../../../utils/ast.js';
66
import * as b from '#compiler/builders';
77
import { binding_properties } from '../../../bindings.js';
88
import { build_attribute_value } from './shared/element.js';
9-
import { build_bind_this, validate_binding } from './shared/utils.js';
9+
import { build_bind_this, validate_binding, handle_spread_binding } from './shared/utils.js';
1010

1111
/**
1212
* @param {AST.BindDirective} node
@@ -17,16 +17,9 @@ export function BindDirective(node, context) {
1717

1818
// Handle SpreadElement by creating a variable declaration before visiting
1919
if (node.expression.type === 'SpreadElement') {
20-
// Generate a unique variable name for this spread binding
21-
const id = b.id(context.state.scope.generate('$$bindings'));
22-
23-
// Store the spread expression in a variable at the component init level
24-
const spread_expression = /** @type {Expression} */ (context.visit(node.expression.argument));
25-
context.state.init.push(b.const(id, spread_expression));
26-
27-
// Use member access to get getter and setter
28-
get = b.member(id, b.literal(0), true);
29-
set = b.member(id, b.literal(1), true);
20+
const { get: getter, set: setter } = handle_spread_binding(node.expression, context.state, context.visit);
21+
get = getter;
22+
set = setter;
3023
} else {
3124
const expression = /** @type {Expression} */ (context.visit(node.expression));
3225

packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,25 @@ export function parse_directive_name(name) {
202202
return expression;
203203
}
204204

205+
/**
206+
* Handles SpreadElement by creating a variable declaration and returning getter/setter expressions
207+
* @param {SpreadElement} spread_expression
208+
* @param {ComponentClientTransformState} state
209+
* @param {function} visit
210+
* @returns {{get: Expression, set: Expression}}
211+
*/
212+
export function handle_spread_binding(spread_expression, state, visit) {
213+
// Generate a unique variable name for this spread binding
214+
const id = b.id(state.scope.generate('$$bindings'));
215+
216+
const visited_expression = /** @type {Expression} */ (visit(spread_expression.argument));
217+
state.init.push(b.const(id, visited_expression));
218+
219+
const get = b.member(id, b.literal(0), true);
220+
const set = b.member(id, b.literal(1), true);
221+
return { get, set };
222+
}
223+
205224
/**
206225
* Serializes `bind:this` for components and elements.
207226
* @param {Identifier | MemberExpression | SequenceExpression | SpreadElement} expression
@@ -210,16 +229,7 @@ export function parse_directive_name(name) {
210229
*/
211230
export function build_bind_this(expression, value, { state, visit }) {
212231
if (expression.type === 'SpreadElement') {
213-
// Generate a unique variable name for this spread binding
214-
const id = b.id(state.scope.generate('$$bindings'));
215-
216-
// Store the spread expression in a variable at the component init level
217-
const spread_expression = /** @type {Expression} */ (visit(expression.argument));
218-
state.init.push(b.const(id, spread_expression));
219-
220-
// Use member access to get getter and setter
221-
const get = b.member(id, b.literal(0), true);
222-
const set = b.member(id, b.literal(1), true);
232+
const { get, set } = handle_spread_binding(expression, state, visit);
223233
return b.call('$.bind_this', value, set, get);
224234
}
225235

@@ -304,7 +314,10 @@ export function build_bind_this(expression, value, { state, visit }) {
304314
* @param {MemberExpression} expression
305315
*/
306316
export function validate_binding(state, binding, expression) {
307-
if (binding.expression.type === 'SequenceExpression' || binding.expression.type === 'SpreadElement') {
317+
if (
318+
binding.expression.type === 'SequenceExpression' ||
319+
binding.expression.type === 'SpreadElement'
320+
) {
308321
return;
309322
}
310323
// If we are referencing a $store.foo then we don't need to add validation

0 commit comments

Comments
 (0)