From 448cff1141638159bd52d0ac62e6d02152c07fe3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 21 May 2025 17:38:55 -0400 Subject: [PATCH] remove indirection --- .../client/transform-template/template.js | 40 +------------------ .../phases/3-transform/client/types.d.ts | 25 ------------ .../3-transform/client/visitors/AwaitBlock.js | 2 +- .../3-transform/client/visitors/Comment.js | 2 +- .../3-transform/client/visitors/EachBlock.js | 2 +- .../3-transform/client/visitors/HtmlTag.js | 2 +- .../3-transform/client/visitors/IfBlock.js | 2 +- .../3-transform/client/visitors/KeyBlock.js | 2 +- .../client/visitors/RegularElement.js | 31 +++++--------- .../3-transform/client/visitors/RenderTag.js | 2 +- .../client/visitors/SlotElement.js | 2 +- .../client/visitors/SvelteBoundary.js | 2 +- .../client/visitors/SvelteElement.js | 2 +- .../client/visitors/shared/component.js | 27 +++++-------- .../client/visitors/shared/fragment.js | 11 ++--- 15 files changed, 35 insertions(+), 119 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/template.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/template.js index 4a2a04676e..ca006504c5 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/template.js @@ -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 }); } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/types.d.ts b/packages/svelte/src/compiler/phases/3-transform/client/types.d.ts index ecb58545ae..d388ffe763 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/types.d.ts +++ b/packages/svelte/src/compiler/phases/3-transform/client/types.d.ts @@ -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; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js index 9680305b15..8a5031cd9f 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js @@ -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 } first to ensure that scopes are in the correct order const expression = b.thunk(/** @type {Expression} */ (context.visit(node.expression))); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/Comment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/Comment.js index c2cfce685f..1124c198a3 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/Comment.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/Comment.js @@ -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); } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js index 96be23dd16..fcdc8bda05 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js @@ -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; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js index f5e30ac17e..5d5b85a21b 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/HtmlTag.js @@ -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)); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js index 15002a4166..b6af5c79fe 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/IfBlock.js @@ -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)); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/KeyBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/KeyBlock.js index 7692e258e1..aa5fce595a 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/KeyBlock.js @@ -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)); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index 1e31c912cc..f1b7515ee3 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -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} */ 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: - is_boolean_attribute(name) && value === true ? undefined : value === true ? '' : 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(); } /** diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js index c199bce38c..2c09d602bc 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js @@ -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); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js index 86e0d85b7e..30f21024f1 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js @@ -11,7 +11,7 @@ import { memoize_expression } from './shared/utils.js'; */ export function SlotElement(node, context) { // fallback --> $.slot($$slots.default, { get a() { .. } }, () => ...fallback); - context.state.template.push({ kind: 'create_anchor' }); + context.state.template.create_anchor(); /** @type {Property[]} */ const props = []; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js index c496e2eaa7..2ce66cb4f4 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js @@ -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 ); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteElement.js index dde2558e94..75d1472f0f 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteElement.js @@ -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} */ const attributes = []; diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js index 26e760f6d1..fd7369b227 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js @@ -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 - 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 - 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))); } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js index 519cc062bb..70bf082b31 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js @@ -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);