remove indirection

pull/15538/head
Rich Harris 4 months ago
parent 8c819e5bdd
commit 448cff1141

@ -1,5 +1,4 @@
/** @import { AST } from '#compiler' */
/** @import { TemplateOperation } from '../types.js' */
/** @import { Node, Element } from './types'; */
export class Template {
@ -14,43 +13,6 @@ export class Template {
#fragment = this.nodes;
/**
* @param {...TemplateOperation} nodes
* @deprecated
*/
push(...nodes) {
for (const node of nodes) {
switch (node.kind) {
case 'create_element':
this.create_element(node.name);
break;
case 'create_anchor':
this.create_anchor(node.data);
break;
case 'create_text':
this.create_text(node.nodes);
break;
case 'push_element': {
this.push_element();
break;
}
case 'pop_element': {
this.pop_element();
break;
}
case 'set_prop': {
this.set_prop(node.key, node.value);
break;
}
}
}
}
/** @param {string} name */
create_element(name) {
this.#element = {
@ -63,7 +25,7 @@ export class Template {
this.#fragment.push(this.#element);
}
/** @param {string | undefined} data */
/** @param {string} [data] */
create_anchor(data) {
this.#fragment.push({ type: 'anchor', data });
}

@ -37,31 +37,6 @@ export interface ClientTransformState extends TransformState {
>;
}
type TemplateOperation =
| {
kind: 'create_element';
name: string;
}
| {
kind: 'create_text';
nodes: AST.Text[];
}
| {
kind: 'create_anchor';
data?: string;
}
| {
kind: 'set_prop';
key: string;
value: string | undefined;
}
| {
kind: 'push_element';
}
| {
kind: 'pop_element';
};
export interface ComponentClientTransformState extends ClientTransformState {
readonly analysis: ComponentAnalysis;
readonly options: ValidatedCompileOptions;

@ -11,7 +11,7 @@ import { get_value } from './shared/declarations.js';
* @param {ComponentContext} context
*/
export function AwaitBlock(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
// Visit {#await <expression>} first to ensure that scopes are in the correct order
const expression = b.thunk(/** @type {Expression} */ (context.visit(node.expression)));

@ -7,5 +7,5 @@
*/
export function Comment(node, context) {
// We'll only get here if comments are not filtered out, which they are unless preserveComments is true
context.state.template.push({ kind: 'create_anchor', data: node.data });
context.state.template.create_anchor(node.data);
}

@ -32,7 +32,7 @@ export function EachBlock(node, context) {
);
if (!each_node_meta.is_controlled) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
}
let flags = 0;

@ -9,7 +9,7 @@ import * as b from '#compiler/builders';
* @param {ComponentContext} context
*/
export function HtmlTag(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
const expression = /** @type {Expression} */ (context.visit(node.expression));

@ -8,7 +8,7 @@ import * as b from '#compiler/builders';
* @param {ComponentContext} context
*/
export function IfBlock(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
const statements = [];
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));

@ -8,7 +8,7 @@ import * as b from '#compiler/builders';
* @param {ComponentContext} context
*/
export function KeyBlock(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
const key = /** @type {Expression} */ (context.visit(node.expression));
const body = /** @type {Expression} */ (context.visit(node.fragment));

@ -52,10 +52,7 @@ export function RegularElement(node, context) {
}
if (node.name === 'noscript') {
context.state.template.push({
kind: 'create_element',
name: 'noscript'
});
context.state.template.create_element('noscript');
return;
}
@ -75,10 +72,7 @@ export function RegularElement(node, context) {
context.state.metadata.context.template_contains_script_tag = true;
}
context.state.template.push({
kind: 'create_element',
name: node.name
});
context.state.template.create_element(node.name);
/** @type {Array<AST.Attribute | AST.SpreadAttribute>} */
const attributes = [];
@ -116,11 +110,7 @@ export function RegularElement(node, context) {
const { value } = build_attribute_value(attribute.value, context);
if (value.type === 'Literal' && typeof value.value === 'string') {
context.state.template.push({
kind: 'set_prop',
key: 'is',
value: value.value
});
context.state.template.set_prop('is', value.value);
continue;
}
}
@ -300,12 +290,10 @@ export function RegularElement(node, context) {
}
if (name !== 'class' || value) {
context.state.template.push({
kind: 'set_prop',
key: attribute.name,
value:
context.state.template.set_prop(
attribute.name,
is_boolean_attribute(name) && value === true ? undefined : value === true ? '' : value
});
);
}
} else if (name === 'autofocus') {
let { value } = build_attribute_value(attribute.value, context);
@ -337,7 +325,8 @@ export function RegularElement(node, context) {
) {
context.state.after_update.push(b.stmt(b.call('$.replay_events', node_id)));
}
context.state.template.push({ kind: 'push_element' });
context.state.template.push_element();
const metadata = {
...context.state.metadata,
@ -458,7 +447,7 @@ export function RegularElement(node, context) {
// @ts-expect-error
location.push(state.locations);
}
context.state.template.push({ kind: 'pop_element' });
context.state.template.pop_element();
}
/**

@ -9,7 +9,7 @@ import * as b from '#compiler/builders';
* @param {ComponentContext} context
*/
export function RenderTag(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
const expression = unwrap_optional(node.expression);

@ -11,7 +11,7 @@ import { memoize_expression } from './shared/utils.js';
*/
export function SlotElement(node, context) {
// <slot {a}>fallback</slot> --> $.slot($$slots.default, { get a() { .. } }, () => ...fallback);
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
/** @type {Property[]} */
const props = [];

@ -88,7 +88,7 @@ export function SvelteBoundary(node, context) {
b.call('$.boundary', context.state.node, props, b.arrow([b.id('$$anchor')], block))
);
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
context.state.init.push(
external_statements.length > 0 ? b.block([...external_statements, boundary]) : boundary
);

@ -13,7 +13,7 @@ import { build_render_statement } from './shared/utils.js';
* @param {ComponentContext} context
*/
export function SvelteElement(node, context) {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
/** @type {Array<AST.Attribute | AST.SpreadAttribute>} */
const attributes = [];

@ -1,6 +1,6 @@
/** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Pattern, Property, SequenceExpression, Statement } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext, TemplateOperation } from '../../types.js' */
/** @import { ComponentContext } from '../../types.js' */
import { dev, is_ignored } from '../../../../../state.js';
import { get_attribute_chunks, object } from '../../../../../utils/ast.js';
import * as b from '#compiler/builders';
@ -440,33 +440,28 @@ export function build_component(node, component_name, context, anchor = context.
}
if (Object.keys(custom_css_props).length > 0) {
/** @type {TemplateOperation[]} */
const template_operations = [];
if (context.state.metadata.namespace === 'svg') {
// this boils down to <g><!></g>
template_operations.push({ kind: 'create_element', name: 'g' });
template_operations.push({ kind: 'push_element' });
template_operations.push({ kind: 'create_anchor' });
template_operations.push({ kind: 'pop_element' });
context.state.template.create_element('g');
context.state.template.push_element();
context.state.template.create_anchor();
context.state.template.pop_element();
} else {
// this boils down to <svelte-css-wrapper style='display: contents'><!></svelte-css-wrapper>
template_operations.push({ kind: 'create_element', name: 'svelte-css-wrapper' });
template_operations.push({ kind: 'set_prop', key: 'style', value: 'display: contents' });
template_operations.push({ kind: 'push_element' });
template_operations.push({ kind: 'create_anchor' });
template_operations.push({ kind: 'pop_element' });
context.state.template.create_element('svelte-css-wrapper');
context.state.template.set_prop('style', 'display: contents');
context.state.template.push_element();
context.state.template.create_anchor();
context.state.template.pop_element();
}
context.state.template.push(...template_operations);
statements.push(
b.stmt(b.call('$.css_props', anchor, b.thunk(b.object(custom_css_props)))),
b.stmt(fn(b.member(anchor, 'lastChild'))),
b.stmt(b.call('$.reset', anchor))
);
} else {
context.state.template.push({ kind: 'create_anchor' });
context.state.template.create_anchor();
statements.push(b.stmt(fn(anchor)));
}

@ -64,16 +64,11 @@ export function process_children(nodes, initial, is_element, { visit, state }) {
function flush_sequence(sequence) {
if (sequence.every((node) => node.type === 'Text')) {
skipped += 1;
state.template.push({
kind: 'create_text',
nodes: sequence
});
state.template.create_text(sequence);
return;
}
state.template.push({
kind: 'create_text',
nodes: [{ type: 'Text', data: ' ', raw: ' ', start: -1, end: -1 }]
});
state.template.create_text([{ type: 'Text', data: ' ', raw: ' ', start: -1, end: -1 }]);
const { has_state, value } = build_template_chunk(sequence, visit, state);

Loading…
Cancel
Save