chore: more JSDoc (#12588)

pull/12594/head
Rich Harris 1 year ago committed by GitHub
parent abaa4413df
commit 6037b961c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,3 +1,5 @@
/** @import { Comment, Program } from 'estree' */
/** @import { Node } from 'acorn' */
import * as acorn from 'acorn';
import { walk } from 'zimmerframe';
import { tsPlugin } from 'acorn-typescript';
@ -23,7 +25,7 @@ export function parse(source, typescript) {
if (typescript) amend(source, ast);
add_comments(ast);
return /** @type {import('estree').Program} */ (ast);
return /** @type {Program} */ (ast);
}
/**
@ -57,7 +59,7 @@ export function parse_expression_at(source, typescript, index) {
*/
function get_comment_handlers(source) {
/**
* @typedef {import('estree').Comment & {
* @typedef {Comment & {
* start: number;
* end: number;
* }} CommentWithLocation
@ -149,7 +151,7 @@ function get_comment_handlers(source) {
/**
* Tidy up some stuff left behind by acorn-typescript
* @param {string} source
* @param {import('acorn').Node} node
* @param {Node} node
*/
function amend(source, node) {
return walk(node, null, {

@ -1,10 +1,12 @@
/** @import { Expression } from 'estree' */
/** @import { Parser } from '../index.js' */
import { parse_expression_at } from '../acorn.js';
import { regex_whitespace } from '../../patterns.js';
import * as e from '../../../errors.js';
/**
* @param {import('../index.js').Parser} parser
* @returns {import('estree').Expression}
* @param {Parser} parser
* @returns {Expression}
*/
export default function read_expression(parser) {
try {
@ -35,7 +37,7 @@ export default function read_expression(parser) {
parser.index = index;
return /** @type {import('estree').Expression} */ (node);
return /** @type {Expression} */ (node);
} catch (err) {
parser.acorn_error(err);
}

@ -1,5 +1,6 @@
/** @import { Parser } from '../index.js' */
/** @import { Expression } from 'estree' */
/** @import * as Compiler from '#compiler' */
/** @import { Parser } from '../index.js' */
import { is_void } from '../../../../constants.js';
import read_expression from '../read/expression.js';
import { read_script } from '../read/script.js';
@ -589,7 +590,7 @@ function read_attribute(parser) {
const first_value = value === true ? undefined : Array.isArray(value) ? value[0] : value;
/** @type {import('estree').Expression | null} */
/** @type {Expression | null} */
let expression = null;
if (first_value) {

@ -1,3 +1,6 @@
/** @import { ArrowFunctionExpression, Expression, Identifier } from 'estree' */
/** @import { AwaitBlock, ConstTag, DebugTag, EachBlock, ExpressionTag, HtmlTag, IfBlock, KeyBlock, RenderTag, SnippetBlock } from '#compiler' */
/** @import { Parser } from '../index.js' */
import read_pattern from '../read/context.js';
import read_expression from '../read/expression.js';
import * as e from '../../../errors.js';
@ -7,7 +10,7 @@ import { parse_expression_at } from '../acorn.js';
const regex_whitespace_with_closing_curly_brace = /^\s*}/;
/** @param {import('../index.js').Parser} parser */
/** @param {Parser} parser */
export default function tag(parser) {
const start = parser.index;
parser.index += 1;
@ -29,7 +32,7 @@ export default function tag(parser) {
parser.allow_whitespace();
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').ExpressionTag>>} */
/** @type {ReturnType<typeof parser.append<ExpressionTag>>} */
parser.append({
type: 'ExpressionTag',
start,
@ -42,7 +45,7 @@ export default function tag(parser) {
});
}
/** @param {import('../index.js').Parser} parser */
/** @param {Parser} parser */
function open(parser) {
let start = parser.index - 2;
while (parser.template[start] !== '{') start -= 1;
@ -50,7 +53,7 @@ function open(parser) {
if (parser.eat('if')) {
parser.require_whitespace();
/** @type {ReturnType<typeof parser.append<import('#compiler').IfBlock>>} */
/** @type {ReturnType<typeof parser.append<IfBlock>>} */
const block = parser.append({
type: 'IfBlock',
elseif: false,
@ -76,7 +79,7 @@ function open(parser) {
const template = parser.template;
let end = parser.template.length;
/** @type {import('estree').Expression | undefined} */
/** @type {Expression | undefined} */
let expression;
// we have to do this loop because `{#each x as { y = z }}` fails to parse —
@ -119,7 +122,7 @@ function open(parser) {
expression = walk(expression, null, {
// @ts-expect-error
TSAsExpression(node, context) {
if (node.end === /** @type {import('estree').Expression} */ (expression).end) {
if (node.end === /** @type {Expression} */ (expression).end) {
assertion = node;
end = node.expression.end;
return node.expression;
@ -171,7 +174,7 @@ function open(parser) {
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').EachBlock>>} */
/** @type {ReturnType<typeof parser.append<EachBlock>>} */
const block = parser.append({
type: 'EachBlock',
start,
@ -195,7 +198,7 @@ function open(parser) {
const expression = read_expression(parser);
parser.allow_whitespace();
/** @type {ReturnType<typeof parser.append<import('#compiler').AwaitBlock>>} */
/** @type {ReturnType<typeof parser.append<AwaitBlock>>} */
const block = parser.append({
type: 'AwaitBlock',
start,
@ -249,7 +252,7 @@ function open(parser) {
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').KeyBlock>>} */
/** @type {ReturnType<typeof parser.append<KeyBlock>>} */
const block = parser.append({
type: 'KeyBlock',
start,
@ -293,14 +296,14 @@ function open(parser) {
const prelude = parser.template.slice(0, params_start).replace(/\S/g, ' ');
const params = parser.template.slice(params_start, parser.index);
let function_expression = /** @type {import('estree').ArrowFunctionExpression} */ (
let function_expression = /** @type {ArrowFunctionExpression} */ (
parse_expression_at(prelude + `${params} => {}`, parser.ts, params_start)
);
parser.allow_whitespace();
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').SnippetBlock>>} */
/** @type {ReturnType<typeof parser.append<SnippetBlock>>} */
const block = parser.append({
type: 'SnippetBlock',
start,
@ -323,7 +326,7 @@ function open(parser) {
e.expected_block_type(parser.index);
}
/** @param {import('../index.js').Parser} parser */
/** @param {Parser} parser */
function next(parser) {
const start = parser.index - 1;
@ -352,7 +355,7 @@ function next(parser) {
let elseif_start = start - 1;
while (parser.template[elseif_start] !== '{') elseif_start -= 1;
/** @type {ReturnType<typeof parser.append<import('#compiler').IfBlock>>} */
/** @type {ReturnType<typeof parser.append<IfBlock>>} */
const child = parser.append({
start: elseif_start,
end: -1,
@ -434,7 +437,7 @@ function next(parser) {
e.block_invalid_continuation_placement(start);
}
/** @param {import('../index.js').Parser} parser */
/** @param {Parser} parser */
function close(parser) {
const start = parser.index - 1;
@ -448,7 +451,7 @@ function close(parser) {
while (block.elseif) {
block.end = parser.index;
parser.stack.pop();
block = /** @type {import('#compiler').IfBlock} */ (parser.current());
block = /** @type {IfBlock} */ (parser.current());
}
block.end = parser.index;
parser.pop();
@ -482,7 +485,7 @@ function close(parser) {
parser.pop();
}
/** @param {import('../index.js').Parser} parser */
/** @param {Parser} parser */
function special(parser) {
let start = parser.index;
while (parser.template[start] !== '{') start -= 1;
@ -496,7 +499,7 @@ function special(parser) {
parser.allow_whitespace();
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').HtmlTag>>} */
/** @type {ReturnType<typeof parser.append<HtmlTag>>} */
parser.append({
type: 'HtmlTag',
start,
@ -508,7 +511,7 @@ function special(parser) {
}
if (parser.eat('debug')) {
/** @type {import('estree').Identifier[]} */
/** @type {Identifier[]} */
let identifiers;
// Implies {@debug} which indicates "debug all"
@ -519,8 +522,8 @@ function special(parser) {
identifiers =
expression.type === 'SequenceExpression'
? /** @type {import('estree').Identifier[]} */ (expression.expressions)
: [/** @type {import('estree').Identifier} */ (expression)];
? /** @type {Identifier[]} */ (expression.expressions)
: [/** @type {Identifier} */ (expression)];
identifiers.forEach(
/** @param {any} node */ (node) => {
@ -534,7 +537,7 @@ function special(parser) {
parser.eat('}', true);
}
/** @type {ReturnType<typeof parser.append<import('#compiler').DebugTag>>} */
/** @type {ReturnType<typeof parser.append<DebugTag>>} */
parser.append({
type: 'DebugTag',
start,
@ -567,7 +570,7 @@ function special(parser) {
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').ConstTag>>} */
/** @type {ReturnType<typeof parser.append<ConstTag>>} */
parser.append({
type: 'ConstTag',
start,
@ -598,7 +601,7 @@ function special(parser) {
parser.allow_whitespace();
parser.eat('}', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').RenderTag>>} */
/** @type {ReturnType<typeof parser.append<RenderTag>>} */
parser.append({
type: 'RenderTag',
start,

@ -1,3 +1,7 @@
/** @import { ArrowFunctionExpression, CallExpression, Expression, FunctionDeclaration, FunctionExpression, Identifier, LabeledStatement, Literal, Node, Program, Super } from 'estree' */
/** @import { Attribute, BindDirective, Binding, DelegatedEvent, RegularElement, Root, Script, SvelteNode, Text, ValidatedCompileOptions, ValidatedModuleCompileOptions } from '#compiler' */
/** @import { AnalysisState, Context, LegacyAnalysisState, Visitors } from './types' */
/** @import { Analysis, ComponentAnalysis, Js, ReactiveStatement, Template } from '../types' */
import is_reference from 'is-reference';
import { walk } from 'zimmerframe';
import * as e from '../../errors.js';
@ -37,14 +41,14 @@ import { ignore_map, ignore_stack, pop_ignore, push_ignore } from '../../state.j
import { equal } from '../../utils/assert.js';
/**
* @param {import('#compiler').Script | null} script
* @param {Script | null} script
* @param {ScopeRoot} root
* @param {boolean} allow_reactive_declarations
* @param {Scope | null} parent
* @returns {import('../types.js').Js}
* @returns {Js}
*/
function js(script, root, allow_reactive_declarations, parent) {
/** @type {import('estree').Program} */
/** @type {Program} */
const ast = script?.content ?? {
type: 'Program',
sourceType: 'module',
@ -75,9 +79,9 @@ function get_component_name(filename) {
/**
* Checks if given event attribute can be delegated/hoisted and returns the corresponding info if so
* @param {string} event_name
* @param {import('estree').Expression | null} handler
* @param {import('./types').Context} context
* @returns {null | import('#compiler').DelegatedEvent}
* @param {Expression | null} handler
* @param {Context} context
* @returns {null | DelegatedEvent}
*/
function get_delegated_event(event_name, handler, context) {
// Handle delegated event handlers. Bail-out if not a delegated event.
@ -91,9 +95,9 @@ function get_delegated_event(event_name, handler, context) {
return null;
}
/** @type {import('#compiler').DelegatedEvent} */
/** @type {DelegatedEvent} */
const non_hoistable = { type: 'non-hoistable' };
/** @type {import('estree').FunctionExpression | import('estree').FunctionDeclaration | import('estree').ArrowFunctionExpression | null} */
/** @type {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression | null} */
let target_function = null;
let binding = null;
@ -119,20 +123,20 @@ function get_delegated_event(event_name, handler, context) {
const grandparent = path.at(-2);
/** @type {import('#compiler').RegularElement | null} */
/** @type {RegularElement | null} */
let element = null;
/** @type {string | null} */
let event_name = null;
if (parent.type === 'OnDirective') {
element = /** @type {import('#compiler').RegularElement} */ (grandparent);
element = /** @type {RegularElement} */ (grandparent);
event_name = parent.name;
} else if (
parent.type === 'ExpressionTag' &&
grandparent?.type === 'Attribute' &&
is_event_attribute(grandparent)
) {
element = /** @type {import('#compiler').RegularElement} */ (path.at(-3));
const attribute = /** @type {import('#compiler').Attribute} */ (grandparent);
element = /** @type {RegularElement} */ (path.at(-3));
const attribute = /** @type {Attribute} */ (grandparent);
event_name = get_attribute_event_name(attribute.name);
}
@ -224,9 +228,9 @@ function get_delegated_event(event_name, handler, context) {
}
/**
* @param {import('estree').Program} ast
* @param {import('#compiler').ValidatedModuleCompileOptions} options
* @returns {import('../types.js').Analysis}
* @param {Program} ast
* @param {ValidatedModuleCompileOptions} options
* @returns {Analysis}
*/
export function analyze_module(ast, options) {
const { scope, scopes } = create_scopes(ast, new ScopeRoot(), false, null);
@ -239,7 +243,7 @@ export function analyze_module(ast, options) {
}
walk(
/** @type {import('estree').Node} */ (ast),
/** @type {Node} */ (ast),
{ scope, analysis: { runes: true } },
// @ts-expect-error TODO clean this mess up
merge(set_scope(scopes), validation_runes_js, runes_scope_js_tweaker)
@ -255,10 +259,10 @@ export function analyze_module(ast, options) {
}
/**
* @param {import('#compiler').Root} root
* @param {Root} root
* @param {string} source
* @param {import('#compiler').ValidatedCompileOptions} options
* @returns {import('../types.js').ComponentAnalysis}
* @param {ValidatedCompileOptions} options
* @returns {ComponentAnalysis}
*/
export function analyze_component(root, source, options) {
const scope_root = new ScopeRoot();
@ -268,7 +272,7 @@ export function analyze_component(root, source, options) {
const { scope, scopes } = create_scopes(root.fragment, scope_root, false, instance.scope);
/** @type {import('../types.js').Template} */
/** @type {Template} */
const template = { ast: root.fragment, scope, scopes };
// create synthetic bindings for store subscriptions
@ -339,7 +343,7 @@ export function analyze_component(root, source, options) {
/** @type {number} */ (node.start) > /** @type {number} */ (module.ast.start) &&
/** @type {number} */ (node.end) < /** @type {number} */ (module.ast.end) &&
// const state = $state(0) is valid
get_rune(/** @type {import('estree').Node} */ (path.at(-1)), module.scope) === null
get_rune(/** @type {Node} */ (path.at(-1)), module.scope) === null
) {
e.store_invalid_subscription(node);
}
@ -360,7 +364,7 @@ export function analyze_component(root, source, options) {
Array.from(module.scope.references).some(([name]) => Runes.includes(/** @type {any} */ (name)));
// TODO remove all the ?? stuff, we don't need it now that we're validating the config
/** @type {import('../types.js').ComponentAnalysis} */
/** @type {ComponentAnalysis} */
const analysis = {
name: module.scope.generate(options.name ?? component_name),
root: scope_root,
@ -434,7 +438,7 @@ export function analyze_component(root, source, options) {
}
for (const { ast, scope, scopes } of [module, instance, template]) {
/** @type {import('./types').AnalysisState} */
/** @type {AnalysisState} */
const state = {
scope,
analysis,
@ -450,7 +454,7 @@ export function analyze_component(root, source, options) {
};
walk(
/** @type {import('#compiler').SvelteNode} */ (ast),
/** @type {SvelteNode} */ (ast),
state,
merge(set_scope(scopes), validation_runes, runes_scope_tweaker, common_visitors)
);
@ -474,7 +478,7 @@ export function analyze_component(root, source, options) {
// bind:this doesn't need to be a state reference if it will never change
if (
type === 'BindDirective' &&
/** @type {import('#compiler').BindDirective} */ (path[i]).name === 'this'
/** @type {BindDirective} */ (path[i]).name === 'this'
) {
for (let j = i - 1; j >= 0; j -= 1) {
const type = path[j].type;
@ -503,7 +507,7 @@ export function analyze_component(root, source, options) {
instance.scope.declare(b.id('$$restProps'), 'rest_prop', 'synthetic');
for (const { ast, scope, scopes } of [module, instance, template]) {
/** @type {import('./types').LegacyAnalysisState} */
/** @type {LegacyAnalysisState} */
const state = {
scope,
analysis,
@ -522,7 +526,7 @@ export function analyze_component(root, source, options) {
};
walk(
/** @type {import('#compiler').SvelteNode} */ (ast),
/** @type {SvelteNode} */ (ast),
state,
// @ts-expect-error TODO
merge(set_scope(scopes), validation_legacy, legacy_scope_tweaker, common_visitors)
@ -583,7 +587,7 @@ export function analyze_component(root, source, options) {
// TODO this happens during the analysis phase, which shouldn't know anything about client vs server
if (element.type === 'SvelteElement' && options.generate === 'client') continue;
/** @type {import('#compiler').Attribute | undefined} */
/** @type {Attribute | undefined} */
let class_attribute = undefined;
for (const attribute of element.attributes) {
@ -602,7 +606,7 @@ export function analyze_component(root, source, options) {
if (is_text_attribute(class_attribute)) {
class_attribute.value[0].data += ` ${analysis.css.hash}`;
} else {
/** @type {import('#compiler').Text} */
/** @type {Text} */
const css_text = {
type: 'Text',
data: ` ${analysis.css.hash}`,
@ -642,19 +646,19 @@ export function analyze_component(root, source, options) {
return analysis;
}
/** @type {import('./types').Visitors<import('./types').LegacyAnalysisState>} */
/** @type {Visitors<LegacyAnalysisState>} */
const legacy_scope_tweaker = {
LabeledStatement(node, { next, path, state }) {
if (
state.ast_type !== 'instance' ||
node.label.name !== '$' ||
/** @type {import('#compiler').SvelteNode} */ (path.at(-1)).type !== 'Program'
/** @type {SvelteNode} */ (path.at(-1)).type !== 'Program'
) {
return next();
}
// Find all dependencies of this `$: {...}` statement
/** @type {import('../types.js').ReactiveStatement} */
/** @type {ReactiveStatement} */
const reactive_statement = {
assignments: new Set(),
dependencies: []
@ -669,14 +673,14 @@ const legacy_scope_tweaker = {
if (binding === null) continue;
for (const { node, path } of nodes) {
/** @type {import('estree').Expression} */
/** @type {Expression} */
let left = node;
let i = path.length - 1;
let parent = /** @type {import('estree').Expression} */ (path.at(i));
let parent = /** @type {Expression} */ (path.at(i));
while (parent.type === 'MemberExpression') {
left = parent;
parent = /** @type {import('estree').Expression} */ (path.at(--i));
parent = /** @type {Expression} */ (path.at(--i));
}
if (
@ -757,7 +761,7 @@ const legacy_scope_tweaker = {
next();
},
Identifier(node, { state, path }) {
const parent = /** @type {import('estree').Node} */ (path.at(-1));
const parent = /** @type {Node} */ (path.at(-1));
if (is_reference(node, parent)) {
if (node.name === '$$props') {
state.analysis.uses_props = true;
@ -834,9 +838,7 @@ const legacy_scope_tweaker = {
if (!node.declaration) {
for (const specifier of node.specifiers) {
const binding = /** @type {import('#compiler').Binding} */ (
state.scope.get(specifier.local.name)
);
const binding = /** @type {Binding} */ (state.scope.get(specifier.local.name));
if (
binding !== null &&
(binding.kind === 'state' ||
@ -863,7 +865,7 @@ const legacy_scope_tweaker = {
node.declaration.type === 'ClassDeclaration'
) {
state.analysis.exports.push({
name: /** @type {import('estree').Identifier} */ (node.declaration.id).name,
name: /** @type {Identifier} */ (node.declaration.id).name,
alias: null
});
return next();
@ -881,7 +883,7 @@ const legacy_scope_tweaker = {
for (const declarator of node.declaration.declarations) {
for (const id of extract_identifiers(declarator.id)) {
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(id.name));
const binding = /** @type {Binding} */ (state.scope.get(id.name));
binding.kind = 'bindable_prop';
}
}
@ -899,7 +901,7 @@ const legacy_scope_tweaker = {
}
};
/** @type {import('zimmerframe').Visitors<import('#compiler').SvelteNode, { scope: Scope, analysis: { runes: true } }>} */
/** @type {import('zimmerframe').Visitors<SvelteNode, { scope: Scope, analysis: { runes: true } }>} */
const runes_scope_js_tweaker = {
VariableDeclarator(node, { state }) {
if (node.init?.type !== 'CallExpression') return;
@ -919,14 +921,14 @@ const runes_scope_js_tweaker = {
for (const path of extract_paths(node.id)) {
// @ts-ignore this fails in CI for some insane reason
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(path.node.name));
const binding = /** @type {Binding} */ (state.scope.get(path.node.name));
binding.kind =
rune === '$state' ? 'state' : rune === '$state.frozen' ? 'frozen_state' : 'derived';
}
}
};
/** @type {import('./types').Visitors} */
/** @type {Visitors} */
const runes_scope_tweaker = {
CallExpression(node, { state, next }) {
const rune = get_rune(node, state.scope);
@ -956,7 +958,7 @@ const runes_scope_tweaker = {
for (const path of extract_paths(node.id)) {
// @ts-ignore this fails in CI for some insane reason
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(path.node.name));
const binding = /** @type {Binding} */ (state.scope.get(path.node.name));
binding.kind =
rune === '$state'
? 'state'
@ -973,7 +975,7 @@ const runes_scope_tweaker = {
state.analysis.needs_props = true;
if (node.id.type === 'Identifier') {
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(node.id.name));
const binding = /** @type {Binding} */ (state.scope.get(node.id.name));
binding.initial = null; // else would be $props()
binding.kind = 'rest_prop';
} else {
@ -984,15 +986,15 @@ const runes_scope_tweaker = {
const name =
property.value.type === 'AssignmentPattern'
? /** @type {import('estree').Identifier} */ (property.value.left).name
: /** @type {import('estree').Identifier} */ (property.value).name;
? /** @type {Identifier} */ (property.value.left).name
: /** @type {Identifier} */ (property.value).name;
const alias =
property.key.type === 'Identifier'
? property.key.name
: String(/** @type {import('estree').Literal} */ (property.key).value);
: String(/** @type {Literal} */ (property.key).value);
let initial = property.value.type === 'AssignmentPattern' ? property.value.right : null;
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(name));
const binding = /** @type {Binding} */ (state.scope.get(name));
binding.prop_alias = alias;
// rewire initial from $props() to the actual initial value, stripping $bindable() if necessary
@ -1001,9 +1003,7 @@ const runes_scope_tweaker = {
initial.callee.type === 'Identifier' &&
initial.callee.name === '$bindable'
) {
binding.initial = /** @type {import('estree').Expression | null} */ (
initial.arguments[0] ?? null
);
binding.initial = /** @type {Expression | null} */ (initial.arguments[0] ?? null);
binding.kind = 'bindable_prop';
} else {
binding.initial = initial;
@ -1033,7 +1033,7 @@ const runes_scope_tweaker = {
node.declaration.type === 'ClassDeclaration'
) {
state.analysis.exports.push({
name: /** @type {import('estree').Identifier} */ (node.declaration.id).name,
name: /** @type {Identifier} */ (node.declaration.id).name,
alias: null
});
return next();
@ -1050,8 +1050,8 @@ const runes_scope_tweaker = {
};
/**
* @param {import('estree').CallExpression} node
* @param {import('./types').Context} context
* @param {CallExpression} node
* @param {Context} context
* @returns {boolean}
*/
function is_known_safe_call(node, context) {
@ -1075,8 +1075,8 @@ function is_known_safe_call(node, context) {
}
/**
* @param {import('estree').ArrowFunctionExpression | import('estree').FunctionExpression | import('estree').FunctionDeclaration} node
* @param {import('./types').Context} context
* @param {ArrowFunctionExpression | FunctionExpression | FunctionDeclaration} node
* @param {Context} context
*/
const function_visitor = (node, context) => {
// TODO retire this in favour of a more general solution based on bindings
@ -1096,7 +1096,7 @@ const function_visitor = (node, context) => {
/**
* A 'safe' identifier means that the `foo` in `foo.bar` or `foo()` will not
* call functions that require component context to exist
* @param {import('estree').Expression | import('estree').Super} expression
* @param {Expression | Super} expression
* @param {Scope} scope
*/
function is_safe_identifier(expression, scope) {
@ -1120,7 +1120,7 @@ function is_safe_identifier(expression, scope) {
);
}
/** @type {import('./types').Visitors} */
/** @type {Visitors} */
const common_visitors = {
_(node, { state, next, path }) {
ignore_map.set(node, structuredClone(ignore_stack));
@ -1243,7 +1243,7 @@ const common_visitors = {
context.next({ ...context.state, expression: node });
},
Identifier(node, context) {
const parent = /** @type {import('estree').Node} */ (context.path.at(-1));
const parent = /** @type {Node} */ (context.path.at(-1));
if (!is_reference(node, parent)) return;
if (node.name === '$$slots') {
@ -1270,8 +1270,7 @@ const common_visitors = {
// TODO it would be better to just bail out when we hit the ExportSpecifier node but that's
// not currently possibly because of our visitor merging, which I desperately want to nuke
const is_export_specifier =
/** @type {import('#compiler').SvelteNode} */ (context.path.at(-1)).type ===
'ExportSpecifier';
/** @type {SvelteNode} */ (context.path.at(-1)).type === 'ExportSpecifier';
if (
context.state.analysis.runes &&
@ -1472,8 +1471,8 @@ const common_visitors = {
node.attributes.push(
create_attribute(
'value',
/** @type {import('#compiler').Text} */ (node.fragment.nodes.at(0)).start,
/** @type {import('#compiler').Text} */ (node.fragment.nodes.at(-1)).end,
/** @type {Text} */ (node.fragment.nodes.at(0)).start,
/** @type {Text} */ (node.fragment.nodes.at(-1)).end,
// @ts-ignore
node.fragment.nodes
)
@ -1552,7 +1551,7 @@ const common_visitors = {
};
/**
* @param {import('#compiler').RegularElement} node
* @param {RegularElement} node
*/
function determine_element_spread(node) {
let has_spread = false;
@ -1578,10 +1577,10 @@ function get_attribute_event_name(event_name) {
}
/**
* @param {Map<import('estree').LabeledStatement, import('../types.js').ReactiveStatement>} unsorted_reactive_declarations
* @param {Map<LabeledStatement, ReactiveStatement>} unsorted_reactive_declarations
*/
function order_reactive_statements(unsorted_reactive_declarations) {
/** @typedef {[import('estree').LabeledStatement, import('../types.js').ReactiveStatement]} Tuple */
/** @typedef {[LabeledStatement, ReactiveStatement]} Tuple */
/** @type {Map<string, Array<Tuple>>} */
const lookup = new Map();
@ -1614,13 +1613,13 @@ function order_reactive_statements(unsorted_reactive_declarations) {
}
// We use a map and take advantage of the fact that the spec says insertion order is preserved when iterating
/** @type {Map<import('estree').LabeledStatement, import('../types.js').ReactiveStatement>} */
/** @type {Map<LabeledStatement, ReactiveStatement>} */
const reactive_declarations = new Map();
/**
*
* @param {import('estree').LabeledStatement} node
* @param {import('../types.js').ReactiveStatement} declaration
* @param {LabeledStatement} node
* @param {ReactiveStatement} declaration
* @returns
*/
const add_declaration = (node, declaration) => {

Loading…
Cancel
Save