From cee14e1fda67448790be5d3a73f60ccc797b418f Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sat, 24 Oct 2026 01:33:25 +0800 Subject: [PATCH] refactor(javascript): reuse semantic member-chain facts Resolve member structure through the existing AST owner while preserving binding, shadowing and global process identity checks in their consumers. --- .../javascriptSemanticDataEffectHelpers.ts | 23 ++++++++----------- .../javascriptSemanticRequireOrigin.ts | 14 +++-------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/domain/javascript/javascriptSemanticDataEffectHelpers.ts b/src/domain/javascript/javascriptSemanticDataEffectHelpers.ts index e014149f55..ccfd619b64 100644 --- a/src/domain/javascript/javascriptSemanticDataEffectHelpers.ts +++ b/src/domain/javascript/javascriptSemanticDataEffectHelpers.ts @@ -34,6 +34,7 @@ import { import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js"; import { readExactJavaScriptLiteral, + semanticMemberChain, semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js"; @@ -319,20 +320,14 @@ const semanticBoundMemberPath = ( readonly path: string[]; } | undefined => { - const path: string[] = []; - let current = unwrapJavaScriptExpression(node).node; - while ( - t.isMemberExpression(current) || - t.isOptionalMemberExpression(current) - ) { - const key = semanticStaticPropertyKey(current.property, current.computed); - if (key === null || !t.isNode(current.object)) return undefined; - path.unshift(key); - current = unwrapJavaScriptExpression(current.object).node; - } - if (!t.isIdentifier(current)) return undefined; - const binding = resolveSemanticBindingState(state, current, current.name); - return binding === undefined ? undefined : { binding, path }; + const chain = semanticMemberChain(node); + if (chain === undefined || !t.isIdentifier(chain.root)) return undefined; + const binding = resolveSemanticBindingState( + state, + chain.root, + chain.root.name, + ); + return binding === undefined ? undefined : { binding, path: chain.members }; }; type BuiltinBindingMemo = Map>; diff --git a/src/domain/javascript/javascriptSemanticRequireOrigin.ts b/src/domain/javascript/javascriptSemanticRequireOrigin.ts index f51d73224d..6b6d93824b 100644 --- a/src/domain/javascript/javascriptSemanticRequireOrigin.ts +++ b/src/domain/javascript/javascriptSemanticRequireOrigin.ts @@ -1460,17 +1460,9 @@ export const semanticGlobalProcessPathOrigin = ( node: t.Node, state: JavaScriptSemanticAnalysisState, ): JavaScriptModuleOrigin | undefined => { - const members: string[] = []; - let current = unwrapJavaScriptExpression(node).node; - while ( - t.isMemberExpression(current) || - t.isOptionalMemberExpression(current) - ) { - const key = semanticStaticPropertyKey(current.property, current.computed); - if (key === null) return undefined; - members.unshift(key); - current = unwrapJavaScriptExpression(current.object).node; - } + const chain = semanticMemberChain(node); + if (chain === undefined) return undefined; + const { root: current, members } = chain; if ( !t.isIdentifier(current) || !["globalThis", "global", "window", "self"].includes(current.name) ||