From 0b3e74fbc28a8a6fc4a503517be10f77678cf4f6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 19 Nov 2024 15:14:37 -0500 Subject: [PATCH] put the code where it's used --- .../phases/2-analyze/visitors/SnippetBlock.js | 54 ++++++++++++++++++- .../src/compiler/phases/3-transform/utils.js | 50 ----------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js index 81b4a71bc0..93f8c8e10f 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js @@ -1,8 +1,8 @@ -/** @import { AST, Binding } from '#compiler' */ +/** @import { AST, Binding, SvelteNode } from '#compiler' */ +/** @import { Scope } from '../../scope' */ /** @import { Context } from '../types' */ import { validate_block_not_empty, validate_opening_tag } from './shared/utils.js'; import * as e from '../../../errors.js'; -import { can_hoist_snippet } from '../../3-transform/utils.js'; /** * @param {AST.SnippetBlock} node @@ -76,3 +76,53 @@ export function SnippetBlock(node, context) { } } } + +/** + * @param {AST.SnippetBlock} node + * @param {Map} scopes + * @param {Scope} scope + */ +function can_hoist_snippet(node, scope, scopes, visited = new Set()) { + let can_hoist = true; + + ref_loop: for (const [reference] of scope.references) { + const local_binding = scope.get(reference); + + if (local_binding) { + if (local_binding.node === node.expression || local_binding.scope.function_depth === 0) { + continue; + } + /** @type {Scope | null} */ + let current_scope = local_binding.scope; + + while (current_scope !== null) { + if (current_scope === scope) { + continue ref_loop; + } + current_scope = current_scope.parent; + } + + // Recursively check if another snippet can be hoisted + if (local_binding.kind === 'normal') { + for (const ref of local_binding.references) { + const parent = ref.path.at(-1); + if (ref.node === local_binding.node && parent?.type === 'SnippetBlock') { + const ref_scope = scopes.get(parent); + if (visited.has(ref)) { + break; + } + visited.add(ref); + if (ref_scope && can_hoist_snippet(parent, ref_scope, scopes, visited)) { + continue ref_loop; + } + break; + } + } + } + can_hoist = false; + break; + } + } + + return can_hoist; +} diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index 96baee3a4a..4d8e9aa514 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -453,53 +453,3 @@ export function transform_inspect_rune(node, context) { return b.call('$.inspect', as_fn ? b.thunk(b.array(arg)) : b.array(arg)); } } - -/** - * @param {AST.SnippetBlock} node - * @param {Map} scopes - * @param {Scope} scope - */ -export function can_hoist_snippet(node, scope, scopes, visited = new Set()) { - let can_hoist = true; - - ref_loop: for (const [reference] of scope.references) { - const local_binding = scope.get(reference); - - if (local_binding) { - if (local_binding.node === node.expression || local_binding.scope.function_depth === 0) { - continue; - } - /** @type {Scope | null} */ - let current_scope = local_binding.scope; - - while (current_scope !== null) { - if (current_scope === scope) { - continue ref_loop; - } - current_scope = current_scope.parent; - } - - // Recursively check if another snippet can be hoisted - if (local_binding.kind === 'normal') { - for (const ref of local_binding.references) { - const parent = ref.path.at(-1); - if (ref.node === local_binding.node && parent?.type === 'SnippetBlock') { - const ref_scope = scopes.get(parent); - if (visited.has(ref)) { - break; - } - visited.add(ref); - if (ref_scope && can_hoist_snippet(parent, ref_scope, scopes, visited)) { - continue ref_loop; - } - break; - } - } - } - can_hoist = false; - break; - } - } - - return can_hoist; -}