Home / File/ AssignmentExpression.js — svelte Source File

AssignmentExpression.js — svelte Source File

Architecture documentation for AssignmentExpression.js, a javascript file in the svelte codebase. 9 imports, 1 dependents.

File javascript Compiler Transformer 9 imports 1 dependents 3 functions

Entity Profile

Dependency Diagram

graph LR
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48["AssignmentExpression.js"]
  0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c["ast.js"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> 0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c
  a3992cec_6c90_d564_7bfc_3ad8518003cc["build_assignment_value"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> a3992cec_6c90_d564_7bfc_3ad8518003cc
  bbca3d2a_42c8_b215_d3b5_5077ccaf0797["nodes.js"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> bbca3d2a_42c8_b215_d3b5_5077ccaf0797
  d69a156c_617a_9397_4c8b_e94508c59e30["get_name"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> d69a156c_617a_9397_4c8b_e94508c59e30
  ee93d8a6_6fde_b1c1_e15b_3a4da5326305["scope.js"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> ee93d8a6_6fde_b1c1_e15b_3a4da5326305
  bed91719_d047_2256_e199_ee875d5f49b9["get_rune"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> bed91719_d047_2256_e199_ee875d5f49b9
  47b19192_eefb_9217_3996_3a0f4e07c6ed["assignments.js"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> 47b19192_eefb_9217_3996_3a0f4e07c6ed
  3f298b15_f3b3_11d6_21ea_d35e2d476f80["visit_assignment_expression"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> 3f298b15_f3b3_11d6_21ea_d35e2d476f80
  95c28355_f14c_c3cd_5a03_d5a53ca255bc["builders"]
  f75f2dc9_b2ee_72df_1184_7fbc8c163e48 --> 95c28355_f14c_c3cd_5a03_d5a53ca255bc
  86cf8685_38fa_3a1c_9b81_21c452968289["transform-server.js"]
  86cf8685_38fa_3a1c_9b81_21c452968289 --> f75f2dc9_b2ee_72df_1184_7fbc8c163e48
  style f75f2dc9_b2ee_72df_1184_7fbc8c163e48 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

/** @import { AssignmentExpression, AssignmentOperator, Expression, Pattern } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { Context, ServerTransformState } from '../types.js' */
import * as b from '#compiler/builders';
import { build_assignment_value } from '../../../../utils/ast.js';
import { get_name } from '../../../nodes.js';
import { get_rune } from '../../../scope.js';
import { visit_assignment_expression } from '../../shared/assignments.js';

/**
 * @param {AssignmentExpression} node
 * @param {Context} context
 */
export function AssignmentExpression(node, context) {
	return visit_assignment_expression(node, context, build_assignment) ?? context.next();
}

/**
 * Only returns an expression if this is not a `$store` assignment, as others can be kept as-is
 * @param {AssignmentOperator} operator
 * @param {Pattern} left
 * @param {Expression} right
 * @param {import('zimmerframe').Context<AST.SvelteNode, ServerTransformState>} context
 * @returns {Expression | null}
 */
function build_assignment(operator, left, right, context) {
	if (
		context.state.analysis.runes &&
		left.type === 'MemberExpression' &&
		left.object.type === 'ThisExpression' &&
		!left.computed
	) {
		const name = get_name(left.property);
		const field = name && context.state.state_fields.get(name);

		// special case — state declaration in class constructor
		if (field && field.node.type === 'AssignmentExpression' && left === field.node.left) {
			const rune = get_rune(right, context.state.scope);

			if (rune) {
				const key =
					left.property.type === 'PrivateIdentifier' || rune === '$state' || rune === '$state.raw'
						? left.property
						: field.key;

				return b.assignment(
					operator,
					b.member(b.this, key, key.type === 'Literal'),
					/** @type {Expression} */ (context.visit(right))
				);
			}
		} else if (
			field &&
			(field.type === '$derived' || field.type === '$derived.by') &&
			left.property.type === 'PrivateIdentifier'
		) {
			let value = /** @type {Expression} */ (
				context.visit(build_assignment_value(operator, left, right))
			);
			return b.call(b.member(b.this, name), value);
		}
	}

	let object = left;

	while (object.type === 'MemberExpression') {
		// @ts-expect-error
		object = object.object;
	}

	if (object.type !== 'Identifier' || !is_store_name(object.name)) {
		return null;
	}

	const name = object.name.slice(1);

	if (!context.state.scope.get(name)) {
		return null;
	}

	if (object === left) {
		let value = /** @type {Expression} */ (
			context.visit(build_assignment_value(operator, left, right))
		);

		return b.call('$.store_set', b.id(name), value);
	}

	return b.call(
		'$.store_mutate',
		b.assignment('??=', b.id('$$store_subs'), b.object([])),
		b.literal(object.name),
		b.id(name),
		b.assignment(
			operator,
			/** @type {Pattern} */ (context.visit(left)),
			/** @type {Expression} */ (context.visit(right))
		)
	);
}

/**
 * @param {string} name
 */
function is_store_name(name) {
	return name[0] === '$' && /[A-Za-z_]/.test(name[1]);
}

Domain

Subdomains

Frequently Asked Questions

What does AssignmentExpression.js do?
AssignmentExpression.js is a source file in the svelte codebase, written in javascript. It belongs to the Compiler domain, Transformer subdomain.
What functions are defined in AssignmentExpression.js?
AssignmentExpression.js defines 3 function(s): AssignmentExpression, build_assignment, is_store_name.
What does AssignmentExpression.js depend on?
AssignmentExpression.js imports 9 module(s): assignments.js, ast.js, build_assignment_value, builders, get_name, get_rune, nodes.js, scope.js, and 1 more.
What files import AssignmentExpression.js?
AssignmentExpression.js is imported by 1 file(s): transform-server.js.
Where is AssignmentExpression.js in the architecture?
AssignmentExpression.js is located at packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js (domain: Compiler, subdomain: Transformer, directory: packages/svelte/src/compiler/phases/3-transform/server/visitors).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free