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.
This commit is contained in:
morluto
2026-10-24 01:33:25 +08:00
parent 92f28b2f56
commit cee14e1fda
2 changed files with 12 additions and 25 deletions
@@ -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<t.Node, Map<string, readonly string[] | null>>;
@@ -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) ||