Home / File/ SnippetBlock.js — svelte Source File

SnippetBlock.js — svelte Source File

Architecture documentation for SnippetBlock.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
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb["SnippetBlock.js"]
  62f818c8_e890_17ed_5ec1_92f953d4a7a6["state.js"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> 62f818c8_e890_17ed_5ec1_92f953d4a7a6
  0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c["ast.js"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> 0c5c28a7_226d_4e7c_e75e_0853c0a9fc2c
  c254e734_2224_c309_f1f8_bb064e80b1af["extract_paths"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> c254e734_2224_c309_f1f8_bb064e80b1af
  1a53d630_ca18_6783_bd92_8c72517a9306["declarations.js"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> 1a53d630_ca18_6783_bd92_8c72517a9306
  b1380aab_0ea6_e12d_3df0_c3526fef2b75["get_value"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> b1380aab_0ea6_e12d_3df0_c3526fef2b75
  95c28355_f14c_c3cd_5a03_d5a53ca255bc["builders"]
  76dbb198_ccb5_ecf8_b96a_5a5edc5846fb --> 95c28355_f14c_c3cd_5a03_d5a53ca255bc
  7665e008_f37d_b860_a594_f2539a66af4e["transform-client.js"]
  7665e008_f37d_b860_a594_f2539a66af4e --> 76dbb198_ccb5_ecf8_b96a_5a5edc5846fb
  style 76dbb198_ccb5_ecf8_b96a_5a5edc5846fb fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

/** @import { AssignmentPattern, BlockStatement, Expression, Identifier, Statement } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types' */
import { dev } from '../../../../state.js';
import { extract_paths } from '../../../../utils/ast.js';
import * as b from '#compiler/builders';
import { get_value } from './shared/declarations.js';

/**
 * @param {AST.SnippetBlock} node
 * @param {ComponentContext} context
 */
export function SnippetBlock(node, context) {
	// TODO hoist where possible
	/** @type {(Identifier | AssignmentPattern)[]} */
	const args = [b.id('$$anchor')];
	/** @type {BlockStatement} */
	let body;

	/** @type {Statement[]} */
	const declarations = [];

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

	for (let i = 0; i < node.parameters.length; i++) {
		const argument = node.parameters[i];

		if (!argument) continue;

		if (argument.type === 'Identifier') {
			args.push(b.assignment_pattern(argument, b.id('$.noop')));
			transform[argument.name] = { read: b.call };

			continue;
		}

		let arg_alias = `$$arg${i}`;
		args.push(b.id(arg_alias));

		const { inserts, paths } = extract_paths(argument, b.maybe_call(b.id(arg_alias)));

		for (const { id, value } of inserts) {
			id.name = context.state.scope.generate('$$array');
			transform[id.name] = { read: get_value };

			declarations.push(
				b.var(id, b.call('$.derived', /** @type {Expression} */ (context.visit(b.thunk(value)))))
			);
		}

		for (const path of paths) {
			const name = /** @type {Identifier} */ (path.node).name;
			const needs_derived = path.has_default_value; // to ensure that default value is only called once
			const fn = b.thunk(/** @type {Expression} */ (context.visit(path.expression, child_state)));

			declarations.push(b.let(path.node, needs_derived ? b.call('$.derived_safe_equal', fn) : fn));

			transform[name] = {
				read: needs_derived ? get_value : b.call
			};

			// we need to eagerly evaluate the expression in order to hit any
			// 'Cannot access x before initialization' errors
			if (dev) {
				declarations.push(b.stmt(transform[name].read(b.id(name))));
			}
		}
	}
	const block = /** @type {BlockStatement} */ (context.visit(node.body, child_state)).body;
	body = b.block([
		dev ? b.stmt(b.call('$.validate_snippet_args', b.spread(b.id('arguments')))) : b.empty,
		...declarations,
		...block
	]);

	// in dev we use a FunctionExpression (not arrow function) so we can use `arguments`
	let snippet = dev
		? b.call('$.wrap_snippet', b.id(context.state.analysis.name), b.function(null, args, body))
		: b.arrow(args, body);

	const declaration = b.const(node.expression, snippet);

	// Top-level snippets are hoisted so they can be referenced in the `<script>`
	if (context.path.length === 1 && context.path[0].type === 'Fragment') {
		if (node.metadata.can_hoist) {
			context.state.module_level_snippets.push(declaration);
		} else {
			context.state.instance_level_snippets.push(declaration);
		}
	} else {
		context.state.snippets.push(declaration);
	}
}

Domain

Subdomains

Functions

Frequently Asked Questions

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