From e81c669ae07000b73fa34cb6759fd42aab619145 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Wed, 21 May 2025 18:54:02 +0200 Subject: [PATCH] chore: refactor `to-functions` to be sane --- .../client/transform-template/to-functions.js | 81 +++++++++---------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/to-functions.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/to-functions.js index ecf8151836..8da8331f16 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/transform-template/to-functions.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-template/to-functions.js @@ -1,9 +1,7 @@ /** * @import { TemplateOperations } from "../types.js" - * @import { Namespace } from "#compiler" - * @import { CallExpression, Statement, ObjectExpression, Identifier, ArrayExpression, Property, Expression, Literal } from "estree" + * @import { ObjectExpression, Identifier, ArrayExpression, Property, Expression, Literal } from "estree" */ -import { NAMESPACE_SVG, NAMESPACE_MATHML } from '../../../../../constants.js'; import * as b from '../../../../utils/builders.js'; import { regex_is_valid_identifier } from '../../../patterns.js'; import fix_attribute_casing from './fix-attribute-casing.js'; @@ -30,41 +28,42 @@ export function template_to_functions(items) { } for (let instruction of items) { - // on push element we add the element to the stack, from this moment on every insert will - // happen on the last element in the stack - if (instruction.kind === 'push_element' && last_current_element) { - elements_stack.push(last_current_element); - continue; - } - // we closed one element, we remove it from the stack and eventually revert back - // the namespace to the previous one - if (instruction.kind === 'pop_element') { - elements_stack.pop(); - continue; - } - - // @ts-expect-error we can't be here if `swap_current_element` but TS doesn't know that - const value = map[instruction.kind]( - ...[ - ...(instruction.kind === 'create_element' - ? [] - : [instruction.kind === 'set_prop' ? last_current_element : elements_stack.at(-1)]), - ...(instruction.args ?? []) - ] - ); - - // with set_prop we don't need to do anything else, in all other cases we also need to - // append the element/node/anchor to the current active element or push it in the elements array - if (instruction.kind !== 'set_prop') { - if (elements_stack.length >= 1 && value !== undefined) { - map.insert(/** @type {Element} */ (elements_stack.at(-1)), value); - } else if (value !== undefined) { + const args = instruction.args ?? []; + const last_element_stack = /** @type {Element} */ (elements_stack.at(-1)); + /** + * @param {Expression | null | void} value + * @returns + */ + function push(value) { + if (value === undefined) return; + if (last_element_stack) { + insert(last_element_stack, value); + } else { elements.elements.push(value); } - // keep track of the last created element (it will be pushed to the stack after the props are set) - if (instruction.kind === 'create_element') { - last_current_element = /** @type {Element} */ (value); - } + } + + switch (instruction.kind) { + case 'push_element': + elements_stack.push(/** @type {Element} */ (last_current_element)); + break; + case 'pop_element': + elements_stack.pop(); + last_current_element = elements_stack.at(-1); + break; + case 'create_element': + last_current_element = create_element(args[0]); + push(last_current_element); + break; + case 'create_text': + push(create_text(last_element_stack, args[0])); + break; + case 'create_anchor': + push(create_anchor(last_element_stack, args[0])); + break; + case 'set_prop': + set_prop(/** @type {Element} */ (last_current_element), args[0], args[1]); + break; } } @@ -166,17 +165,9 @@ function set_prop(element, prop, value) { /** * * @param {Element} element - * @param {Element} child + * @param {Expression | null} child */ function insert(element, child) { const c = get_or_create_prop(element, 'c', b.array([])); /** @type {ArrayExpression} */ (c.value).elements.push(child); } - -let map = { - create_element, - create_text, - create_anchor, - set_prop, - insert -};