fix: return ast from `compile` (#11191)

Svelte 4 does it and language tools assumes it's there
This also uncovered another case of how ridicoulus the old AST was
pull/11193/head
Simon H 1 year ago committed by GitHub
parent 7363f873df
commit e7869faf4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: return ast from `compile` (like Svelte 4 does)

@ -44,6 +44,7 @@ export function compile(source, options) {
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;
} catch (e) {
if (e instanceof CompileError) {
@ -121,7 +122,16 @@ export function parse(source, options = {}) {
throw e;
}
if (options.modern) {
return to_public_ast(source, ast, options.modern);
}
/**
* @param {string} source
* @param {import('#compiler').Root} ast
* @param {boolean | undefined} modern
*/
function to_public_ast(source, ast, modern) {
if (modern) {
// remove things that we don't want to treat as public API
return walk(ast, null, {
_(node, { next }) {

@ -141,29 +141,37 @@ export function convert(source, ast) {
};
if (node.pending) {
const first = /** @type {import('#compiler').BaseNode} */ (node.pending.nodes.at(0));
const last = /** @type {import('#compiler').BaseNode} */ (node.pending.nodes.at(-1));
const first = node.pending.nodes.at(0);
const last = node.pending.nodes.at(-1);
pendingblock.start = first.start;
pendingblock.end = last.end;
pendingblock.start = first?.start ?? source.indexOf('}', node.expression.end) + 1;
pendingblock.end = last?.end ?? pendingblock.start;
pendingblock.skip = false;
}
if (node.then) {
const first = /** @type {import('#compiler').BaseNode} */ (node.then.nodes.at(0));
const last = /** @type {import('#compiler').BaseNode} */ (node.then.nodes.at(-1));
const first = node.then.nodes.at(0);
const last = node.then.nodes.at(-1);
thenblock.start = pendingblock.end ?? first.start;
thenblock.end = last.end;
thenblock.start =
pendingblock.end ?? first?.start ?? source.indexOf('}', node.expression.end) + 1;
thenblock.end =
last?.end ?? source.lastIndexOf('}', pendingblock.end ?? node.expression.end) + 1;
thenblock.skip = false;
}
if (node.catch) {
const first = /** @type {import('#compiler').BaseNode} */ (node.catch.nodes.at(0));
const last = /** @type {import('#compiler').BaseNode} */ (node.catch.nodes.at(-1));
catchblock.start = thenblock.end ?? pendingblock.end ?? first.start;
catchblock.end = last.end;
const first = node.catch.nodes.at(0);
const last = node.catch.nodes.at(-1);
catchblock.start =
thenblock.end ??
pendingblock.end ??
first?.start ??
source.indexOf('}', node.expression.end) + 1;
catchblock.end =
last?.end ??
source.lastIndexOf('}', thenblock.end ?? pendingblock.end ?? node.expression.end) + 1;
catchblock.skip = false;
}

@ -20,7 +20,8 @@ export function transform_component(analysis, source, options) {
warnings: transform_warnings(source, options.filename, analysis.warnings),
metadata: {
runes: analysis.runes
}
},
ast: /** @type {any} */ (null) // set afterwards
};
}
@ -62,7 +63,8 @@ export function transform_component(analysis, source, options) {
warnings: transform_warnings(source, options.filename, analysis.warnings), // TODO apply preprocessor sourcemap
metadata: {
runes: analysis.runes
}
},
ast: /** @type {any} */ (null) // set afterwards
};
}
@ -80,7 +82,8 @@ export function transform_module(analysis, source, options) {
warnings: transform_warnings(source, analysis.name, analysis.warnings),
metadata: {
runes: true
}
},
ast: /** @type {any} */ (null) // set afterwards
};
}
@ -105,7 +108,8 @@ export function transform_module(analysis, source, options) {
warnings: transform_warnings(source, analysis.name, analysis.warnings),
metadata: {
runes: true
}
},
ast: /** @type {any} */ (null) // set afterwards
};
}

@ -46,6 +46,8 @@ export interface CompileResult {
*/
runes: boolean;
};
/** The AST */
ast: any;
}
export interface Warning {
@ -184,6 +186,13 @@ export interface CompileOptions extends ModuleCompileOptions {
* @default false
*/
hmr?: boolean;
/**
* If `true`, returns the modern version of the AST.
* Will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
*
* @default false
*/
modernAst?: boolean;
}
export interface ModuleCompileOptions {

@ -541,6 +541,8 @@ declare module 'svelte/compiler' {
*/
runes: boolean;
};
/** The AST */
ast: any;
}
interface Warning {
@ -675,6 +677,13 @@ declare module 'svelte/compiler' {
* @default false
*/
hmr?: boolean;
/**
* If `true`, returns the modern version of the AST.
* Will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
*
* @default false
*/
modernAst?: boolean;
}
interface ModuleCompileOptions {
@ -2476,6 +2485,13 @@ declare module 'svelte/types/compiler/interfaces' {
* @default false
*/
hmr?: boolean;
/**
* If `true`, returns the modern version of the AST.
* Will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.
*
* @default false
*/
modernAst?: boolean;
}
interface ModuleCompileOptions {

Loading…
Cancel
Save