diff --git a/packages/svelte/src/compiler/index.js b/packages/svelte/src/compiler/index.js index 429c6b4a6f..9ba23c1485 100644 --- a/packages/svelte/src/compiler/index.js +++ b/packages/svelte/src/compiler/index.js @@ -20,9 +20,8 @@ export { default as preprocess } from './preprocess/index.js'; */ export function compile(source, options) { source = remove_bom(source); - state.reset_warning_filter(options.warningFilter); + state.reset_warnings(options.warningFilter); const validated = validate_component_options(options, ''); - state.reset(source, validated); let parsed = _parse(source); @@ -64,9 +63,8 @@ export function compile(source, options) { */ export function compileModule(source, options) { source = remove_bom(source); - state.reset_warning_filter(options.warningFilter); + state.reset_warnings(options.warningFilter); const validated = validate_module_options(options, ''); - state.reset(source, validated); const analysis = analyze_module(source, validated); return transform_module(analysis, source, validated); @@ -96,6 +94,7 @@ export function compileModule(source, options) { * @returns {Record} */ +// TODO 6.0 remove unused `filename` /** * The parse function parses a component, returning only its abstract syntax tree. * @@ -104,14 +103,15 @@ export function compileModule(source, options) { * * The `loose` option, available since 5.13.0, tries to always return an AST even if the input will not successfully compile. * + * The `filename` option is unused and will be removed in Svelte 6.0. + * * @param {string} source * @param {{ filename?: string; rootDir?: string; modern?: boolean; loose?: boolean }} [options] * @returns {AST.Root | LegacyRoot} */ -export function parse(source, { filename, rootDir, modern, loose } = {}) { +export function parse(source, { modern, loose } = {}) { source = remove_bom(source); - state.reset_warning_filter(() => false); - state.reset(source, { filename: filename ?? '(unknown)', rootDir }); + state.reset_warnings(() => false); const ast = _parse(source, loose); return to_public_ast(source, ast, modern); diff --git a/packages/svelte/src/compiler/migrate/index.js b/packages/svelte/src/compiler/migrate/index.js index 5ca9adb98b..fdc9734f85 100644 --- a/packages/svelte/src/compiler/migrate/index.js +++ b/packages/svelte/src/compiler/migrate/index.js @@ -9,7 +9,7 @@ import { parse } from '../phases/1-parse/index.js'; import { regex_valid_component_name } from '../phases/1-parse/state/element.js'; import { analyze_component } from '../phases/2-analyze/index.js'; import { get_rune } from '../phases/scope.js'; -import { reset, reset_warning_filter } from '../state.js'; +import { reset, reset_warnings } from '../state.js'; import { extract_identifiers, extract_all_identifiers_from_expression, @@ -134,8 +134,7 @@ export function migrate(source, { filename, use_ts } = {}) { return start + style_placeholder + end; }); - reset_warning_filter(() => false); - reset(source, { filename: filename ?? '(unknown)' }); + reset_warnings(() => false); let parsed = parse(source); diff --git a/packages/svelte/src/compiler/phases/1-parse/index.js b/packages/svelte/src/compiler/phases/1-parse/index.js index b8ae8199eb..77cc2bf3fa 100644 --- a/packages/svelte/src/compiler/phases/1-parse/index.js +++ b/packages/svelte/src/compiler/phases/1-parse/index.js @@ -9,6 +9,7 @@ import { create_fragment } from './utils/create.js'; import read_options from './read/options.js'; import { is_reserved } from '../../../utils.js'; import { disallow_children } from '../2-analyze/visitors/shared/special-element.js'; +import * as state from '../../state.js'; const regex_position_indicator = / \(\d+:\d+\)$/; @@ -301,6 +302,8 @@ export class Parser { * @returns {AST.Root} */ export function parse(template, loose = false) { + state.set_source(template); + const parser = new Parser(template, loose); return parser.root; } diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index be1f1ee5bb..d73e273ec2 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -76,6 +76,7 @@ import { UseDirective } from './visitors/UseDirective.js'; import { VariableDeclarator } from './visitors/VariableDeclarator.js'; import is_reference from 'is-reference'; import { mark_subtree_dynamic } from './visitors/shared/fragment.js'; +import * as state from '../../state.js'; /** * @type {Visitors} @@ -240,6 +241,7 @@ export function analyze_module(source, options) { /** @type {AST.JSComment[]} */ const comments = []; + state.set_source(source); const ast = parse(source, comments, false, false); const { scope, scopes } = create_scopes(ast, new ScopeRoot(), false, null); @@ -269,6 +271,13 @@ export function analyze_module(source, options) { classes: new Map() }; + state.reset({ + dev: options.dev, + filename: options.filename, + rootDir: options.rootDir, + runes: true + }); + walk( /** @type {Node} */ (ast), { @@ -506,6 +515,14 @@ export function analyze_component(root, source, options) { snippets: new Set() }; + state.reset({ + component_name: analysis.name, + dev: options.dev, + filename: options.filename, + rootDir: options.rootDir, + runes: true + }); + if (!runes) { // every exported `let` or `var` declaration becomes a prop, everything else becomes an export for (const node of instance.ast.body) { diff --git a/packages/svelte/src/compiler/phases/types.d.ts b/packages/svelte/src/compiler/phases/types.d.ts index 661f363991..dba2559a17 100644 --- a/packages/svelte/src/compiler/phases/types.d.ts +++ b/packages/svelte/src/compiler/phases/types.d.ts @@ -34,7 +34,9 @@ export interface ReactiveStatement { */ export interface Analysis { module: Js; + /** @deprecated use `component_name` from `state.js` instead */ name: string; // TODO should this be filename? it's used in `compileModule` as well as `compile` + /** @deprecated use `runes` from `state.js` instead */ runes: boolean; immutable: boolean; tracing: boolean; @@ -90,6 +92,7 @@ export interface ComponentAnalysis extends Analysis { keyframes: string[]; has_global: boolean; }; + /** @deprecated use `source` from `state.js` instead */ source: string; undefined_exports: Map; /** diff --git a/packages/svelte/src/compiler/state.js b/packages/svelte/src/compiler/state.js index 1db3db917f..9095651ced 100644 --- a/packages/svelte/src/compiler/state.js +++ b/packages/svelte/src/compiler/state.js @@ -16,6 +16,8 @@ export let warnings = []; */ export let filename; +export let component_name = ''; + /** * The original source code * @type {string} @@ -28,8 +30,16 @@ export let source; */ export let dev; +export let runes = false; + export let locator = getLocator('', { offsetLine: 1 }); +/** @param {string} value */ +export function set_source(value) { + source = value; + locator = getLocator(source, { offsetLine: 1 }); +} + /** * @param {AST.SvelteNode & { start?: number | undefined }} node */ @@ -71,8 +81,9 @@ export function pop_ignore() { * * @param {(warning: Warning) => boolean} fn */ -export function reset_warning_filter(fn = () => true) { +export function reset_warnings(fn = () => true) { warning_filter = fn; + warnings = []; } /** @@ -85,23 +96,27 @@ export function is_ignored(node, code) { } /** - * @param {string} _source - * @param {{ dev?: boolean; filename: string; rootDir?: string }} options + * @param {{ + * dev: boolean; + * filename: string; + * component_name?: string; + * rootDir?: string; + * runes: boolean; + * }} state */ -export function reset(_source, options) { - source = _source; - const root_dir = options.rootDir?.replace(/\\/g, '/'); - filename = options.filename.replace(/\\/g, '/'); +export function reset(state) { + const root_dir = state.rootDir?.replace(/\\/g, '/'); + filename = state.filename.replace(/\\/g, '/'); - dev = !!options.dev; + dev = state.dev; + runes = state.runes; + component_name = state.component_name ?? '(unknown)'; if (typeof root_dir === 'string' && filename.startsWith(root_dir)) { // make filename relative to rootDir filename = filename.replace(root_dir, '').replace(/^[/\\]/, ''); } - locator = getLocator(source, { offsetLine: 1 }); - warnings = []; ignore_stack = []; ignore_map.clear(); }