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 5428x 4450x 4450x 1x 1x 4450x 5427x 5428x 1821x 1821x 5427x 5428x 1276x 1276x 5427x 5428x 177x 177x 177x 163x 163x 163x 31x 31x 31x 31x 31x 25x 25x 25x 25x 31x 8x 3x 3x 8x 31x 163x 177x 5427x 5427x 5427x  
/** @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();
}