cleaner error messages

Jack Goodall 2 months ago
parent c8294cc632
commit a9ffe159ec

@ -1,4 +1,4 @@
/** @import { Expression, MemberExpression, SequenceExpression, SpreadElement, Literal, Super, UpdateExpression, ExpressionStatement } from 'estree' */
/** @import { CallExpression, Expression, SpreadElement, Super } from 'estree' */
/** @import { ComponentClientTransformState } from '../client/types.js' */
/** @import { ComponentServerTransformState } from '../server/types.js' */
import * as b from '#compiler/builders';
@ -17,20 +17,33 @@ export function handle_spread_binding(spread_expression, state, visit) {
const visited_expression = /** @type {Expression} */ (visit(spread_expression.argument));
state.init.push(b.const(id, visited_expression));
// Create conditional expressions that work for both arrays and objects
// Array.isArray($$bindings) ? $$bindings[0] : $$bindings.get
const get = b.conditional(
b.call('Array.isArray', id),
b.member(id, b.literal(0), true),
b.member(id, b.id('get'))
);
const noop = b.arrow([], b.block([]));
// Generate helper variables for clearer error messages
const get = b.id(state.scope.generate(id.name + '_get'));
const set = b.id(state.scope.generate(id.name + '_set'));
// Array.isArray($$bindings) ? $$bindings[1] : $$bindings.set
const set = b.conditional(
b.call('Array.isArray', id),
b.member(id, b.literal(1), true),
b.member(id, b.id('set'))
const getter = b.logical(
'??',
b.conditional(
b.call('Array.isArray', id),
b.member(id, b.literal(0), true),
b.member(id, b.id('get'))
),
noop
);
const setter = b.logical(
'??',
b.conditional(
b.call('Array.isArray', id),
b.member(id, b.literal(1), true),
b.member(id, b.id('set'))
),
noop
);
state.init.push(b.const(get, getter));
state.init.push(b.const(set, setter));
return { get, set };
}

@ -9,9 +9,8 @@ export default test({
assert.htmlEqual(target.innerHTML, `<input type="checkbox" >`.repeat(checkboxes.length));
flushSync(() => {
checkboxes.forEach((checkbox) => checkbox.click());
});
checkboxes.forEach((checkbox) => checkbox.click());
assert.deepEqual(logs, [
'getArrayBindings',
'getObjectBindings',

@ -1,33 +1,35 @@
<script>
let check = $state(true);
let check_bindings = [
() => check,
(v) => {
console.log('check', v);
check = v;
}
];
const get = () => check;
const set = (v) => {
console.log('check', v);
check = v;
};
const bindings = [get, set];
const nested = {deep: {
bindings: [get, set],}
};
function getArrayBindings() {
console.log('getArrayBindings');
return check_bindings;
return [get, set];
}
function getObjectBindings() {
console.log('getObjectBindings');
const [get, set] = check_bindings;
return { get, set };
}
</script>
<input type="checkbox" bind:checked={get, set} />
<input type="checkbox" bind:checked={check_bindings[0], check_bindings[1]} />
<input type="checkbox" bind:checked={...bindings} />
<input type="checkbox" bind:checked={...check_bindings} />
<input type="checkbox" bind:checked={...nested.deep.bindings} />
<input type="checkbox" bind:checked={...getArrayBindings()} />
<input type="checkbox" bind:checked={...(() => check_bindings)()} />
<input type="checkbox" bind:checked={...(() => [get, set])()} />
<input type="checkbox" bind:checked={...getObjectBindings()} />

Loading…
Cancel
Save