opt into runes mode when using blocking await

aaa
Rich Harris 8 months ago
parent f355eaf9a0
commit d5de86803d

@ -203,9 +203,9 @@ function js(script, root, allow_reactive_declarations, parent) {
body: [] body: []
}; };
const { scope, scopes } = create_scopes(ast, root, allow_reactive_declarations, parent); const { scope, scopes, is_async } = create_scopes(ast, root, allow_reactive_declarations, parent);
return { ast, scope, scopes }; return { ast, scope, scopes, is_async };
} }
/** /**
@ -230,7 +230,7 @@ const RESERVED = ['$$props', '$$restProps', '$$slots'];
* @returns {Analysis} * @returns {Analysis}
*/ */
export function analyze_module(ast, options) { export function analyze_module(ast, options) {
const { scope, scopes } = create_scopes(ast, new ScopeRoot(), false, null); const { scope, scopes, is_async } = create_scopes(ast, new ScopeRoot(), false, null);
for (const [name, references] of scope.references) { for (const [name, references] of scope.references) {
if (name[0] !== '$' || RESERVED.includes(name)) continue; if (name[0] !== '$' || RESERVED.includes(name)) continue;
@ -259,7 +259,7 @@ export function analyze_module(ast, options) {
); );
return { return {
module: { ast, scope, scopes }, module: { ast, scope, scopes, is_async },
name: options.filename, name: options.filename,
accessors: false, accessors: false,
runes: true, runes: true,
@ -282,7 +282,12 @@ export function analyze_component(root, source, options) {
const module = js(root.module, scope_root, false, null); const module = js(root.module, scope_root, false, null);
const instance = js(root.instance, scope_root, true, module.scope); const instance = js(root.instance, scope_root, true, module.scope);
const { scope, scopes } = create_scopes(root.fragment, scope_root, false, instance.scope); const { scope, scopes, is_async } = create_scopes(
root.fragment,
scope_root,
false,
instance.scope
);
/** @type {Template} */ /** @type {Template} */
const template = { ast: root.fragment, scope, scopes }; const template = { ast: root.fragment, scope, scopes };
@ -390,7 +395,9 @@ export function analyze_component(root, source, options) {
const component_name = get_component_name(options.filename); const component_name = get_component_name(options.filename);
const runes = options.runes ?? Array.from(module.scope.references.keys()).some(is_rune); const runes =
options.runes ??
(is_async || instance.is_async || Array.from(module.scope.references.keys()).some(is_rune));
if (!runes) { if (!runes) {
for (let check of synthetic_stores_legacy_check) { for (let check of synthetic_stores_legacy_check) {

@ -345,7 +345,24 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
} }
}; };
let is_async = false;
walk(ast, state, { walk(ast, state, {
AwaitExpression(node, context) {
// this doesn't _really_ belong here, but it allows us to
// automatically opt into runes mode on encountering
// blocking awaits, without doing an additional walk
// before the analysis occurs
is_async ||= context.path.every(
({ type }) =>
type !== 'ArrowFunctionExpression' &&
type !== 'FunctionExpression' &&
type !== 'FunctionDeclaration'
);
context.next();
},
// references // references
Identifier(node, { path, state }) { Identifier(node, { path, state }) {
const parent = path.at(-1); const parent = path.at(-1);
@ -713,6 +730,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
} }
return { return {
is_async,
scope, scope,
scopes scopes
}; };

@ -13,6 +13,7 @@ export interface Js {
ast: Program; ast: Program;
scope: Scope; scope: Scope;
scopes: Map<AST.SvelteNode, Scope>; scopes: Map<AST.SvelteNode, Scope>;
is_async: boolean;
} }
export interface Template { export interface Template {

Loading…
Cancel
Save