diff --git a/.changeset/lucky-panthers-chew.md b/.changeset/lucky-panthers-chew.md new file mode 100644 index 0000000000..9bd08df3e6 --- /dev/null +++ b/.changeset/lucky-panthers-chew.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: internal compiler refactoring diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index d797703e92..2a4241a338 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -1,44 +1,171 @@ -/** @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 { Node, Program } from 'estree' */ +/** @import { Root, Script, SvelteNode, ValidatedCompileOptions, ValidatedModuleCompileOptions } from '#compiler' */ +/** @import { AnalysisState, 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'; import * as w from '../../warnings.js'; -import { - extract_identifiers, - extract_all_identifiers_from_expression, - extract_paths, - is_event_attribute, - is_text_attribute, - object, - unwrap_optional, - get_attribute_expression, - get_attribute_chunks -} from '../../utils/ast.js'; +import { is_text_attribute } from '../../utils/ast.js'; import * as b from '../../utils/builders.js'; -import { MathMLElements, ReservedKeywords, Runes, SVGElements } from '../constants.js'; -import { Scope, ScopeRoot, create_scopes, get_rune, set_scope } from '../scope.js'; -import { merge } from '../visitors.js'; -import { validation_legacy, validation_runes, validation_runes_js } from './validation.js'; +import { ReservedKeywords, Runes } from '../constants.js'; +import { Scope, ScopeRoot, create_scopes, get_rune } from '../scope.js'; import check_graph_for_cycles from './utils/check_graph_for_cycles.js'; -import { regex_starts_with_newline } from '../patterns.js'; -import { create_attribute, is_element_node } from '../nodes.js'; -import { - DelegatedEvents, - is_capture_event, - namespace_mathml, - namespace_svg -} from '../../../constants.js'; -import { should_proxy_or_freeze } from '../3-transform/client/utils.js'; +import { create_attribute } from '../nodes.js'; import { analyze_css } from './css/css-analyze.js'; import { prune } from './css/css-prune.js'; import { hash } from '../../../utils.js'; import { warn_unused } from './css/css-warn.js'; import { extract_svelte_ignore } from '../../utils/extract_svelte_ignore.js'; import { ignore_map, ignore_stack, pop_ignore, push_ignore } from '../../state.js'; -import { equal } from '../../utils/assert.js'; +import { ArrowFunctionExpression } from './visitors/ArrowFunctionExpression.js'; +import { AssignmentExpression } from './visitors/AssignmentExpression.js'; +import { Attribute } from './visitors/Attribute.js'; +import { AwaitBlock } from './visitors/AwaitBlock.js'; +import { BindDirective } from './visitors/BindDirective.js'; +import { CallExpression } from './visitors/CallExpression.js'; +import { ClassBody } from './visitors/ClassBody.js'; +import { ClassDeclaration } from './visitors/ClassDeclaration.js'; +import { ClassDirective } from './visitors/ClassDirective.js'; +import { Component } from './visitors/Component.js'; +import { ConstTag } from './visitors/ConstTag.js'; +import { DebugTag } from './visitors/DebugTag.js'; +import { EachBlock } from './visitors/EachBlock.js'; +import { ExportDefaultDeclaration } from './visitors/ExportDefaultDeclaration.js'; +import { ExportNamedDeclaration } from './visitors/ExportNamedDeclaration.js'; +import { ExportSpecifier } from './visitors/ExportSpecifier.js'; +import { ExpressionStatement } from './visitors/ExpressionStatement.js'; +import { ExpressionTag } from './visitors/ExpressionTag.js'; +import { FunctionDeclaration } from './visitors/FunctionDeclaration.js'; +import { FunctionExpression } from './visitors/FunctionExpression.js'; +import { HtmlTag } from './visitors/HtmlTag.js'; +import { Identifier } from './visitors/Identifier.js'; +import { IfBlock } from './visitors/IfBlock.js'; +import { ImportDeclaration } from './visitors/ImportDeclaration.js'; +import { KeyBlock } from './visitors/KeyBlock.js'; +import { LabeledStatement } from './visitors/LabeledStatement.js'; +import { LetDirective } from './visitors/LetDirective.js'; +import { MemberExpression } from './visitors/MemberExpression.js'; +import { NewExpression } from './visitors/NewExpression.js'; +import { OnDirective } from './visitors/OnDirective.js'; +import { RegularElement } from './visitors/RegularElement.js'; +import { RenderTag } from './visitors/RenderTag.js'; +import { SlotElement } from './visitors/SlotElement.js'; +import { SnippetBlock } from './visitors/SnippetBlock.js'; +import { SpreadAttribute } from './visitors/SpreadAttribute.js'; +import { StyleDirective } from './visitors/StyleDirective.js'; +import { SvelteComponent } from './visitors/SvelteComponent.js'; +import { SvelteElement } from './visitors/SvelteElement.js'; +import { SvelteFragment } from './visitors/SvelteFragment.js'; +import { SvelteHead } from './visitors/SvelteHead.js'; +import { SvelteSelf } from './visitors/SvelteSelf.js'; +import { Text } from './visitors/Text.js'; +import { TitleElement } from './visitors/TitleElement.js'; +import { UpdateExpression } from './visitors/UpdateExpression.js'; +import { VariableDeclarator } from './visitors/VariableDeclarator.js'; + +/** + * @type {Visitors} + */ +const visitors = { + _(node, { state, next, path }) { + const parent = path.at(-1); + + /** @type {string[]} */ + const ignores = []; + + if (parent?.type === 'Fragment' && node.type !== 'Comment' && node.type !== 'Text') { + const idx = parent.nodes.indexOf(/** @type {any} */ (node)); + + for (let i = idx - 1; i >= 0; i--) { + const prev = parent.nodes[i]; + + if (prev.type === 'Comment') { + ignores.push( + ...extract_svelte_ignore( + prev.start + 4 /* '