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 18658x 18658x 18658x 14404x 25x 25x 14379x 14379x 14379x 14379x 14404x 14404x 14404x 2807x 14404x 21x 21x 21x 21x 21x 21x 6x 21x 6x 6x 21x 14373x 14373x 14373x 18658x  
/** @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);
	}
}