clean up diff

pull/16607/head
Jack Goodall 3 weeks ago
parent 9c9a1a841c
commit d4417cb245

@ -818,9 +818,8 @@ function read_sequence(parser, done, location) {
parser.allow_whitespace();
const has_spread = parser.match('...');
const has_spread = parser.eat('...');
if (has_spread) {
parser.eat('...', true);
parser.allow_whitespace();
}

@ -253,7 +253,7 @@ export function BindDirective(node, context) {
node.metadata = {
binding_group_name: group_name,
parent_each_blocks: each_blocks,
spread_binding: false
spread_binding: node.metadata.spread_binding
};
}

@ -197,6 +197,35 @@ export function build_component(node, component_name, context) {
push_prop(b.init(attribute.name, value));
}
} else if (attribute.type === 'BindDirective') {
const expression = /** @type {Expression} */ (context.visit(attribute.expression));
if (
dev &&
attribute.name !== 'this' &&
!is_ignored(node, 'ownership_invalid_binding') &&
// bind:x={() => x.y, y => x.y = y} and bind:x={...[() => x.y, y => x.y = y]}
// will be handled by the assignment expression binding validation
attribute.expression.type !== 'SequenceExpression' &&
!attribute.metadata.spread_binding
) {
const left = object(attribute.expression);
const binding = left && context.state.scope.get(left.name);
if (binding?.kind === 'bindable_prop' || binding?.kind === 'prop') {
context.state.analysis.needs_mutation_validation = true;
binding_initializers.push(
b.stmt(
b.call(
'$$ownership_validator.binding',
b.literal(binding.node.name),
b.id(is_component_dynamic ? intermediate_name : component_name),
b.thunk(expression)
)
)
);
}
}
if (attribute.metadata.spread_binding) {
const { get, set } = init_spread_bindings(attribute.expression, context);
@ -209,91 +238,57 @@ export function build_component(node, component_name, context) {
push_prop(b.get(attribute.name, [b.return(b.call(get))]), true);
push_prop(b.set(attribute.name, [b.stmt(b.call(set, b.id('$$value')))]), true);
}
} else {
const expression = /** @type {Expression} */ (context.visit(attribute.expression));
} else if (expression.type === 'SequenceExpression') {
if (attribute.name === 'this') {
bind_this = attribute.expression;
} else {
const [get, set] = expression.expressions;
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));
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 {
if (
dev &&
attribute.name !== 'this' &&
!is_ignored(node, 'ownership_invalid_binding') &&
// bind:x={() => x.y, y => x.y = y} will be handled by the assignment expression binding validation
attribute.expression.type !== 'SequenceExpression'
expression.type === 'MemberExpression' &&
context.state.analysis.runes &&
!is_ignored(node, 'binding_property_non_reactive')
) {
const left = object(attribute.expression);
const binding = left && context.state.scope.get(left.name);
if (binding?.kind === 'bindable_prop' || binding?.kind === 'prop') {
context.state.analysis.needs_mutation_validation = true;
binding_initializers.push(
b.stmt(
b.call(
'$$ownership_validator.binding',
b.literal(binding.node.name),
b.id(is_component_dynamic ? intermediate_name : component_name),
b.thunk(expression)
)
)
);
}
validate_binding(context.state, attribute, expression);
}
if (expression.type === 'SequenceExpression') {
if (attribute.name === 'this') {
bind_this = attribute.expression;
} else {
const [get, set] = expression.expressions;
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));
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')))]));
}
if (attribute.name === 'this') {
bind_this = attribute.expression;
} else {
if (
dev &&
expression.type === 'MemberExpression' &&
context.state.analysis.runes &&
!is_ignored(node, 'binding_property_non_reactive')
) {
validate_binding(context.state, attribute, expression);
}
if (attribute.name === 'this') {
bind_this = attribute.expression;
} else {
const is_store_sub =
attribute.expression.type === 'Identifier' &&
context.state.scope.get(attribute.expression.name)?.kind === 'store_sub';
// Delay prop pushes so bindings come at the end, to avoid spreads overwriting them
if (is_store_sub) {
push_prop(
b.get(attribute.name, [
b.stmt(b.call('$.mark_store_binding')),
b.return(expression)
]),
true
);
} else {
push_prop(b.get(attribute.name, [b.return(expression)]), true);
}
const assignment = b.assignment(
'=',
/** @type {Pattern} */ (attribute.expression),
b.id('$$value')
);
const is_store_sub =
attribute.expression.type === 'Identifier' &&
context.state.scope.get(attribute.expression.name)?.kind === 'store_sub';
// Delay prop pushes so bindings come at the end, to avoid spreads overwriting them
if (is_store_sub) {
push_prop(
b.set(attribute.name, [
b.stmt(/** @type {Expression} */ (context.visit(assignment)))
]),
b.get(attribute.name, [b.stmt(b.call('$.mark_store_binding')), b.return(expression)]),
true
);
} else {
push_prop(b.get(attribute.name, [b.return(expression)]), true);
}
const assignment = b.assignment(
'=',
/** @type {Pattern} */ (attribute.expression),
b.id('$$value')
);
push_prop(
b.set(attribute.name, [b.stmt(/** @type {Expression} */ (context.visit(assignment)))]),
true
);
}
}
} else if (attribute.type === 'AttachTag') {

@ -15,8 +15,7 @@ import type {
Program,
ChainExpression,
SimpleCallExpression,
SequenceExpression,
SpreadElement
SequenceExpression
} from 'estree';
import type { Scope } from '../phases/scope';
import type { _CSS } from './css';

Loading…
Cancel
Save