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 117 118 119 120 121 122 123 124 125 126 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 45841x 45841x 45841x 45841x 9672x 9672x 36169x 36169x 36169x 36169x 36169x 45841x 3x 45841x 1x 1x 36168x 36168x 45841x 13x 13x 36168x 45841x 11222x 11222x 11222x 1817x 11222x 1765x 1765x 1765x 1765x 1765x 128x 128x 128x 128x 128x 128x 128x 2x 1x 1x 1x 2x 1x 2x 1x 1x 1x 128x 1763x 1765x 2x 2x 1765x 11222x 36164x 36164x 36164x 45763x 24946x 68x 68x 24946x 24946x 59x 59x 24946x 36164x 45841x 33058x 10348x 10348x 10348x 33058x 33058x 33058x 33058x 33058x 650x 650x 650x 56x 37x 37x 37x 650x 650x 33058x 42x 33058x 29x 33058x 24x 24x 33058x 33058x 33058x 33058x 34x 33058x 3x 3x 33058x 45841x | /** @import { Expression, Identifier } from 'estree' */
/** @import { EachBlock } from '#compiler' */
/** @import { Context } from '../types' */
import is_reference from 'is-reference';
import { should_proxy } from '../../3-transform/client/utils.js';
import * as e from '../../../errors.js';
import * as w from '../../../warnings.js';
import { is_rune } from '../../../../utils.js';
import { mark_subtree_dynamic } from './shared/fragment.js';
/**
* @param {Identifier} node
* @param {Context} context
*/
export function Identifier(node, context) {
let i = context.path.length;
let parent = /** @type {Expression} */ (context.path[--i]);
if (!is_reference(node, parent)) {
return;
}
mark_subtree_dynamic(context.path);
// If we are using arguments outside of a function, then throw an error
if (
node.name === 'arguments' &&
!context.path.some((n) => n.type === 'FunctionDeclaration' || n.type === 'FunctionExpression')
) {
e.invalid_arguments_usage(node);
}
// `$$slots` exists even in runes mode
if (node.name === '$$slots') {
context.state.analysis.uses_slots = true;
}
if (context.state.analysis.runes) {
if (
is_rune(node.name) &&
context.state.scope.get(node.name) === null &&
context.state.scope.get(node.name.slice(1)) === null
) {
/** @type {Expression} */
let current = node;
let name = node.name;
while (parent.type === 'MemberExpression') {
if (parent.computed) e.rune_invalid_computed_property(parent);
name += `.${/** @type {Identifier} */ (parent.property).name}`;
current = parent;
parent = /** @type {Expression} */ (context.path[--i]);
if (!is_rune(name)) {
if (name === '$effect.active') {
e.rune_renamed(parent, '$effect.active', '$effect.tracking');
}
if (name === '$state.frozen') {
e.rune_renamed(parent, '$state.frozen', '$state.raw');
}
if (name === '$state.is') {
e.rune_removed(parent, '$state.is');
}
e.rune_invalid_name(parent, name);
}
}
if (parent.type !== 'CallExpression') {
e.rune_missing_parentheses(current);
}
}
}
let binding = context.state.scope.get(node.name);
if (!context.state.analysis.runes) {
if (node.name === '$$props') {
context.state.analysis.uses_props = true;
}
if (node.name === '$$restProps') {
context.state.analysis.uses_rest_props = true;
}
}
if (binding) {
if (context.state.expression) {
context.state.expression.dependencies.add(binding);
context.state.expression.has_state ||= binding.kind !== 'normal';
}
if (
context.state.analysis.runes &&
node !== binding.node &&
context.state.function_depth === binding.scope.function_depth &&
// If we have $state that can be proxied or frozen and isn't re-assigned, then that means
// it's likely not using a primitive value and thus this warning isn't that helpful.
((binding.kind === 'state' &&
(binding.reassigned ||
(binding.initial?.type === 'CallExpression' &&
binding.initial.arguments.length === 1 &&
binding.initial.arguments[0].type !== 'SpreadElement' &&
!should_proxy(binding.initial.arguments[0], context.state.scope)))) ||
binding.kind === 'raw_state' ||
binding.kind === 'derived') &&
// We're only concerned with reads here
(parent.type !== 'AssignmentExpression' || parent.left !== node) &&
parent.type !== 'UpdateExpression'
) {
w.state_referenced_locally(node);
}
if (
context.state.reactive_statement &&
binding.scope === context.state.analysis.module.scope &&
binding.reassigned
) {
w.reactive_declaration_module_script_dependency(node);
}
}
}
|