mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import * as t from "@babel/types";
|
|
|
|
import type { JavaScriptModuleOrigin } from "./javascriptSemanticIr.js";
|
|
import {
|
|
resolveSemanticBindingState,
|
|
semanticResolutionBlocked,
|
|
type JavaScriptSemanticAnalysisState,
|
|
} from "./javascriptSemanticState.js";
|
|
import {
|
|
semanticStaticPropertyKey,
|
|
unwrapJavaScriptExpression,
|
|
} from "./javascriptAstValues.js";
|
|
import { stringValue } from "./javascriptStaticAnalysisHelpers.js";
|
|
|
|
/** Recover an unshadowed literal require origin and its exact member path. */
|
|
export const semanticRequireOrigin = (
|
|
node: t.Node | null | undefined,
|
|
state: JavaScriptSemanticAnalysisState,
|
|
): JavaScriptModuleOrigin | undefined => {
|
|
const members: string[] = [];
|
|
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);
|
|
current = current.object;
|
|
}
|
|
if (
|
|
!t.isCallExpression(current) ||
|
|
!t.isIdentifier(current.callee, { name: "require" })
|
|
)
|
|
return undefined;
|
|
if (
|
|
resolveSemanticBindingState(state, current.callee, "require") !==
|
|
undefined ||
|
|
semanticResolutionBlocked(state, current.callee, "require")
|
|
)
|
|
return undefined;
|
|
const specifier = stringValue(current.arguments[0]);
|
|
return specifier === undefined
|
|
? undefined
|
|
: { specifier, importedPath: members.reverse() };
|
|
};
|