From b8a8190b2f30e377eee2d69d1ba31ea454fa70b9 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sat, 10 Oct 2026 07:40:25 +0800 Subject: [PATCH] fix(javascript): retain conditional mutation ordering uncertainty --- ...manticAnalysis.reference_lifetimes.test.ts | 2 ++ .../javascriptSemanticMutationInitializers.ts | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts b/src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts index 0a339f2ca..2795427bd 100644 --- a/src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts +++ b/src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts @@ -72,6 +72,8 @@ describe("reference lifetimes across calls and shallow copies", () => { "mutate(alias); alias={};", "if(flag) alias={}; mutate(alias);", "alias={}; if(flag) mutate(alias);", + "alias={}; flag && mutate(alias);", + "alias={}; flag ? mutate(alias) : noop();", "function invoke(){mutate(alias);} alias={}; invoke();", "alias={}; mutate(alias); alias=source;", ])("retains uncertain call ordering: %s", (body) => { diff --git a/src/domain/javascript/javascriptSemanticMutationInitializers.ts b/src/domain/javascript/javascriptSemanticMutationInitializers.ts index 970f6b1f2..cfaaf0ef5 100644 --- a/src/domain/javascript/javascriptSemanticMutationInitializers.ts +++ b/src/domain/javascript/javascriptSemanticMutationInitializers.ts @@ -94,19 +94,25 @@ const directMutationPosition = ( !t.isTaggedTemplateExpression(node) ) return null; - let current = parents.get(node); - while (current !== undefined) { - if (t.isFunction(current)) return null; - if (t.isStatement(current)) return statementPosition(current, parents); - if (t.isVariableDeclarator(current)) { - const declaration = parents.get(current); + let current: t.Node = node; + while (true) { + const parent = parents.get(current); + if ( + parent === undefined || + t.isFunction(parent) || + (t.isLogicalExpression(parent) && parent.right === current) || + (t.isConditionalExpression(parent) && parent.test !== current) + ) + return null; + if (t.isStatement(parent)) return statementPosition(parent, parents); + if (t.isVariableDeclarator(parent)) { + const declaration = parents.get(parent); return t.isVariableDeclaration(declaration) - ? statementPosition(declaration, parents, current) + ? statementPosition(declaration, parents, parent) : null; } - current = parents.get(current); + current = parent; } - return null; }; const referenceInitializerPosition = (