diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index c0acd0546c..10753729b3 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -691,9 +691,14 @@ export function analyze_component(root, source, options) { if (instance.has_await) { /** * @param {ESTree.Node} node - * @param {Set} dependencies + * @param {Set} seen + * @param {Set} reads + * @param {Set} writes */ - const trace_dependencies = (node, dependencies) => { + const trace_references = (node, reads, writes, seen = new Set()) => { + if (seen.has(node)) return; + seen.add(node); + walk( node, { scope: instance.scope }, @@ -706,33 +711,45 @@ export function analyze_component(root, source, options) { context.next(); } }, + AssignmentExpression(node, context) { + // TODO mark writes + }, + CallExpression(node, context) { + // TODO deopt arguments, assume they are mutated + // TODO recurse into function definitions + }, Identifier(node, context) { const parent = /** @type {ESTree.Node} */ (context.path.at(-1)); if (is_reference(node, parent)) { const binding = context.state.scope.get(node.name); if (binding) { - dependencies.add(binding); + reads.add(binding); } - - // TODO recurse into function definitions } } } ); - - return dependencies; }; /** * @param {ESTree.Statement | ESTree.VariableDeclarator | ESTree.FunctionDeclaration | ESTree.ClassDeclaration} node */ const push = (node) => { + /** @type {Set} */ + const reads = new Set(); + + /** @type {Set} */ + const writes = new Set(); + + trace_references(node, reads, writes); + /** @type {AwaitedStatement} */ const statement = { node, has_await: has_await_expression(node), declarations: [], - dependencies: trace_dependencies(node, new Set()) + reads, + writes }; analysis.awaited_statements.set(node, statement); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/Program.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/Program.js index 327e80f29a..bd07e4bd07 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/Program.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/Program.js @@ -236,7 +236,7 @@ function transform_body(program, context) { // find the earliest point we can insert this derived let index = -1; - for (const binding of derived.dependencies) { + for (const binding of derived.reads) { index = Math.max( index, statements.findIndex((s) => s.declarations.includes(binding)) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/Program.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/Program.js index 4d4d8deae9..5f3fa33394 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/Program.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/Program.js @@ -106,7 +106,7 @@ function transform_body(program, context) { // find the earliest point we can insert this derived let index = -1; - for (const binding of derived.dependencies) { + for (const binding of derived.reads) { index = Math.max( index, statements.findIndex((s) => s.declarations.includes(binding)) diff --git a/packages/svelte/src/compiler/phases/types.d.ts b/packages/svelte/src/compiler/phases/types.d.ts index 2a3617b2f1..c36b90a723 100644 --- a/packages/svelte/src/compiler/phases/types.d.ts +++ b/packages/svelte/src/compiler/phases/types.d.ts @@ -46,7 +46,8 @@ export interface AwaitedStatement { node: Statement | VariableDeclarator | ClassDeclaration | FunctionDeclaration; has_await: boolean; declarations: Binding[]; - dependencies: Set; + reads: Set; + writes: Set; } /**