From 69b0bcd0c8caf98232f57c8df488c1b360631624 Mon Sep 17 00:00:00 2001 From: Nic <162764842+Nic-Polumeyv@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:29:47 -0400 Subject: [PATCH] scopes come from the parser's tables: a script is no longer walked, a template's javascript neither, and a reference finds its ancestors through the parser's parent links --- packages/svelte/src/compiler/migrate/index.js | 9 +- .../svelte/src/compiler/phases/1-parse/js.js | 37 +- .../src/compiler/phases/2-analyze/index.js | 21 +- .../2-analyze/visitors/LabeledStatement.js | 48 +- packages/svelte/src/compiler/phases/scope.js | 739 +++++++++++------- packages/svelte/src/compiler/utils/ast.js | 7 + 6 files changed, 529 insertions(+), 332 deletions(-) diff --git a/packages/svelte/src/compiler/migrate/index.js b/packages/svelte/src/compiler/migrate/index.js index 3baef3ecae..3da3d90034 100644 --- a/packages/svelte/src/compiler/migrate/index.js +++ b/packages/svelte/src/compiler/migrate/index.js @@ -746,11 +746,12 @@ const instance_script = { // Analyze declaration bindings to see if they're exclusively updated within a single reactive statement const possible_derived = bindings.every((binding) => binding.references.every((reference) => { - const declaration = reference.path.find((el) => el.type === 'VariableDeclaration'); - const assignment = reference.path.find((el) => el.type === 'AssignmentExpression'); - const update = reference.path.find((el) => el.type === 'UpdateExpression'); + const path = reference.path; + const declaration = path.find((el) => el.type === 'VariableDeclaration'); + const assignment = path.find((el) => el.type === 'AssignmentExpression'); + const update = path.find((el) => el.type === 'UpdateExpression'); const labeled = /** @type {LabeledStatement | undefined} */ ( - reference.path.find((el) => el.type === 'LabeledStatement' && el.label.name === '$') + path.find((el) => el.type === 'LabeledStatement' && el.label.name === '$') ); if ( diff --git a/packages/svelte/src/compiler/phases/1-parse/js.js b/packages/svelte/src/compiler/phases/1-parse/js.js index 2e34814dd0..41bee4d975 100644 --- a/packages/svelte/src/compiler/phases/1-parse/js.js +++ b/packages/svelte/src/compiler/phases/1-parse/js.js @@ -4,6 +4,7 @@ import * as teasel from '@teasel/parser'; import * as e from '../../errors.js'; import { find_matching_bracket } from './utils/bracket.js'; +import { parsed } from '../../utils/ast.js'; /** * A standalone module, as `analyze_module` reads one. @@ -28,12 +29,23 @@ export function parse(source, comments, typescript) { add_comments(source, comments, /** @type {teasel.Comment[]} */ (ast.comments)); delete ast.comments; - delete ast.scopes; - delete ast.bindings; + parsed.set(ast, tables(ast)); return ast; } +/** + * Takes the tables off an answer, so they reach the scope analysis without showing in the tree. + * @param {{ scopes?: any; bindings?: any; references?: any }} answer + */ +function tables(answer) { + const { scopes, bindings, references } = answer; + delete answer.scopes; + delete answer.bindings; + delete answer.references; + return { scopes, bindings, references }; +} + /** * The program inside a `