All files / src/compiler/phases/3-transform/client/visitors/shared declarations.js

100% Statements 80/80
100% Branches 25/25
100% Functions 6/6
100% Lines 77/77

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 782x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2604x 2604x 2x 2x 2x 2x 2x 2x 6208x 9983x 9983x 9983x 9205x 9983x 842x 842x 842x 756x 756x 756x 756x 756x 756x 31x 31x 31x 31x 31x 756x 756x 8x 8x 756x 756x 842x 842x 85x 15x 15x 70x 70x 842x 842x 101x 101x 101x 101x 101x 101x 101x 101x 101x 101x 8x 8x 8x 8x 8x 101x 101x 101x 842x 842x 9983x 6208x  
/** @import { Expression, Identifier } from 'estree' */
/** @import { Location } from 'locate-character' */
/** @import { ComponentContext, Context } from '../../types' */
import { is_state_source } from '../../utils.js';
import * as b from '../../../../../utils/builders.js';
import { dev, filename, locator } from '../../../../../state.js';
 
/**
 * Turns `foo` into `$.get(foo)`
 * @param {Identifier} node
 */
export function get_value(node) {
	return b.call('$.get', node);
}
 
/**
 *
 * @param {Context | ComponentContext} context
 */
export function add_state_transformers(context) {
	for (const [name, binding] of context.state.scope.declarations) {
		if (
			is_state_source(binding, context.state.analysis) ||
			binding.kind === 'derived' ||
			binding.kind === 'legacy_reactive'
		) {
			context.state.transform[name] = {
				read: binding.declaration_kind === 'var' ? (node) => b.call('$.safe_get', node) : get_value,
				assign: (node, value) => {
					/** @type {Expression} */
					let call = b.call('$.set', node, value);
 
					const loc = dev && node.start !== undefined && locator(node.start);
 
					if (loc) {
						call = b.sequence([
							b.call('$.track_assignment', b.literal(`${filename}:${loc.line}:${loc.column}`)),
							call
						]);
					}
 
					if (context.state.scope.get(`$${node.name}`)?.kind === 'store_sub') {
						call = b.call('$.store_unsub', call, b.literal(`$${node.name}`), b.id('$$stores'));
					}
 
					return call;
				},
				mutate: (node, mutation) => {
					if (context.state.analysis.runes) {
						return mutation;
					}
 
					return b.call('$.mutate', node, mutation);
				},
				update: (node) => {
					/** @type {Expression} */
					let call = b.call(
						node.prefix ? '$.update_pre' : '$.update',
						node.argument,
						node.operator === '--' && b.literal(-1)
					);
 
					const loc = dev && node.start !== undefined && locator(node.start);
 
					if (loc) {
						call = b.sequence([
							b.call('$.track_assignment', b.literal(`${filename}:${loc.line}:${loc.column}`)),
							call
						]);
					}
 
					return call;
				}
			};
		}
	}
}