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

86.55% Statements 103/119
79.54% Branches 35/44
100% Functions 1/1
86.2% Lines 100/116

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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 1172x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2900x 2900x 2900x 2900x 2900x 2900x 1278x 2900x 2900x 51x 1x 1x 50x 51x     50x 50x 50x 51x 50x 51x 2x 2x 48x 48x 2900x 2900x 2x   2x 2x 2x   2900x 2900x 238x     238x 2900x 2900x 2900x 2900x 2900x 1116x 1116x 122x 1116x 5x 5x 1111x 1111x 2900x 2900x 2900x 152x 2x 2x 150x 150x 2x 2x 148x 2900x 2900x 10x     10x 2900x 2900x 14x     14x 2900x 2900x 24x     24x 2900x 2900x 4x     4x 2900x 2900x 7x 1x 1x 6x 2900x 2900x 4x     4x 2900x 2885x 2885x 2885x  
/** @import { CallExpression } from 'estree' */
/** @import { SvelteNode } from '#compiler' */
/** @import { Context } from '../types' */
import { get_rune } from '../../scope.js';
import * as e from '../../../errors.js';
import { get_parent } from '../../../utils/ast.js';
 
/**
 * @param {CallExpression} node
 * @param {Context} context
 */
export function CallExpression(node, context) {
	const parent = /** @type {SvelteNode} */ (get_parent(context.path, -1));
 
	const rune = get_rune(node, context.state.scope);
 
	switch (rune) {
		case null:
			break;
 
		case '$bindable':
			if (node.arguments.length > 1) {
				e.rune_invalid_arguments_length(node, '$bindable', 'zero or one arguments');
			}
 
			if (parent.type !== 'AssignmentPattern' || context.path.at(-3)?.type !== 'ObjectPattern') {
				e.bindable_invalid_location(node);
			}
 
			const declarator = context.path.at(-4);
			if (
				declarator?.type !== 'VariableDeclarator' ||
				get_rune(declarator.init, context.state.scope) !== '$props'
			) {
				e.bindable_invalid_location(node);
			}
 
			break;
 
		case '$host':
			if (node.arguments.length > 0) {
				e.rune_invalid_arguments(node, '$host');
			} else if (context.state.ast_type === 'module' || !context.state.analysis.custom_element) {
				e.host_invalid_placement(node);
			}
			break;
 
		case '$props':
			if (parent.type !== 'VariableDeclarator') {
				e.props_invalid_placement(node);
			}
			break;
 
		case '$state':
		case '$state.frozen':
		case '$derived':
		case '$derived.by':
			if (
				parent.type !== 'VariableDeclarator' &&
				!(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed)
			) {
				e.state_invalid_placement(node, rune);
			}
 
			break;
 
		case '$effect':
		case '$effect.pre':
			if (parent.type !== 'ExpressionStatement') {
				e.effect_invalid_placement(node);
			}
 
			if (node.arguments.length !== 1) {
				e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
			}
			break;
 
		case '$effect.tracking':
			if (node.arguments.length !== 0) {
				e.rune_invalid_arguments(node, rune);
			}
			break;
 
		case '$effect.root':
			if (node.arguments.length !== 1) {
				e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
			}
			break;
 
		case '$inspect':
			if (node.arguments.length < 1) {
				e.rune_invalid_arguments_length(node, rune, 'one or more arguments');
			}
			break;
 
		case '$inspect().with':
			if (node.arguments.length !== 1) {
				e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
			}
			break;
 
		case '$state.snapshot':
			if (node.arguments.length !== 1) {
				e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
			}
			break;
 
		case '$state.is':
			if (node.arguments.length !== 2) {
				e.rune_invalid_arguments_length(node, rune, 'exactly two arguments');
			}
			break;
	}
 
	context.next();
}