Skip to content

Commit 9f71f66

Browse files
committed
simpler to just keep it as a SequenceExpression
1 parent 8f925b9 commit 9f71f66

File tree

10 files changed

+50
-76
lines changed

10 files changed

+50
-76
lines changed

packages/svelte/src/compiler/phases/1-parse/state/element.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ function read_attribute(parser) {
507507
const colon_index = name.indexOf(':');
508508
const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index));
509509

510-
/** @type {Expression | [Expression, Expression] | null} */
510+
/** @type {Expression | null} */
511511
let expression = null;
512512

513513
/** @type {true | AST.ExpressionTag | Array<AST.Text | AST.ExpressionTag>} */
@@ -536,24 +536,11 @@ function read_attribute(parser) {
536536
!Array.isArray(value) &&
537537
value.expression.type === 'SequenceExpression'
538538
) {
539-
try {
540-
const bind_getter_setter = parse_expression_at(
541-
`[${parser.template.slice(value_start, value.expression.end)}]`,
542-
parser.ts,
543-
0
544-
);
545-
546-
if (
547-
bind_getter_setter.type !== 'ArrayExpression' ||
548-
bind_getter_setter.elements.length !== 2
549-
) {
550-
e.invalid_bind_directive(value_start);
551-
}
552-
expression = /** @type {[Expression, Expression]} */ (bind_getter_setter.elements);
553-
} catch {
554-
e.invalid_bind_directive(value_start);
539+
if (value.expression.expressions.length !== 2) {
540+
e.invalid_bind_directive(value);
555541
}
556542
}
543+
557544
end = parser.index;
558545
} else if (parser.match_regex(regex_starts_with_quote_characters)) {
559546
e.expected_token(parser.index, '=');

packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export function BindDirective(node, context) {
125125
// When dealing with bind getters/setters skip the specific binding validation
126126
// Group bindings aren't supported for getter/setters so we don't need to handle
127127
// the metadata
128-
if (Array.isArray(node.expression)) {
128+
if (node.expression.type === 'SequenceExpression') {
129129
if (node.name === 'group') {
130130
e.bind_group_invalid_expression(node);
131131
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { CallExpression, Expression, MemberExpression } from 'estree' */
1+
/** @import { CallExpression, Expression, MemberExpression, SequenceExpression } from 'estree' */
22
/** @import { AST, SvelteNode } from '#compiler' */
33
/** @import { ComponentContext } from '../types' */
44
import { dev, is_ignored } from '../../../../state.js';
@@ -20,10 +20,8 @@ export function BindDirective(node, context) {
2020

2121
let get, set;
2222

23-
if (Array.isArray(expression)) {
24-
const [get_expression, set_expression] = expression;
25-
get = /** @type {Expression} */ (context.visit(get_expression));
26-
set = /** @type {Expression} */ (context.visit(set_expression));
23+
if (expression.type === 'SequenceExpression') {
24+
[get, set] = /** @type {SequenceExpression} */ (context.visit(expression)).expressions;
2725
} else {
2826
if (
2927
dev &&

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

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Property, Statement } from 'estree' */
1+
/** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Property, SequenceExpression, Statement } from 'estree' */
22
/** @import { AST, TemplateNode } from '#compiler' */
33
/** @import { ComponentContext } from '../../types.js' */
44
import { dev, is_ignored } from '../../../../../state.js';
@@ -42,7 +42,7 @@ export function build_component(node, component_name, context, anchor = context.
4242
/** @type {Property[]} */
4343
const custom_css_props = [];
4444

45-
/** @type {Identifier | MemberExpression | [Expression, Expression] | null} */
45+
/** @type {Identifier | MemberExpression | SequenceExpression | null} */
4646
let bind_this = null;
4747

4848
/** @type {ExpressionStatement[]} */
@@ -161,13 +161,26 @@ export function build_component(node, component_name, context, anchor = context.
161161
push_prop(b.init(attribute.name, value));
162162
}
163163
} else if (attribute.type === 'BindDirective') {
164-
if (Array.isArray(attribute.expression)) {
164+
const expression = /** @type {Expression} */ (context.visit(attribute.expression));
165+
166+
if (dev && attribute.name !== 'this') {
167+
binding_initializers.push(
168+
b.stmt(
169+
b.call(
170+
b.id('$.add_owner_effect'),
171+
b.thunk(expression),
172+
b.id(component_name),
173+
is_ignored(node, 'ownership_invalid_binding') && b.true
174+
)
175+
)
176+
);
177+
}
178+
179+
if (expression.type === 'SequenceExpression') {
165180
if (attribute.name === 'this') {
166181
bind_this = attribute.expression;
167182
} else {
168-
const [get_expression, set_expression] = attribute.expression;
169-
const get = /** @type {Expression} */ (context.visit(get_expression));
170-
const set = /** @type {Expression} */ (context.visit(set_expression));
183+
const [get, set] = expression.expressions;
171184
const get_id = b.id(context.state.scope.generate('bind_get'));
172185
const set_id = b.id(context.state.scope.generate('bind_set'));
173186

@@ -178,8 +191,6 @@ export function build_component(node, component_name, context, anchor = context.
178191
push_prop(b.set(attribute.name, [b.stmt(b.call(set_id, b.id('$$value')))]));
179192
}
180193
} else {
181-
const expression = /** @type {Expression} */ (context.visit(attribute.expression));
182-
183194
if (
184195
dev &&
185196
expression.type === 'MemberExpression' &&
@@ -192,19 +203,6 @@ export function build_component(node, component_name, context, anchor = context.
192203
if (attribute.name === 'this') {
193204
bind_this = attribute.expression;
194205
} else {
195-
if (dev) {
196-
binding_initializers.push(
197-
b.stmt(
198-
b.call(
199-
b.id('$.add_owner_effect'),
200-
b.thunk(expression),
201-
b.id(component_name),
202-
is_ignored(node, 'ownership_invalid_binding') && b.true
203-
)
204-
)
205-
);
206-
}
207-
208206
const is_store_sub =
209207
attribute.expression.type === 'Identifier' &&
210208
context.state.scope.get(attribute.expression.name)?.kind === 'store_sub';

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,13 @@ export function build_update_assignment(state, id, init, value, update) {
161161

162162
/**
163163
* Serializes `bind:this` for components and elements.
164-
* @param {Identifier | MemberExpression | [Expression, Expression]} expression
164+
* @param {Identifier | MemberExpression | SequenceExpression} expression
165165
* @param {Expression} value
166166
* @param {import('zimmerframe').Context<SvelteNode, ComponentClientTransformState>} context
167167
*/
168168
export function build_bind_this(expression, value, { state, visit }) {
169-
if (Array.isArray(expression)) {
170-
const [get_expression, set_expression] = expression;
171-
const get = /** @type {Expression} */ (visit(get_expression));
172-
const set = /** @type {Expression} */ (visit(set_expression));
173-
169+
if (expression.type === 'SequenceExpression') {
170+
const [get, set] = /** @type {SequenceExpression} */ (visit(expression)).expressions;
174171
return b.call('$.bind_this', value, set, get);
175172
}
176173

@@ -250,7 +247,7 @@ export function build_bind_this(expression, value, { state, visit }) {
250247
* @param {MemberExpression} expression
251248
*/
252249
export function validate_binding(state, binding, expression) {
253-
if (Array.isArray(binding.expression)) {
250+
if (binding.expression.type === 'SequenceExpression') {
254251
return;
255252
}
256253
// If we are referencing a $store.foo then we don't need to add validation

packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { BlockStatement, Expression, Pattern, Property, Statement } from 'estree' */
1+
/** @import { BlockStatement, Expression, Pattern, Property, SequenceExpression, Statement } from 'estree' */
22
/** @import { AST, TemplateNode } from '#compiler' */
33
/** @import { ComponentContext } from '../../types.js' */
44
import { empty_comment, build_attribute_value } from './utils.js';
@@ -81,10 +81,9 @@ export function build_inline_component(node, expression, context) {
8181
const value = build_attribute_value(attribute.value, context, false, true);
8282
push_prop(b.prop('init', b.key(attribute.name), value));
8383
} else if (attribute.type === 'BindDirective' && attribute.name !== 'this') {
84-
if (Array.isArray(attribute.expression)) {
85-
const [get_expression, set_expression] = attribute.expression;
86-
const get = /** @type {Expression} */ (context.visit(get_expression));
87-
const set = /** @type {Expression} */ (context.visit(set_expression));
84+
if (attribute.expression.type === 'SequenceExpression') {
85+
const [get, set] = /** @type {SequenceExpression} */ (context.visit(attribute.expression))
86+
.expressions;
8887
const get_id = b.id(context.state.scope.generate('bind_get'));
8988
const set_id = b.id(context.state.scope.generate('bind_set'));
9089

packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,16 @@ export function build_element_attributes(node, context) {
109109
const binding = binding_properties[attribute.name];
110110
if (binding?.omit_in_ssr) continue;
111111

112-
if (is_content_editable_binding(attribute.name)) {
113-
content = Array.isArray(attribute.expression)
114-
? b.call(/** @type {Expression} */ (context.visit(attribute.expression[0])))
112+
const get =
113+
attribute.expression.type === 'SequenceExpression'
114+
? b.call(/** @type {Expression} */ (context.visit(attribute.expression.expressions[0])))
115115
: /** @type {Expression} */ (context.visit(attribute.expression));
116+
117+
if (is_content_editable_binding(attribute.name)) {
118+
content = get;
116119
} else if (attribute.name === 'value' && node.name === 'textarea') {
117-
content = b.call(
118-
'$.escape',
119-
Array.isArray(attribute.expression)
120-
? b.call(/** @type {Expression} */ (context.visit(attribute.expression[0])))
121-
: /** @type {Expression} */ (context.visit(attribute.expression))
122-
);
123-
} else if (attribute.name === 'group' && !Array.isArray(attribute.expression)) {
120+
content = b.call('$.escape', get);
121+
} else if (attribute.name === 'group' && attribute.expression.type !== 'SequenceExpression') {
124122
const value_attribute = /** @type {AST.Attribute | undefined} */ (
125123
node.attributes.find((attr) => attr.type === 'Attribute' && attr.name === 'value')
126124
);
@@ -158,18 +156,14 @@ export function build_element_attributes(node, context) {
158156
])
159157
);
160158
} else {
161-
const attribute_expression = Array.isArray(attribute.expression)
162-
? b.call(attribute.expression[0])
163-
: attribute.expression;
164-
165159
attributes.push(
166160
create_attribute(attribute.name, -1, -1, [
167161
{
168162
type: 'ExpressionTag',
169163
start: -1,
170164
end: -1,
171165
parent: attribute,
172-
expression: attribute_expression,
166+
expression: get,
173167
metadata: {
174168
expression: create_expression_metadata()
175169
}

packages/svelte/src/compiler/types/legacy-nodes.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export interface LegacyBinding extends BaseNode {
5050
/** The 'x' in `bind:x` */
5151
name: string;
5252
/** The y in `bind:x={y}` */
53-
expression: Identifier | MemberExpression | [Expression, Expression];
53+
expression: Identifier | MemberExpression | SequenceExpression;
5454
}
5555

5656
export interface LegacyBody extends BaseElement {

packages/svelte/src/compiler/types/template.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import type {
1414
Pattern,
1515
Program,
1616
ChainExpression,
17-
SimpleCallExpression
17+
SimpleCallExpression,
18+
SequenceExpression
1819
} from 'estree';
1920
import type { Scope } from '../phases/scope';
2021

@@ -185,7 +186,7 @@ export namespace AST {
185186
/** The 'x' in `bind:x` */
186187
name: string;
187188
/** The y in `bind:x={y}` */
188-
expression: Identifier | MemberExpression | [Expression, Expression];
189+
expression: Identifier | MemberExpression | SequenceExpression;
189190
/** @internal */
190191
metadata: {
191192
binding_group_name: Identifier;

packages/svelte/types/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ declare module 'svelte/animate' {
606606
}
607607

608608
declare module 'svelte/compiler' {
609-
import type { Expression, Identifier, ArrayExpression, ArrowFunctionExpression, VariableDeclaration, VariableDeclarator, MemberExpression, ObjectExpression, Pattern, Program, ChainExpression, SimpleCallExpression } from 'estree';
609+
import type { Expression, Identifier, ArrayExpression, ArrowFunctionExpression, VariableDeclaration, VariableDeclarator, MemberExpression, ObjectExpression, Pattern, Program, ChainExpression, SimpleCallExpression, SequenceExpression } from 'estree';
610610
import type { SourceMap } from 'magic-string';
611611
import type { Location } from 'locate-character';
612612
/**
@@ -1047,7 +1047,7 @@ declare module 'svelte/compiler' {
10471047
/** The 'x' in `bind:x` */
10481048
name: string;
10491049
/** The y in `bind:x={y}` */
1050-
expression: Identifier | MemberExpression | [Expression, Expression];
1050+
expression: Identifier | MemberExpression | SequenceExpression;
10511051
}
10521052

10531053
/** A `class:` directive */

0 commit comments

Comments
 (0)