Home / File/ ClassBody.js — svelte Source File

ClassBody.js — svelte Source File

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

File javascript Compiler Transformer 6 imports 1 dependents 1 functions

Entity Profile

Dependency Diagram

graph LR
  b3660a8f_0eea_ece0_adac_3539aff5c652["ClassBody.js"]
  62f818c8_e890_17ed_5ec1_92f953d4a7a6["state.js"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> 62f818c8_e890_17ed_5ec1_92f953d4a7a6
  0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c["ast.js"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> 0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c
  68a38b3b_6f0f_ed43_404f_3d00302677a2["get_parent"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> 68a38b3b_6f0f_ed43_404f_3d00302677a2
  bbca3d2a_42c8_b215_d3b5_5077ccaf0797["nodes.js"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> bbca3d2a_42c8_b215_d3b5_5077ccaf0797
  d69a156c_617a_9397_4c8b_e94508c59e30["get_name"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> d69a156c_617a_9397_4c8b_e94508c59e30
  95c28355_f14c_c3cd_5a03_d5a53ca255bc["builders"]
  b3660a8f_0eea_ece0_adac_3539aff5c652 --> 95c28355_f14c_c3cd_5a03_d5a53ca255bc
  7665e008_f37d_b860_a594_f2539a66af4e["transform-client.js"]
  7665e008_f37d_b860_a594_f2539a66af4e --> b3660a8f_0eea_ece0_adac_3539aff5c652
  style b3660a8f_0eea_ece0_adac_3539aff5c652 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

/** @import { CallExpression, ClassBody, ClassDeclaration, ClassExpression, MethodDefinition, PropertyDefinition, StaticBlock } from 'estree' */
/** @import { StateField } from '#compiler' */
/** @import { Context } from '../types' */
import * as b from '#compiler/builders';
import { dev } from '../../../../state.js';
import { get_parent } from '../../../../utils/ast.js';
import { get_name } from '../../../nodes.js';

/**
 * @param {ClassBody} node
 * @param {Context} context
 */
export function ClassBody(node, context) {
	const state_fields = context.state.analysis.classes.get(node);

	if (!state_fields) {
		// in legacy mode, do nothing
		context.next();
		return;
	}

	/** @type {Array<MethodDefinition | PropertyDefinition | StaticBlock>} */
	const body = [];

	const child_state = { ...context.state, state_fields };

	for (const [name, field] of state_fields) {
		if (name[0] === '#') {
			continue;
		}

		// insert backing fields for stuff declared in the constructor
		if (field.node.type === 'AssignmentExpression') {
			const member = b.member(b.this, field.key);

			const should_proxy = field.type === '$state' && true; // TODO

			const key = b.key(name);

			body.push(
				b.prop_def(field.key, null),

				b.method('get', key, [], [b.return(b.call('$.get', member))]),

				b.method(
					'set',
					key,
					[b.id('value')],
					[b.stmt(b.call('$.set', member, b.id('value'), should_proxy && b.true))]
				)
			);
		}
	}

	const declaration = /** @type {ClassDeclaration | ClassExpression} */ (
		get_parent(context.path, -1)
	);

	// Replace parts of the class body
	for (const definition of node.body) {
		if (definition.type !== 'PropertyDefinition') {
			body.push(
				/** @type {MethodDefinition | StaticBlock} */ (context.visit(definition, child_state))
			);
			continue;
		}

		const name = get_name(definition.key);
		const field = name && /** @type {StateField} */ (state_fields.get(name));

		if (!field) {
			body.push(/** @type {PropertyDefinition} */ (context.visit(definition, child_state)));
			continue;
		}

		if (name[0] === '#') {
			let value = definition.value
				? /** @type {CallExpression} */ (context.visit(definition.value, child_state))
				: undefined;

			if (dev && field.node === definition) {
				value = b.call('$.tag', value, b.literal(`${declaration.id?.name ?? '[class]'}.${name}`));
			}

			body.push(b.prop_def(definition.key, value));
		} else if (field.node === definition) {
			let call = /** @type {CallExpression} */ (context.visit(field.value, child_state));

			if (dev) {
				call = b.call('$.tag', call, b.literal(`${declaration.id?.name ?? '[class]'}.${name}`));
			}
			const member = b.member(b.this, field.key);
			const should_proxy = field.type === '$state' && true; // TODO

			body.push(
				b.prop_def(field.key, call),

				b.method('get', definition.key, [], [b.return(b.call('$.get', member))]),

				b.method(
					'set',
					definition.key,
					[b.id('value')],
					[b.stmt(b.call('$.set', member, b.id('value'), should_proxy && b.true))]
				)
			);
		}
	}

	return { ...node, body };
}

Domain

Subdomains

Functions

Frequently Asked Questions

What does ClassBody.js do?
ClassBody.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 ClassBody.js?
ClassBody.js defines 1 function(s): ClassBody.
What does ClassBody.js depend on?
ClassBody.js imports 6 module(s): ast.js, builders, get_name, get_parent, nodes.js, state.js.
What files import ClassBody.js?
ClassBody.js is imported by 1 file(s): transform-client.js.
Where is ClassBody.js in the architecture?
ClassBody.js is located at packages/svelte/src/compiler/phases/3-transform/client/visitors/ClassBody.js (domain: Compiler, subdomain: Transformer, directory: packages/svelte/src/compiler/phases/3-transform/client/visitors).

Analyze Your Own Codebase

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

Try Supermodel Free