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 19051x 19051x 19051x 14691x 25x 25x 14666x 14666x 14666x 14666x 14691x 14691x 14691x 2972x 14691x 23x 23x 23x 23x 23x 23x 6x 23x 6x 6x 23x 14660x 14660x 14660x 19051x  
/** @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);
	}
}