diff --git a/packages/svelte/src/compiler/phases/scope.js b/packages/svelte/src/compiler/phases/scope.js index 401372b6d214..1ba9851ee3c9 100644 --- a/packages/svelte/src/compiler/phases/scope.js +++ b/packages/svelte/src/compiler/phases/scope.js @@ -1,3 +1,6 @@ +/** @import { ClassDeclaration, Expression, FunctionDeclaration, Identifier, ImportDeclaration, MemberExpression, Node, Pattern, VariableDeclarator } from 'estree' */ +/** @import { Context, Visitor, Visitors } from 'zimmerframe' */ +/** @import { AnimateDirective, Binding, DeclarationKind, EachBlock, ElementLike, LetDirective, SvelteNode, TransitionDirective, UseDirective } from '#compiler' */ import is_reference from 'is-reference'; import { walk } from 'zimmerframe'; import { is_element_node } from './nodes.js'; @@ -30,20 +33,20 @@ export class Scope { /** * A map of every identifier declared by this scope, and all the * identifiers that reference it - * @type {Map} + * @type {Map} */ declarations = new Map(); /** * A map of declarators to the bindings they declare - * @type {Map} + * @type {Map} */ declarators = new Map(); /** * A set of all the names referenced with this scope * — useful for generating unique names - * @type {Map} + * @type {Map} */ references = new Map(); @@ -67,11 +70,11 @@ export class Scope { } /** - * @param {import('estree').Identifier} node - * @param {import('#compiler').Binding['kind']} kind - * @param {import('#compiler').DeclarationKind} declaration_kind - * @param {null | import('estree').Expression | import('estree').FunctionDeclaration | import('estree').ClassDeclaration | import('estree').ImportDeclaration | import('../types/template.js').EachBlock} initial - * @returns {import('#compiler').Binding} + * @param {Identifier} node + * @param {Binding['kind']} kind + * @param {DeclarationKind} declaration_kind + * @param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration | EachBlock} initial + * @returns {Binding} */ declare(node, kind, declaration_kind, initial = null) { if (node.name === '$') { @@ -103,7 +106,7 @@ export class Scope { e.declaration_duplicate(node, node.name); } - /** @type {import('#compiler').Binding} */ + /** @type {Binding} */ const binding = { node, references: [], @@ -157,15 +160,15 @@ export class Scope { /** * @param {string} name - * @returns {import('#compiler').Binding | null} + * @returns {Binding | null} */ get(name) { return this.declarations.get(name) ?? this.parent?.get(name) ?? null; } /** - * @param {import('estree').VariableDeclarator | import('#compiler').LetDirective} node - * @returns {import('#compiler').Binding[]} + * @param {VariableDeclarator | LetDirective} node + * @returns {Binding[]} */ get_bindings(node) { const bindings = this.declarators.get(node); @@ -184,8 +187,8 @@ export class Scope { } /** - * @param {import('estree').Identifier} node - * @param {import('#compiler').SvelteNode[]} path + * @param {Identifier} node + * @param {SvelteNode[]} path */ reference(node, path) { path = [...path]; // ensure that mutations to path afterwards don't affect this reference @@ -231,7 +234,7 @@ export class ScopeRoot { } /** - * @param {import('#compiler').SvelteNode} ast + * @param {SvelteNode} ast * @param {ScopeRoot} root * @param {boolean} allow_reactive_declarations * @param {Scope | null} parent @@ -241,7 +244,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { /** * A map of node->associated scope. A node appearing in this map does not necessarily mean that it created a scope - * @type {Map} + * @type {Map} */ const scopes = new Map(); const scope = new Scope(root, parent, false); @@ -250,21 +253,21 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { /** @type {State} */ const state = { scope }; - /** @type {[Scope, { node: import('estree').Identifier; path: import('#compiler').SvelteNode[] }][]} */ + /** @type {[Scope, { node: Identifier; path: SvelteNode[] }][]} */ const references = []; - /** @type {[Scope, import('estree').Pattern | import('estree').MemberExpression][]} */ + /** @type {[Scope, Pattern | MemberExpression][]} */ const updates = []; /** * An array of reactive declarations, i.e. the `a` in `$: a = b * 2` - * @type {import('estree').Identifier[]} + * @type {Identifier[]} */ const possible_implicit_declarations = []; /** * @param {Scope} scope - * @param {import('estree').Pattern[]} params + * @param {Pattern[]} params */ function add_params(scope, params) { for (const param of params) { @@ -275,7 +278,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { } /** - * @type {import('zimmerframe').Visitor} + * @type {Visitor} */ const create_block_scope = (node, { state, next }) => { const scope = state.scope.child(true); @@ -285,7 +288,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { }; /** - * @type {import('zimmerframe').Visitor} + * @type {Visitor} */ const SvelteFragment = (node, { state, next }) => { const [scope] = analyze_let_directives(node, state.scope); @@ -294,7 +297,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { }; /** - * @param {import('#compiler').ElementLike} node + * @param {ElementLike} node * @param {Scope} parent */ function analyze_let_directives(node, parent) { @@ -303,7 +306,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { for (const attribute of node.attributes) { if (attribute.type === 'LetDirective') { - /** @type {import('#compiler').Binding[]} */ + /** @type {Binding[]} */ const bindings = []; scope.declarators.set(attribute, bindings); @@ -317,7 +320,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { bindings.push(binding); } } else { - /** @type {import('estree').Identifier} */ + /** @type {Identifier} */ const id = { name: attribute.name, type: 'Identifier', @@ -336,7 +339,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { } /** - * @type {import('zimmerframe').Visitor} + * @type {Visitor} */ const SvelteDirective = (node, { state, path, visit }) => { state.scope.reference(b.id(node.name.split('.')[0]), path); @@ -350,7 +353,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { // references Identifier(node, { path, state }) { const parent = path.at(-1); - if (parent && is_reference(node, /** @type {import('estree').Node} */ (parent))) { + if (parent && is_reference(node, /** @type {Node} */ (parent))) { references.push([state.scope, { node, path: path.slice() }]); } }, @@ -432,12 +435,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { }, UpdateExpression(node, { state, next }) { - updates.push([ - state.scope, - /** @type {import('estree').Identifier | import('estree').MemberExpression} */ ( - node.argument - ) - ]); + updates.push([state.scope, /** @type {Identifier | MemberExpression} */ (node.argument)]); next(); }, @@ -489,7 +487,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { VariableDeclaration(node, { state, path, next }) { const is_parent_const_tag = path.at(-1)?.type === 'ConstTag'; for (const declarator of node.declarations) { - /** @type {import('#compiler').Binding[]} */ + /** @type {Binding[]} */ const bindings = []; state.scope.declarators.set(declarator, bindings); @@ -525,7 +523,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { EachBlock(node, { state, visit }) { // Array part is still from the scope above - /** @type {Set} */ + /** @type {Set} */ const references_within = new Set(); const idx = references.length; visit(node.expression); @@ -600,7 +598,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { item: node.context.type === 'Identifier' ? node.context : b.id('$$item'), declarations: scope.declarations, references: [...references_within] - .map((id) => /** @type {import('#compiler').Binding} */ (state.scope.get(id.name))) + .map((id) => /** @type {Binding} */ (state.scope.get(id.name))) .filter(Boolean), is_controlled: false }; @@ -673,9 +671,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { BindDirective(node, context) { updates.push([ context.state.scope, - /** @type {import('estree').Identifier | import('estree').MemberExpression} */ ( - node.expression - ) + /** @type {Identifier | MemberExpression} */ (node.expression) ]); context.next(); }, @@ -718,7 +714,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { object = object.object; } - const binding = scope.get(/** @type {import('estree').Identifier} */ (object).name); + const binding = scope.get(/** @type {Identifier} */ (object).name); if (binding) binding.mutated = true; } else { unwrap_pattern(node).forEach((node) => { @@ -742,15 +738,15 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { /** * @template {{ scope: Scope }} State - * @param {Map} scopes - * @returns {import('zimmerframe').Visitors} + * @param {Map} scopes + * @returns {Visitors} */ export function set_scope(scopes) { return { /** * - * @param {import('#compiler').SvelteNode} node - * @param {import('zimmerframe').Context} context + * @param {SvelteNode} node + * @param {Context} context */ _(node, { next, state }) { const scope = scopes.get(node); @@ -761,7 +757,7 @@ export function set_scope(scopes) { /** * Returns the name of the rune if the given expression is a `CallExpression` using a rune. - * @param {import('estree').Node | import('../types/template.js').EachBlock | null | undefined} node + * @param {Node | EachBlock | null | undefined} node * @param {Scope} scope * @returns {Runes[number] | null} */ diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 62705db8c64b..3b64e6501baf 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -582,7 +582,7 @@ declare module 'svelte/animate' { } declare module 'svelte/compiler' { - import type { AssignmentExpression, ClassDeclaration, Expression, FunctionDeclaration, Identifier, ImportDeclaration, ArrayExpression, MemberExpression, ObjectExpression, Pattern, ArrowFunctionExpression, VariableDeclaration, VariableDeclarator, FunctionExpression, Node, Program, ChainExpression, SimpleCallExpression } from 'estree'; + import type { AssignmentExpression, ClassDeclaration, Expression, FunctionDeclaration, Identifier, ImportDeclaration, ArrayExpression, MemberExpression, ObjectExpression, Pattern, Node, VariableDeclarator, ArrowFunctionExpression, VariableDeclaration, FunctionExpression, Program, ChainExpression, SimpleCallExpression } from 'estree'; import type { SourceMap } from 'magic-string'; import type { Context } from 'zimmerframe'; import type { Location } from 'locate-character'; @@ -1254,13 +1254,13 @@ declare module 'svelte/compiler' { /** * A map of declarators to the bindings they declare * */ - declarators: Map; + declarators: Map; /** * A set of all the names referenced with this scope * — useful for generating unique names * */ references: Map; /** @@ -1269,25 +1269,25 @@ declare module 'svelte/compiler' { */ function_depth: number; - declare(node: import("estree").Identifier, kind: Binding["kind"], declaration_kind: DeclarationKind, initial?: null | import("estree").Expression | import("estree").FunctionDeclaration | import("estree").ClassDeclaration | import("estree").ImportDeclaration | EachBlock): Binding; + declare(node: Identifier, kind: Binding["kind"], declaration_kind: DeclarationKind, initial?: null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration | EachBlock): Binding; child(porous?: boolean): Scope; generate(preferred_name: string): string; get(name: string): Binding | null; - get_bindings(node: import("estree").VariableDeclarator | LetDirective): Binding[]; + get_bindings(node: VariableDeclarator | LetDirective): Binding[]; owner(name: string): Scope | null; - reference(node: import("estree").Identifier, path: SvelteNode[]): void; + reference(node: Identifier, path: SvelteNode[]): void; #private; } class ScopeRoot { conflicts: Set; - unique(preferred_name: string): import("estree").Identifier; + unique(preferred_name: string): Identifier; } namespace Css { export interface BaseNode {