Skip to content

Commit f6a2599

Browse files
authored
chore: remove memoize_expression (#16358)
1 parent df5801c commit f6a2599

File tree

3 files changed

+30
-44
lines changed

3 files changed

+30
-44
lines changed

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

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
/** @import { BlockStatement, Expression, ExpressionStatement, Literal, Property } from 'estree' */
1+
/** @import { BlockStatement, Expression, ExpressionStatement, Literal, Property, Statement } from 'estree' */
22
/** @import { AST } from '#compiler' */
33
/** @import { ComponentContext } from '../types' */
44
import * as b from '#compiler/builders';
55
import { build_attribute_value } from './shared/element.js';
6-
import { memoize_expression } from './shared/utils.js';
6+
import { Memoizer } from './shared/utils.js';
77

88
/**
99
* @param {AST.SlotElement} node
@@ -22,7 +22,7 @@ export function SlotElement(node, context) {
2222
/** @type {ExpressionStatement[]} */
2323
const lets = [];
2424

25-
let is_default = true;
25+
const memoizer = new Memoizer();
2626

2727
let name = b.literal('default');
2828

@@ -33,12 +33,11 @@ export function SlotElement(node, context) {
3333
const { value, has_state } = build_attribute_value(
3434
attribute.value,
3535
context,
36-
(value, metadata) => (metadata.has_call ? memoize_expression(context.state, value) : value)
36+
(value, metadata) => (metadata.has_call ? b.call('$.get', memoizer.add(value)) : value)
3737
);
3838

3939
if (attribute.name === 'name') {
4040
name = /** @type {Literal} */ (value);
41-
is_default = false;
4241
} else if (attribute.name !== 'slot') {
4342
if (has_state) {
4443
props.push(b.get(attribute.name, [b.return(value)]));
@@ -51,9 +50,14 @@ export function SlotElement(node, context) {
5150
}
5251
}
5352

53+
memoizer.apply();
54+
5455
// Let bindings first, they can be used on attributes
5556
context.state.init.push(...lets);
5657

58+
/** @type {Statement[]} */
59+
const statements = memoizer.deriveds(context.state.analysis.runes);
60+
5761
const props_expression =
5862
spreads.length === 0 ? b.object(props) : b.call('$.spread_props', b.object(props), ...spreads);
5963

@@ -62,14 +66,9 @@ export function SlotElement(node, context) {
6266
? b.null
6367
: b.arrow([b.id('$$anchor')], /** @type {BlockStatement} */ (context.visit(node.fragment)));
6468

65-
const slot = b.call(
66-
'$.slot',
67-
context.state.node,
68-
b.id('$$props'),
69-
name,
70-
props_expression,
71-
fallback
69+
statements.push(
70+
b.stmt(b.call('$.slot', context.state.node, b.id('$$props'), name, props_expression, fallback))
7271
);
7372

74-
context.state.init.push(b.stmt(slot));
73+
context.state.init.push(statements.length === 1 ? statements[0] : b.block(statements));
7574
}

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

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44
import { dev, is_ignored } from '../../../../../state.js';
55
import { get_attribute_chunks, object } from '../../../../../utils/ast.js';
66
import * as b from '#compiler/builders';
7-
import {
8-
build_bind_this,
9-
memoize_expression,
10-
validate_binding,
11-
add_svelte_meta
12-
} from '../shared/utils.js';
7+
import { add_svelte_meta, build_bind_this, Memoizer, validate_binding } from '../shared/utils.js';
138
import { build_attribute_value } from '../shared/element.js';
149
import { build_event_handler } from './events.js';
1510
import { determine_slot } from '../../../../../utils/slot.js';
@@ -48,6 +43,8 @@ export function build_component(node, component_name, context) {
4843
/** @type {Record<string, Expression[]>} */
4944
const events = {};
5045

46+
const memoizer = new Memoizer();
47+
5148
/** @type {Property[]} */
5249
const custom_css_props = [];
5350

@@ -133,15 +130,13 @@ export function build_component(node, component_name, context) {
133130
} else if (attribute.type === 'SpreadAttribute') {
134131
const expression = /** @type {Expression} */ (context.visit(attribute));
135132
if (attribute.metadata.expression.has_state) {
136-
let value = expression;
137-
138-
if (attribute.metadata.expression.has_call) {
139-
const id = b.id(context.state.scope.generate('spread_element'));
140-
context.state.init.push(b.var(id, b.call('$.derived', b.thunk(value))));
141-
value = b.call('$.get', id);
142-
}
143-
144-
props_and_spreads.push(b.thunk(value));
133+
props_and_spreads.push(
134+
b.thunk(
135+
attribute.metadata.expression.has_call
136+
? b.call('$.get', memoizer.add(expression))
137+
: expression
138+
)
139+
);
145140
} else {
146141
props_and_spreads.push(expression);
147142
}
@@ -150,10 +145,10 @@ export function build_component(node, component_name, context) {
150145
custom_css_props.push(
151146
b.init(
152147
attribute.name,
153-
build_attribute_value(attribute.value, context, (value, metadata) =>
148+
build_attribute_value(attribute.value, context, (value, metadata) => {
154149
// TODO put the derived in the local block
155-
metadata.has_call ? memoize_expression(context.state, value) : value
156-
).value
150+
return metadata.has_call ? b.call('$.get', memoizer.add(value)) : value;
151+
}).value
157152
)
158153
);
159154
continue;
@@ -184,7 +179,7 @@ export function build_component(node, component_name, context) {
184179
);
185180
});
186181

187-
return should_wrap_in_derived ? memoize_expression(context.state, value) : value;
182+
return should_wrap_in_derived ? b.call('$.get', memoizer.add(value)) : value;
188183
}
189184
);
190185

@@ -444,7 +439,7 @@ export function build_component(node, component_name, context) {
444439
};
445440
}
446441

447-
const statements = [...snippet_declarations];
442+
const statements = [...snippet_declarations, ...memoizer.deriveds(context.state.analysis.runes)];
448443

449444
if (is_component_dynamic) {
450445
const prev = fn;
@@ -492,5 +487,7 @@ export function build_component(node, component_name, context) {
492487
statements.push(add_svelte_meta(fn(anchor), node, 'component', { componentTag: node.name }));
493488
}
494489

490+
memoizer.apply();
491+
495492
return statements.length > 1 ? b.block(statements) : statements[0];
496493
}

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

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,7 @@ import { sanitize_template_string } from '../../../../../utils/sanitize_template
88
import { regex_is_valid_identifier } from '../../../../patterns.js';
99
import is_reference from 'is-reference';
1010
import { dev, is_ignored, locator, component_name } from '../../../../../state.js';
11-
import { build_getter, create_derived } from '../../utils.js';
12-
13-
/**
14-
* @param {ComponentClientTransformState} state
15-
* @param {Expression} value
16-
*/
17-
export function memoize_expression(state, value) {
18-
const id = b.id(state.scope.generate('expression'));
19-
state.init.push(b.const(id, create_derived(state, b.thunk(value))));
20-
return b.call('$.get', id);
21-
}
11+
import { build_getter } from '../../utils.js';
2212

2313
/**
2414
* A utility for extracting complex expressions (such as call expressions)

0 commit comments

Comments
 (0)