refactor(javascript): normalize erased expression syntax once

This commit is contained in:
morluto
2026-10-10 01:39:28 +08:00
parent cfb12e47dc
commit b628bba1fa
17 changed files with 313 additions and 205 deletions
@@ -6,7 +6,10 @@ import {
semanticResolutionBlocked,
type JavaScriptSemanticAnalysisState,
} from "./javascriptSemanticState.js";
import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
import {
semanticStaticPropertyKey,
unwrapJavaScriptExpression,
} from "./javascriptAstValues.js";
import { stringValue } from "./javascriptStaticAnalysisHelpers.js";
/** Recover an unshadowed literal require origin and its exact member path. */
@@ -15,23 +18,34 @@ export const semanticRequireOrigin = (
state: JavaScriptSemanticAnalysisState,
): JavaScriptModuleOrigin | undefined => {
const members: string[] = [];
while (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
const member = semanticStaticPropertyKey(node.property, node.computed);
if (member === null || !t.isNode(node.object)) return undefined;
let current = node;
while (current !== null && current !== undefined) {
current = unwrapJavaScriptExpression(current).node;
if (
!t.isMemberExpression(current) &&
!t.isOptionalMemberExpression(current)
)
break;
const member = semanticStaticPropertyKey(
current.property,
current.computed,
);
if (member === null || !t.isNode(current.object)) return undefined;
members.push(member);
node = node.object;
current = current.object;
}
if (
!t.isCallExpression(node) ||
!t.isIdentifier(node.callee, { name: "require" })
!t.isCallExpression(current) ||
!t.isIdentifier(current.callee, { name: "require" })
)
return undefined;
if (
resolveSemanticBindingState(state, node.callee, "require") !== undefined ||
semanticResolutionBlocked(state, node.callee, "require")
resolveSemanticBindingState(state, current.callee, "require") !==
undefined ||
semanticResolutionBlocked(state, current.callee, "require")
)
return undefined;
const specifier = stringValue(node.arguments[0]);
const specifier = stringValue(current.arguments[0]);
return specifier === undefined
? undefined
: { specifier, importedPath: members.reverse() };