fix(javascript): derive loader references from lexical binding ownership

Use shared lexical bindings and recovered bundler identities for require and chunk references. Preserve uncertain writes as unresolved evidence; remove name-only loader aliases and repeated definition scans.

Reviewed-PR: #2989
Co-authored-by: Hussnain Ahmad <ha7886899@gmail.com>
This commit is contained in:
morlutoandHussnain Ahmad committed 2026-10-14 16:10:46 +08:00
1 parent f2f83934d2
commit eef4a0bfb4
8 files changed
+509 -32

No files matched your search

@@ -6,6 +6,7 @@ import type { JavaScriptModuleOrigin } from "./javascriptSemanticIr.js";
import {
resolveSemanticBindingState,
semanticResolutionBlocked,
semanticStableInitializer,
type JavaScriptSemanticAnalysisState,
} from "./javascriptSemanticState.js";
import {
@@ -22,6 +23,169 @@ export interface JavaScriptRequireOrigin {
readonly call: t.CallExpression;
}
export type JavaScriptRequireLoaderFact =
| "commonjs-loader"
| "factory-loader"
| "create-require"
| "local"
| "unknown";
/** Classify a bare `require(...)` using the shared lexical binding owner. */
export const semanticRequireLoaderAt = (
node: t.CallExpression | t.OptionalCallExpression | t.NewExpression,
state: JavaScriptSemanticAnalysisState,
factoryBindingIds: ReadonlySet<string>,
): JavaScriptRequireLoaderFact => {
if (!t.isIdentifier(node.callee, { name: "require" })) return "local";
const binding = resolveSemanticBindingState(state, node.callee, "require");
if (binding === undefined)
return semanticResolutionBlocked(state, node.callee, "require")
? "unknown"
: "commonjs-loader";
if (factoryBindingIds.has(binding.bindingId))
return binding.initializers.length === 0 ? "factory-loader" : "unknown";
if (isWrapperRequireInitializerCall(binding, node, state))
return "commonjs-loader";
const scope = state.scopesById.get(binding.scopeId);
if (
scope?.kind === "program" &&
binding.declarationKinds.size > 0 &&
[...binding.declarationKinds].every((kind) => kind === "var") &&
binding.initializers.length === 0
)
return "commonjs-loader";
if (isSemanticCreateRequireBinding(binding, state)) return "create-require";
const initializer = semanticStableInitializer(binding, state)?.node;
if (
(binding.kind === "function" || binding.kind === "class") &&
initializer !== undefined
)
return "local";
if (
binding.declarationKinds.size === 1 &&
binding.declarationKinds.has("const") &&
(t.isFunctionExpression(initializer) ||
t.isArrowFunctionExpression(initializer))
)
return "local";
return "unknown";
};
/** Classify a call through an exact recovered factory-loader binding. */
export const semanticFactoryRequireLoaderAt = (
node: t.CallExpression | t.OptionalCallExpression | t.NewExpression,
state: JavaScriptSemanticAnalysisState,
bindingIds: ReadonlySet<string>,
): JavaScriptRequireLoaderFact | undefined => {
const callee = unwrapJavaScriptExpression(node.callee).node;
if (t.isIdentifier(callee))
return semanticFactoryLoaderMemberAt(node, state, bindingIds, null);
if (
(t.isMemberExpression(callee) || t.isOptionalMemberExpression(callee)) &&
semanticStaticPropertyKey(callee.property, callee.computed) === "bind"
)
return semanticFactoryLoaderMemberAt(node, state, bindingIds, "bind");
return undefined;
};
/** Classify an exact loader call by binding identity and expected member. */
export const semanticFactoryLoaderMemberAt = (
node: t.CallExpression | t.OptionalCallExpression | t.NewExpression,
state: JavaScriptSemanticAnalysisState,
bindingIds: ReadonlySet<string>,
member: string | null,
): JavaScriptRequireLoaderFact | undefined => {
const callee = unwrapJavaScriptExpression(node.callee).node;
let loader: t.Identifier | undefined;
if (member === null) {
if (t.isIdentifier(callee)) loader = callee;
} else if (
(t.isMemberExpression(callee) || t.isOptionalMemberExpression(callee)) &&
semanticStaticPropertyKey(callee.property, callee.computed) === member
) {
const root = unwrapJavaScriptExpression(callee.object).node;
if (t.isIdentifier(root)) loader = root;
}
if (loader === undefined) return undefined;
const binding = resolveSemanticBindingState(state, loader, loader.name);
if (binding === undefined || !bindingIds.has(binding.bindingId))
return undefined;
return binding.initializers.length === 0 ? "factory-loader" : "unknown";
};
const isSemanticCreateRequireBinding = (
binding: NonNullable<ReturnType<typeof resolveSemanticBindingState>>,
state: JavaScriptSemanticAnalysisState,
): boolean => {
if (binding.initializers.length !== 1) return false;
const initializer = semanticStableInitializer(binding, state)?.node;
if (!t.isCallExpression(initializer)) return false;
const callee = unwrapJavaScriptExpression(initializer.callee).node;
if (t.isIdentifier(callee)) {
const origins = resolveSemanticBindingState(
state,
callee,
callee.name,
)?.directOrigins;
if (origins?.length !== 1) return false;
const [origin] = origins;
return (
origin?.importedPath.at(-1) === "createRequire" &&
["module", "node:module"].includes(origin.specifier)
);
}
const chain = semanticMemberChain(callee);
if (chain === undefined || chain.members.at(-1) !== "createRequire")
return false;
if (!t.isNode(chain.root)) return false;
const root = unwrapJavaScriptExpression(chain.root).node;
if (!t.isIdentifier(root)) return false;
const origins = resolveSemanticBindingState(
state,
root,
root.name,
)?.directOrigins;
if (origins?.length !== 1) return false;
const [origin] = origins;
return (
origin?.importedPath.length === 0 &&
["module", "node:module"].includes(origin.specifier)
);
};
/** The RHS call runs before its assignment replaces Node's wrapper loader. */
const isWrapperRequireInitializerCall = (
binding: NonNullable<ReturnType<typeof resolveSemanticBindingState>>,
node: t.CallExpression | t.OptionalCallExpression | t.NewExpression,
state: JavaScriptSemanticAnalysisState,
): boolean => {
const scope = state.scopesById.get(binding.scopeId);
if (
scope?.kind !== "program" ||
binding.kind !== "variable" ||
binding.declarationKinds.size !== 1 ||
!binding.declarationKinds.has("var") ||
binding.initializers.length !== 1 ||
binding.initializers[0]?.node !== node
)
return false;
const assignment = state.parentsByNode.get(node);
if (
!t.isAssignmentExpression(assignment) ||
assignment.right !== node ||
state.conditionallySkippedExpressions.has(node)
)
return false;
const statement = state.parentsByNode.get(assignment);
if (!t.isExpressionStatement(statement)) return false;
if (state.parentsByNode.get(statement) !== state.program) return false;
const target = unwrapJavaScriptExpression(assignment.left).node;
return (
t.isIdentifier(target, { name: "require" }) &&
resolveSemanticBindingState(state, target, target.name) === binding
);
};
// Ambient indexing finishes before these derived facts are consumed. Keep only
// replacement sites, rather than rescanning unrelated global member writes.
const globalProcessReplacements = new WeakMap<