Skip to content

Commit 5ae974f

Browse files
committed
separate sync from async expressions
1 parent 6ea6e2d commit 5ae974f

File tree

7 files changed

+40
-20
lines changed

7 files changed

+40
-20
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export function client_component(analysis, options) {
175175
init: /** @type {any} */ (null),
176176
update: /** @type {any} */ (null),
177177
expressions: /** @type {any} */ (null),
178+
async_expressions: /** @type {any} */ (null),
178179
after_update: /** @type {any} */ (null),
179180
template: /** @type {any} */ (null),
180181
locations: /** @type {any} */ (null)

packages/svelte/src/compiler/phases/3-transform/client/types.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ export interface ComponentClientTransformState extends ClientTransformState {
5353
/** Stuff that happens after the render effect (control blocks, dynamic elements, bindings, actions, etc) */
5454
readonly after_update: Statement[];
5555
/** Expressions used inside the render effect */
56-
readonly expressions: Array<{ id: Identifier; expression: Expression; is_async: boolean }>;
56+
readonly expressions: Array<{ id: Identifier; expression: Expression }>;
57+
/** Expressions used inside the render effect */
58+
readonly async_expressions: Array<{ id: Identifier; expression: Expression }>;
5759
/** The HTML template string */
5860
readonly template: Array<string | Expression>;
5961
readonly locations: SourceLocation[];
@@ -113,3 +115,8 @@ export type ComponentVisitors = import('zimmerframe').Visitors<
113115
AST.SvelteNode,
114116
ComponentClientTransformState
115117
>;
118+
119+
export interface MemoizedExpression {
120+
id: Identifier;
121+
expression: Expression;
122+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export function Fragment(node, context) {
6464
init: [],
6565
update: [],
6666
expressions: [],
67+
async_expressions: [],
6768
after_update: [],
6869
template: [],
6970
locations: [],

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ function build_element_attribute_update_assignment(
543543

544544
let { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
545545
metadata.has_call || metadata.is_async
546-
? get_expression_id(state, value, metadata.is_async)
546+
? get_expression_id(metadata.is_async ? state.async_expressions : state.expressions, value)
547547
: value
548548
);
549549

@@ -673,7 +673,7 @@ function build_element_special_value_attribute(element, node_id, attribute, cont
673673
const state = context.state;
674674
const { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
675675
metadata.has_call || metadata.is_async
676-
? get_expression_id(state, value, metadata.is_async)
676+
? get_expression_id(metadata.is_async ? state.async_expressions : state.expressions, value)
677677
: value
678678
);
679679

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export function SvelteElement(node, context) {
4848
init: [],
4949
update: [],
5050
expressions: [],
51+
async_expressions: [],
5152
after_update: []
5253
}
5354
};

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ export function build_set_attributes(
4040
context,
4141
(value, metadata) =>
4242
metadata.has_call || metadata.is_async
43-
? get_expression_id(context.state, value, metadata.is_async)
43+
? get_expression_id(
44+
metadata.is_async ? context.state.async_expressions : context.state.expressions,
45+
value
46+
)
4447
: value
4548
);
4649

@@ -64,7 +67,12 @@ export function build_set_attributes(
6467
let value = /** @type {Expression} */ (context.visit(attribute));
6568

6669
if (attribute.metadata.expression.has_call || attribute.metadata.expression.is_async) {
67-
value = get_expression_id(context.state, value, attribute.metadata.expression.is_async);
70+
value = get_expression_id(
71+
attribute.metadata.expression.is_async
72+
? context.state.async_expressions
73+
: context.state.expressions,
74+
value
75+
);
6876
}
6977

7078
values.push(b.spread(value));
@@ -117,7 +125,10 @@ export function build_style_directives(
117125
? build_getter({ name: directive.name, type: 'Identifier' }, context.state)
118126
: build_attribute_value(directive.value, context, (value, metadata) =>
119127
metadata.has_call || metadata.is_async
120-
? get_expression_id(context.state, value, metadata.is_async)
128+
? get_expression_id(
129+
metadata.is_async ? context.state.async_expressions : context.state.expressions,
130+
value
131+
)
121132
: value
122133
).value;
123134

@@ -159,7 +170,7 @@ export function build_class_directives(
159170
let value = /** @type {Expression} */ (context.visit(directive.expression));
160171

161172
if (has_call || is_async) {
162-
value = get_expression_id(state, value, is_async);
173+
value = get_expression_id(is_async ? state.async_expressions : state.expressions, value);
163174
}
164175

165176
const update = b.stmt(b.call('$.toggle_class', element_id, b.literal(directive.name), value));

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

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
/** @import { Expression, ExpressionStatement, Identifier, MemberExpression, SequenceExpression, Statement, Super } from 'estree' */
1+
/** @import { Expression, ExpressionStatement, Identifier, MemberExpression, SequenceExpression, Super } from 'estree' */
22
/** @import { AST, ExpressionMetadata } from '#compiler' */
3-
/** @import { ComponentClientTransformState } from '../../types' */
3+
/** @import { ComponentClientTransformState, MemoizedExpression } from '../../types' */
44
import { walk } from 'zimmerframe';
55
import { object } from '../../../../../utils/ast.js';
66
import * as b from '../../../../../utils/builders.js';
@@ -22,19 +22,18 @@ export function memoize_expression(state, value) {
2222

2323
/**
2424
*
25-
* @param {ComponentClientTransformState} state
25+
* @param {MemoizedExpression[]} expressions
2626
* @param {Expression} expression
27-
* @param {boolean} is_async
2827
*/
29-
export function get_expression_id(state, expression, is_async) {
30-
for (let i = 0; i < state.expressions.length; i += 1) {
31-
if (compare_expressions(state.expressions[i].expression, expression)) {
32-
return state.expressions[i].id;
28+
export function get_expression_id(expressions, expression) {
29+
for (let i = 0; i < expressions.length; i += 1) {
30+
if (compare_expressions(expressions[i].expression, expression)) {
31+
return expressions[i].id;
3332
}
3433
}
3534

36-
const id = b.id(''); // filled in later
37-
state.expressions.push({ id, expression, is_async });
35+
const id = b.id('~'); // filled in later
36+
expressions.push({ id, expression });
3837

3938
return id;
4039
}
@@ -92,7 +91,7 @@ export function build_template_chunk(
9291
state,
9392
memoize = (value, metadata) =>
9493
metadata.has_call || metadata.is_async
95-
? get_expression_id(state, value, metadata.is_async)
94+
? get_expression_id(metadata.is_async ? state.async_expressions : state.expressions, value)
9695
: value
9796
) {
9897
/** @type {Expression[]} */
@@ -163,8 +162,8 @@ export function build_template_chunk(
163162
* @param {ComponentClientTransformState} state
164163
*/
165164
export function build_render_statement(state) {
166-
const sync = state.expressions.filter(({ is_async }) => !is_async);
167-
const async = state.expressions.filter(({ is_async }) => is_async);
165+
const sync = state.expressions;
166+
const async = state.async_expressions;
168167

169168
const all = [...sync, ...async];
170169

0 commit comments

Comments
 (0)