Skip to content

Commit a01f658

Browse files
authored
chore: tidy up each block compiler logic (#12513)
* small tidy-up * each_type -> flags * tidy up
1 parent ca2f02c commit a01f658

File tree

1 file changed

+23
-26
lines changed
  • packages/svelte/src/compiler/phases/3-transform/client/visitors

1 file changed

+23
-26
lines changed

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

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,7 +2362,6 @@ export const template_visitors = {
23622362
EachBlock(node, context) {
23632363
const each_node_meta = node.metadata;
23642364
const collection = /** @type {Expression} */ (context.visit(node.expression));
2365-
let each_item_is_reactive = true;
23662365

23672366
if (!each_node_meta.is_controlled) {
23682367
context.state.template.push('<!>');
@@ -2372,36 +2371,29 @@ export const template_visitors = {
23722371
context.state.init.push(b.const(each_node_meta.array_name, b.thunk(collection)));
23732372
}
23742373

2375-
// The runtime needs to know what kind of each block this is in order to optimize for the
2376-
// key === item (we avoid extra allocations). In that case, the item doesn't need to be reactive.
2377-
// We can guarantee this by knowing that in order for the item of the each block to change, they
2378-
// would need to mutate the key/item directly in the array. Given that in runes mode we use ===
2379-
// equality, we can apply a fast-path (as long as the index isn't reactive).
2380-
let each_type = 0;
2374+
let flags = 0;
23812375

23822376
if (
23832377
node.key &&
23842378
(node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index)
23852379
) {
2386-
each_type |= EACH_KEYED;
2387-
// If there's a destructuring, then we likely need the generated $$index
2388-
if (node.index || node.context.type !== 'Identifier') {
2389-
each_type |= EACH_INDEX_REACTIVE;
2380+
flags |= EACH_KEYED;
2381+
2382+
if (node.index) {
2383+
flags |= EACH_INDEX_REACTIVE;
23902384
}
2391-
if (
2392-
context.state.analysis.runes &&
2385+
2386+
// In runes mode, if key === item, we don't need to wrap the item in a source
2387+
const key_is_item =
23932388
node.key.type === 'Identifier' &&
23942389
node.context.type === 'Identifier' &&
2395-
node.context.name === node.key.name &&
2396-
(each_type & EACH_INDEX_REACTIVE) === 0
2397-
) {
2398-
// Fast-path for when the key === item
2399-
each_item_is_reactive = false;
2400-
} else {
2401-
each_type |= EACH_ITEM_REACTIVE;
2390+
node.context.name === node.key.name;
2391+
2392+
if (!context.state.analysis.runes || !key_is_item) {
2393+
flags |= EACH_ITEM_REACTIVE;
24022394
}
24032395
} else {
2404-
each_type |= EACH_ITEM_REACTIVE;
2396+
flags |= EACH_ITEM_REACTIVE;
24052397
}
24062398

24072399
// Since `animate:` can only appear on elements that are the sole child of a keyed each block,
@@ -2414,15 +2406,15 @@ export const template_visitors = {
24142406
return child.attributes.some((attr) => attr.type === 'AnimateDirective');
24152407
})
24162408
) {
2417-
each_type |= EACH_IS_ANIMATED;
2409+
flags |= EACH_IS_ANIMATED;
24182410
}
24192411

24202412
if (each_node_meta.is_controlled) {
2421-
each_type |= EACH_IS_CONTROLLED;
2413+
flags |= EACH_IS_CONTROLLED;
24222414
}
24232415

24242416
if (context.state.analysis.runes) {
2425-
each_type |= EACH_IS_STRICT_EQUALS;
2417+
flags |= EACH_IS_STRICT_EQUALS;
24262418
}
24272419

24282420
// If the array is a store expression, we need to invalidate it when the array is changed.
@@ -2447,10 +2439,12 @@ export const template_visitors = {
24472439
);
24482440
return [array, ...transitive_dependencies];
24492441
});
2442+
24502443
if (each_node_meta.array_name) {
24512444
indirect_dependencies.push(b.call(each_node_meta.array_name));
24522445
} else {
24532446
indirect_dependencies.push(collection);
2447+
24542448
const transitive_dependencies = serialize_transitive_dependencies(
24552449
each_node_meta.references,
24562450
context
@@ -2469,6 +2463,7 @@ export const template_visitors = {
24692463
// into separate expressions, at which point this is called again with an identifier or member expression
24702464
return serialize_set_binding(assignment, context, () => assignment);
24712465
}
2466+
24722467
const left = object(assignment.left);
24732468
const value = get_assignment_value(assignment, context);
24742469
const invalidate = b.call(
@@ -2509,10 +2504,12 @@ export const template_visitors = {
25092504
const item_with_loc = with_loc(item, id);
25102505
return b.call('$.unwrap', item_with_loc);
25112506
};
2507+
25122508
if (node.index) {
25132509
const index_binding = /** @type {import('#compiler').Binding} */ (
25142510
context.state.scope.get(node.index)
25152511
);
2512+
25162513
index_binding.expression = (id) => {
25172514
const index_with_loc = with_loc(index, id);
25182515
return b.call('$.unwrap', index_with_loc);
@@ -2575,7 +2572,7 @@ export const template_visitors = {
25752572
declarations.push(b.let(node.index, index));
25762573
}
25772574

2578-
if (context.state.options.dev && (each_type & EACH_KEYED) !== 0) {
2575+
if (context.state.options.dev && (flags & EACH_KEYED) !== 0) {
25792576
context.state.init.push(
25802577
b.stmt(b.call('$.validate_each_keys', b.thunk(collection), key_function))
25812578
);
@@ -2584,7 +2581,7 @@ export const template_visitors = {
25842581
/** @type {Expression[]} */
25852582
const args = [
25862583
context.state.node,
2587-
b.literal(each_type),
2584+
b.literal(flags),
25882585
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
25892586
key_function,
25902587
b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(block.body)))

0 commit comments

Comments
 (0)