All files / src/compiler/phases/3-transform/client/visitors Identifier.js

100% Statements 44/44
100% Branches 13/13
100% Functions 1/1
100% Lines 41/41

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 422x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 13221x 13221x 13221x 10585x 25x 25x 10560x 10560x 10560x 10560x 10585x 10585x 10585x 122x 10585x 7x 7x 7x 7x 7x 7x 3x 7x 3x 3x 7x 10557x 10557x 10557x 13221x  
/** @import { Identifier, Node } from 'estree' */
/** @import { Context } from '../types' */
import is_reference from 'is-reference';
import * as b from '../../../../utils/builders.js';
import { build_getter } from '../utils.js';
 
/**
 * @param {Identifier} node
 * @param {Context} context
 */
export function Identifier(node, context) {
	const parent = /** @type {Node} */ (context.path.at(-1));
 
	if (is_reference(node, parent)) {
		if (node.name === '$$props') {
			return b.id('$$sanitized_props');
		}
 
		// Optimize prop access: If it's a member read access, we can use the $$props object directly
		const binding = context.state.scope.get(node.name);
		if (
			context.state.analysis.runes && // can't do this in legacy mode because the proxy does more than just read/write
			binding !== null &&
			node !== binding.node &&
			binding.kind === 'rest_prop'
		) {
			const grand_parent = context.path.at(-2);
 
			if (
				parent?.type === 'MemberExpression' &&
				!parent.computed &&
				grand_parent?.type !== 'AssignmentExpression' &&
				grand_parent?.type !== 'UpdateExpression'
			) {
				return b.id('$$props');
			}
		}
 
		return build_getter(node, context.state);
	}
}