All files / src/compiler/phases/2-analyze/visitors EachBlock.js

100% Statements 40/40
100% Branches 13/13
100% Functions 1/1
100% Lines 38/38

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 392x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 980x 980x 980x 980x 980x 980x 980x 1x 1x 1x 979x 980x 219x 219x 219x 219x 979x 979x 979x 979x 979x 979x 979x 979x 980x 976x 980x  
/** @import { EachBlock } from '#compiler' */
/** @import { Context } from '../types' */
/** @import { Scope } from '../../scope' */
import * as e from '../../../errors.js';
import { validate_block_not_empty, validate_opening_tag } from './shared/utils.js';
 
/**
 * @param {EachBlock} node
 * @param {Context} context
 */
export function EachBlock(node, context) {
	validate_opening_tag(node, context.state, '#');
 
	validate_block_not_empty(node.body, context);
	validate_block_not_empty(node.fallback, context);
 
	const id = node.context;
	if (id.type === 'Identifier' && (id.name === '$state' || id.name === '$derived')) {
		// TODO weird that this is necessary
		e.state_invalid_placement(node, id.name);
	}
 
	if (node.key) {
		// treat `{#each items as item, i (i)}` as a normal indexed block, everything else as keyed
		node.metadata.keyed =
			node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index;
	}
 
	// evaluate expression in parent scope
	context.visit(node.expression, {
		...context.state,
		scope: /** @type {Scope} */ (context.state.scope.parent)
	});
 
	context.visit(node.body);
	if (node.key) context.visit(node.key);
	if (node.fallback) context.visit(node.fallback);
}