All files / src/compiler/phases/2-analyze/visitors MemberExpression.js

100% Statements 58/58
100% Branches 24/24
100% Functions 1/1
100% Lines 54/54

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 42 43 44 45 46 47 48 49 50 51 52 53 54 552x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 5659x 4640x 4640x 1x 1x 4640x 5658x 5659x 1850x 1850x 5658x 5659x 1331x 1331x 5658x 5659x 184x 184x 184x 170x 170x 170x 35x 35x 35x 35x 35x 27x 27x 27x 27x 35x 12x 3x 3x 12x 35x 170x 184x 5658x 5658x 5658x  
/** @import { MemberExpression, Node } from 'estree' */
/** @import { Context } from '../types' */
import * as e from '../../../errors.js';
import * as w from '../../../warnings.js';
import { object } from '../../../utils/ast.js';
import { is_pure, is_safe_identifier } from './shared/utils.js';
 
/**
 * @param {MemberExpression} node
 * @param {Context} context
 */
export function MemberExpression(node, context) {
	if (node.object.type === 'Identifier' && node.property.type === 'Identifier') {
		const binding = context.state.scope.get(node.object.name);
		if (binding?.kind === 'rest_prop' && node.property.name.startsWith('$$')) {
			e.props_illegal_name(node.property);
		}
	}
 
	if (context.state.expression && !is_pure(node, context)) {
		context.state.expression.has_state = true;
	}
 
	if (!is_safe_identifier(node, context.state.scope)) {
		context.state.analysis.needs_context = true;
	}
 
	if (context.state.reactive_statement) {
		const left = object(node);
 
		if (left !== null) {
			const binding = context.state.scope.get(left.name);
 
			if (binding && binding.kind === 'normal') {
				const parent = /** @type {Node} */ (context.path.at(-1));
 
				if (
					binding.scope === context.state.analysis.module.scope ||
					binding.declaration_kind === 'import' ||
					(binding.initial &&
						binding.initial.type !== 'ArrayExpression' &&
						binding.initial.type !== 'ObjectExpression' &&
						binding.scope.function_depth <= 1)
				) {
					if (parent.type !== 'MemberExpression' && parent.type !== 'CallExpression') {
						w.reactive_declaration_non_reactive_property(node);
					}
				}
			}
		}
	}
 
	context.next();
}