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 976x 976x 976x 976x 976x 976x 976x 1x 1x 1x 975x 976x 219x 219x 219x 219x 975x 975x 975x 975x 975x 975x 975x 975x 976x 972x 976x  
/** @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);
}