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 18937x 18937x 18937x 14603x 25x 25x 14578x 14578x 14578x 14578x 14603x 14603x 14603x 2911x 14603x 23x 23x 23x 23x 23x 23x 6x 23x 6x 6x 23x 14572x 14572x 14572x 18937x  
/** @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);
	}
}