init
This commit is contained in:
+198
@@ -0,0 +1,198 @@
|
||||
/** @import { LegacyRoot } from './types/legacy-nodes.js' */
|
||||
/** @import { CompileOptions, CompileResult, ValidatedCompileOptions, ModuleCompileOptions } from '#compiler' */
|
||||
/** @import { AST } from './public.js' */
|
||||
import { walk as zimmerframe_walk } from 'zimmerframe';
|
||||
import { convert } from './legacy.js';
|
||||
import { parse as _parse, Parser } from './phases/1-parse/index.js';
|
||||
import { remove_typescript_nodes } from './phases/1-parse/remove_typescript_nodes.js';
|
||||
import { parse_stylesheet } from './phases/1-parse/read/style.js';
|
||||
import { analyze_component, analyze_module } from './phases/2-analyze/index.js';
|
||||
import { transform_component, transform_module } from './phases/3-transform/index.js';
|
||||
import { validate_component_options, validate_module_options } from './validate-options.js';
|
||||
import * as state from './state.js';
|
||||
export { default as preprocess } from './preprocess/index.js';
|
||||
export { print } from './print/index.js';
|
||||
|
||||
/**
|
||||
* `compile` converts your `.svelte` source code into a JavaScript module that exports a component
|
||||
*
|
||||
* @param {string} source The component source code
|
||||
* @param {CompileOptions} options The compiler options
|
||||
* @returns {CompileResult}
|
||||
*/
|
||||
export function compile(source, options) {
|
||||
source = remove_bom(source);
|
||||
state.reset({ warning: options.warningFilter, filename: options.filename });
|
||||
const validated = validate_component_options(options, '');
|
||||
|
||||
let parsed = _parse(source);
|
||||
|
||||
const { customElement: customElementOptions, ...parsed_options } = parsed.options || {};
|
||||
|
||||
/** @type {ValidatedCompileOptions} */
|
||||
const combined_options = {
|
||||
...validated,
|
||||
...parsed_options,
|
||||
customElementOptions
|
||||
};
|
||||
|
||||
if (parsed.metadata.ts) {
|
||||
parsed = {
|
||||
...parsed,
|
||||
fragment: parsed.fragment && remove_typescript_nodes(parsed.fragment),
|
||||
instance: parsed.instance && remove_typescript_nodes(parsed.instance),
|
||||
module: parsed.module && remove_typescript_nodes(parsed.module)
|
||||
};
|
||||
if (combined_options.customElementOptions?.extend) {
|
||||
combined_options.customElementOptions.extend = remove_typescript_nodes(
|
||||
combined_options.customElementOptions?.extend
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const analysis = analyze_component(parsed, source, combined_options);
|
||||
const result = transform_component(analysis, source, combined_options);
|
||||
result.ast = to_public_ast(source, parsed, options.modernAst);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* `compileModule` takes your JavaScript source code containing runes, and turns it into a JavaScript module.
|
||||
*
|
||||
* @param {string} source The component source code
|
||||
* @param {ModuleCompileOptions} options
|
||||
* @returns {CompileResult}
|
||||
*/
|
||||
export function compileModule(source, options) {
|
||||
source = remove_bom(source);
|
||||
state.reset({ warning: options.warningFilter, filename: options.filename });
|
||||
const validated = validate_module_options(options, '');
|
||||
|
||||
const analysis = analyze_module(source, validated);
|
||||
return transform_module(analysis, source, validated);
|
||||
}
|
||||
|
||||
/**
|
||||
* The parse function parses a component, returning only its abstract syntax tree.
|
||||
*
|
||||
* The `modern` option (`false` by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.
|
||||
* `modern` will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
|
||||
*
|
||||
* @overload
|
||||
* @param {string} source
|
||||
* @param {{ filename?: string; modern: true; loose?: boolean }} options
|
||||
* @returns {AST.Root}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The parse function parses a component, returning only its abstract syntax tree.
|
||||
*
|
||||
* The `modern` option (`false` by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.
|
||||
* `modern` will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
|
||||
*
|
||||
* @overload
|
||||
* @param {string} source
|
||||
* @param {{ filename?: string; modern?: false; loose?: boolean }} [options]
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
|
||||
// TODO 6.0 remove unused `filename`
|
||||
/**
|
||||
* The parse function parses a component, returning only its abstract syntax tree.
|
||||
*
|
||||
* The `modern` option (`false` by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.
|
||||
* `modern` will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
|
||||
*
|
||||
* 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, { modern, loose } = {}) {
|
||||
source = remove_bom(source);
|
||||
state.reset({ warning: () => false, filename: undefined });
|
||||
|
||||
const ast = _parse(source, loose);
|
||||
return to_public_ast(source, ast, modern);
|
||||
}
|
||||
|
||||
/**
|
||||
* The parseCss function parses a CSS stylesheet, returning its abstract syntax tree.
|
||||
*
|
||||
* @param {string} source The CSS source code
|
||||
* @returns {Omit<AST.CSS.StyleSheet, 'attributes' | 'content'>}
|
||||
*/
|
||||
export function parseCss(source) {
|
||||
source = remove_bom(source);
|
||||
state.reset({ warning: () => false, filename: undefined });
|
||||
|
||||
state.set_source(source);
|
||||
|
||||
const parser = Parser.forCss(source);
|
||||
const children = parse_stylesheet(parser);
|
||||
|
||||
return {
|
||||
type: 'StyleSheet',
|
||||
start: 0,
|
||||
end: source.length,
|
||||
children
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {AST.Root} ast
|
||||
* @param {boolean | undefined} modern
|
||||
*/
|
||||
function to_public_ast(source, ast, modern) {
|
||||
if (modern) {
|
||||
const clean = (/** @type {any} */ node) => {
|
||||
delete node.metadata;
|
||||
};
|
||||
|
||||
ast.options?.attributes.forEach((attribute) => {
|
||||
clean(attribute);
|
||||
clean(attribute.value);
|
||||
if (Array.isArray(attribute.value)) {
|
||||
attribute.value.forEach(clean);
|
||||
}
|
||||
});
|
||||
|
||||
// remove things that we don't want to treat as public API
|
||||
return zimmerframe_walk(ast, null, {
|
||||
_(node, { next }) {
|
||||
clean(node);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return convert(source, ast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the byte order mark from a string if it's present since it would mess with our template generation logic
|
||||
* @param {string} source
|
||||
*/
|
||||
function remove_bom(source) {
|
||||
if (source.charCodeAt(0) === 0xfeff) {
|
||||
return source.slice(1);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replace this with `import { walk } from 'estree-walker'`
|
||||
* @returns {never}
|
||||
*/
|
||||
export function walk() {
|
||||
throw new Error(
|
||||
`'svelte/compiler' no longer exports a \`walk\` utility — please import it directly from 'estree-walker' instead`
|
||||
);
|
||||
}
|
||||
|
||||
export { VERSION } from '../version.js';
|
||||
export { migrate } from './migrate/index.js';
|
||||
Reference in New Issue
Block a user