Skip to content

Commit dcda57d

Browse files
committed
remove support for spreading objects
1 parent 9c05042 commit dcda57d

File tree

10 files changed

+34
-67
lines changed

10 files changed

+34
-67
lines changed

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,9 @@ export function analyze_component(root, source, options) {
714714
if (
715715
type === 'FunctionDeclaration' ||
716716
type === 'FunctionExpression' ||
717-
type === 'ArrowFunctionExpression'
717+
type === 'ArrowFunctionExpression' ||
718+
(type === 'BindDirective' &&
719+
/** @type {AST.BindDirective} */ (path[i]).metadata.spread_binding)
718720
) {
719721
continue inner;
720722
}

packages/svelte/src/compiler/phases/3-transform/shared/spread_bindings.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,32 @@ import { dev, source } from '../../../state.js';
1212
*/
1313
export function init_spread_bindings(spread_expression, { state, visit }) {
1414
const expression = /** @type {Expression} */ (visit(spread_expression));
15-
const expression_text = dev
16-
? b.literal(source.slice(spread_expression.start, spread_expression.end))
17-
: undefined;
15+
const expression_text = b.literal(source.slice(spread_expression.start, spread_expression.end));
1816

1917
const id = b.id(state.scope.generate('$$spread_binding'));
2018
state.init.push(
2119
b.const(
2220
id,
2321
b.call(
2422
'$.derived',
25-
b.thunk(b.call('$.validate_spread_bindings', expression, expression_text))
23+
b.thunk(
24+
dev ? b.call('$.validate_spread_bindings', expression, expression_text) : expression
25+
)
2626
)
2727
)
2828
);
2929

3030
const is_server = state.options.generate === 'server';
3131
const binding = is_server ? b.call(id) : b.call('$.get', id);
3232

33-
const get = b.thunk(b.call(b.member(binding, b.literal(0), true)));
33+
const get = b.thunk(
34+
b.call(b.logical('??', b.member(binding, b.literal(0), true), b.id('$.noop')))
35+
);
36+
3437
const set = b.arrow(
3538
[b.id('$$value')],
36-
b.call(b.member(binding, b.literal(1), true), b.id('$$value'))
39+
b.call(b.logical('??', b.member(binding, b.literal(1), true), b.id('$.noop')), b.id('$$value'))
3740
);
41+
3842
return { get, set };
3943
}

packages/svelte/src/internal/server/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ export { assign_payload, copy_payload } from './payload.js';
511511

512512
export { snapshot } from '../shared/clone.js';
513513

514-
export { fallback, to_array } from '../shared/utils.js';
514+
export { noop, fallback, to_array } from '../shared/utils.js';
515515

516516
export {
517517
invalid_default_snippet,

packages/svelte/src/internal/shared/validate.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,15 @@ export function prevent_snippet_stringification(fn) {
5353
* @return {[() => unknown, (value: unknown) => void]}
5454
*/
5555
export function validate_spread_bindings(spread_object, name) {
56-
const is_array = Array.isArray(spread_object);
57-
const getter = is_array ? spread_object[0] : spread_object.get;
58-
const setter = is_array ? spread_object[1] : spread_object.set;
56+
const getter = spread_object[0];
57+
const setter = spread_object[1];
5958

6059
if (typeof getter !== 'function' && getter != null) {
61-
e.invalid_spread_bindings(name + (is_array ? '[0]' : '.get'));
60+
e.invalid_spread_bindings(name + '[0]');
6261
}
6362
if (typeof setter !== 'function' && setter != null) {
64-
e.invalid_spread_bindings(name + (is_array ? '[1]' : '.set'));
63+
e.invalid_spread_bindings(name + '[1]');
6564
}
6665

67-
return [getter ?? noop, setter ?? noop];
66+
return [getter, setter];
6867
}

packages/svelte/tests/runtime-runes/samples/bind-spread-component/Child.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<script>
22
let { a = $bindable() } = $props();
33
4-
const bindings = $derived([
4+
const bindings = [
55
() => a,
66
(v) => {
77
console.log('b', v);
88
a = v;
99
}
10-
]);
10+
];
1111
</script>
1212

1313
<input

packages/svelte/tests/runtime-runes/samples/bind-spread-component/_config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { flushSync } from 'svelte';
22
import { test } from '../../test';
3-
import { assert_ok } from '../../../suite';
43

54
export default test({
65
async test({ assert, target, logs }) {
Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,15 @@
11
<script>
2-
const empty_bindings_array = []
3-
const empty_bindings_object = {}
4-
const incompatible_bindings_object = {
5-
read() {
6-
console.log('read');
7-
return true;
8-
},
9-
write(v) {
10-
console.log('write', v);
11-
}
12-
}
13-
const undefined_bindings_array = [undefined, undefined];
14-
const undefined_bindings_object = { get: undefined, set: undefined };
15-
const null_bindings_array = [null, null];
16-
const null_bindings_object = { get: null, set: null };
17-
182
function onchange(event) {
193
console.log('change', event.currentTarget.checked);
204
}
215
</script>
226

237
<input type="checkbox" {onchange} />
248

25-
<input type="checkbox" bind:checked={...empty_bindings_array} {onchange} />
26-
27-
<input type="checkbox" bind:checked={...empty_bindings_object} {onchange} />
28-
29-
<input type="checkbox" bind:checked={...incompatible_bindings_object} {onchange} />
30-
31-
<input type="checkbox" bind:checked={...undefined_bindings_array} {onchange} />
9+
<input type="checkbox" bind:checked={...[]} {onchange} />
3210

33-
<input type="checkbox" bind:checked={...undefined_bindings_object} {onchange} />
11+
<input type="checkbox" bind:checked={...[undefined, undefined]} {onchange} />
3412

35-
<input type="checkbox" bind:checked={...null_bindings_array} {onchange} />
13+
<input type="checkbox" bind:checked={...[null, null]} {onchange} />
3614

37-
<input type="checkbox" bind:checked={...null_bindings_object} {onchange} />
15+
<input type="checkbox" bind:checked={...{}} {onchange} />
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1 @@
1-
<script>
2-
function getInvalidBindings() {
3-
return { get: 'not a function', set: 'not a function' };
4-
}
5-
</script>
6-
7-
<input type="checkbox" bind:checked={...getInvalidBindings()} />
1+
<input type="checkbox" bind:checked={...['not a function', 'not a function' ]} />

packages/svelte/tests/runtime-runes/samples/bind-spread/_config.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ export default test({
1111

1212
checkboxes.forEach((checkbox) => checkbox.click());
1313

14-
assert.deepEqual(logs, [
15-
'getArrayBindings',
16-
'getObjectBindings',
17-
...repeatArray(checkboxes.length, ['check', false])
18-
]);
14+
assert.deepEqual(logs, ['getBindings', ...repeatArray(checkboxes.length, ['check', false])]);
1915
}
2016
});
2117

packages/svelte/tests/runtime-runes/samples/bind-spread/main.svelte

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,16 @@
77
check = v;
88
};
99
const bindings = [get, set];
10-
const nested = {deep: {
11-
bindings: [get, set],}
10+
const nested = {
11+
deep: {
12+
bindings: [get, set],
13+
},
1214
};
1315
14-
function getArrayBindings() {
15-
console.log('getArrayBindings');
16+
function getBindings() {
17+
console.log('getBindings');
1618
return [get, set];
1719
}
18-
19-
function getObjectBindings() {
20-
console.log('getObjectBindings');
21-
return { get, set };
22-
}
2320
</script>
2421

2522
<input type="checkbox" bind:checked={get, set} />
@@ -28,8 +25,6 @@
2825

2926
<input type="checkbox" bind:checked={...nested.deep.bindings} />
3027

31-
<input type="checkbox" bind:checked={...getArrayBindings()} />
28+
<input type="checkbox" bind:checked={...getBindings()} />
3229

3330
<input type="checkbox" bind:checked={...(() => [get, set])()} />
34-
35-
<input type="checkbox" bind:checked={...getObjectBindings()} />

0 commit comments

Comments
 (0)