diff --git a/.changeset/slimy-donkeys-hang.md b/.changeset/slimy-donkeys-hang.md new file mode 100644 index 0000000000..d63141660e --- /dev/null +++ b/.changeset/slimy-donkeys-hang.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: add support for bind getters/setters diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js index 9babedc46d..f0afeb4dd7 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js @@ -42,7 +42,7 @@ export function build_component(node, component_name, context, anchor = context. /** @type {Property[]} */ const custom_css_props = []; - /** @type {Identifier | MemberExpression | null} */ + /** @type {Identifier | MemberExpression | [Expression, Expression] | null} */ let bind_this = null; /** @type {ExpressionStatement[]} */ @@ -162,17 +162,21 @@ export function build_component(node, component_name, context, anchor = context. } } else if (attribute.type === 'BindDirective') { if (Array.isArray(attribute.expression)) { - const [get_expression, set_expression] = attribute.expression; - const get = /** @type {Expression} */ (context.visit(get_expression)); - const set = /** @type {Expression} */ (context.visit(set_expression)); - const get_id = b.id(context.state.scope.generate('bind_get')); - const set_id = b.id(context.state.scope.generate('bind_set')); + if (attribute.name === 'this') { + bind_this = attribute.expression; + } else { + const [get_expression, set_expression] = attribute.expression; + const get = /** @type {Expression} */ (context.visit(get_expression)); + const set = /** @type {Expression} */ (context.visit(set_expression)); + const get_id = b.id(context.state.scope.generate('bind_get')); + const set_id = b.id(context.state.scope.generate('bind_set')); - context.state.init.push(b.var(get_id, get)); - context.state.init.push(b.var(set_id, set)); + context.state.init.push(b.var(get_id, get)); + context.state.init.push(b.var(set_id, set)); - push_prop(b.get(attribute.name, [b.return(b.call(get_id))])); - push_prop(b.set(attribute.name, [b.stmt(b.call(set_id, b.id('$$value')))])); + push_prop(b.get(attribute.name, [b.return(b.call(get_id))])); + push_prop(b.set(attribute.name, [b.stmt(b.call(set_id, b.id('$$value')))])); + } } else { const expression = /** @type {Expression} */ (context.visit(attribute.expression)); 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 575ff5dd69..400be7a08d 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 @@ -171,7 +171,7 @@ export function build_bind_this(expression, value, { state, visit }) { const get = /** @type {Expression} */ (visit(get_expression)); const set = /** @type {Expression} */ (visit(set_expression)); - return b.call('$.bind_this', value, get, set); + return b.call('$.bind_this', value, set, get); } /** @type {Identifier[]} */ diff --git a/packages/svelte/tests/runtime-runes/samples/bind-getter-setter-2/Child.svelte b/packages/svelte/tests/runtime-runes/samples/bind-getter-setter-2/Child.svelte new file mode 100644 index 0000000000..0026309d44 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/bind-getter-setter-2/Child.svelte @@ -0,0 +1,11 @@ + + +