All files / src/compiler/phases/3-transform/server/visitors EachBlock.js

100% Statements 65/65
100% Branches 8/8
100% Functions 1/1
100% Lines 62/62

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 632x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 1x 1x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 486x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 26x 486x 460x 460x 486x  
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import { BLOCK_OPEN_ELSE } from '../../../../../internal/server/hydration.js';
import * as b from '../../../../utils/builders.js';
import { block_close, block_open } from './shared/utils.js';
 
/**
 * @param {AST.EachBlock} node
 * @param {ComponentContext} context
 */
export function EachBlock(node, context) {
	const state = context.state;
 
	const each_node_meta = node.metadata;
	const collection = /** @type {Expression} */ (context.visit(node.expression));
	const index =
		each_node_meta.contains_group_binding || !node.index ? each_node_meta.index : b.id(node.index);
 
	const array_id = state.scope.root.unique('each_array');
	state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
 
	/** @type {Statement[]} */
	const each = [b.let(/** @type {Pattern} */ (node.context), b.member(array_id, index, true))];
 
	if (index.name !== node.index && node.index != null) {
		each.push(b.let(node.index, index));
	}
 
	each.push(.../** @type {BlockStatement} */ (context.visit(node.body)).body);
 
	const for_loop = b.for(
		b.declaration('let', [
			b.declarator(index, b.literal(0)),
			b.declarator('$$length', b.member(array_id, 'length'))
		]),
		b.binary('<', index, b.id('$$length')),
		b.update('++', index, false),
		b.block(each)
	);
 
	if (node.fallback) {
		const open = b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open));
 
		const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
 
		fallback.body.unshift(
			b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
		);
 
		state.template.push(
			b.if(
				b.binary('!==', b.member(array_id, 'length'), b.literal(0)),
				b.block([open, for_loop]),
				fallback
			),
			block_close
		);
	} else {
		state.template.push(block_open, for_loop, block_close);
	}
}