mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
fix(javascript): retain unbound CommonJS semantic imports
Collect unbound literal CommonJS dependencies at the semantic module-link owner, retain null binding names and source provenance, and avoid duplicate links for calls already represented by bindings or re-exports. Preserve distinct nested calls, shadowing exclusions, dynamic binding uncertainty, and existing static asset references. Fixes #1793.
This commit is contained in:
1 parent
40d9c7b836
commit
3a17882cc4
10 files changed
+388
-33
No files matched your search
@@ -100,6 +100,7 @@ export const collectSemanticModuleLink = (
|
||||
);
|
||||
else if (t.isVariableDeclarator(node)) collectRequireLink(node, state);
|
||||
else if (t.isAssignmentExpression(node)) collectCommonJsExport(node, state);
|
||||
else if (t.isCallExpression(node)) collectUnboundRequireLink(node, state);
|
||||
};
|
||||
|
||||
/** Collect lexical references after definitions exist, optionally for one name. */
|
||||
@@ -322,9 +323,11 @@ const collectRequireLink = (
|
||||
node: t.VariableDeclarator,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): void => {
|
||||
const origin = semanticRequireOrigin(node.init, state);
|
||||
if (origin === undefined) return;
|
||||
for (const binding of requirePatternBindings(node.id, origin.importedPath))
|
||||
const required = semanticRequireOrigin(node.init, state);
|
||||
if (required === undefined) return;
|
||||
const { origin, call } = required;
|
||||
const bindings = requirePatternBindings(node.id, origin.importedPath);
|
||||
for (const binding of bindings)
|
||||
addModuleLink(
|
||||
state,
|
||||
{
|
||||
@@ -337,6 +340,29 @@ const collectRequireLink = (
|
||||
},
|
||||
node,
|
||||
);
|
||||
if (bindings.length > 0) state.linkedRequireCalls.add(call);
|
||||
};
|
||||
|
||||
const collectUnboundRequireLink = (
|
||||
node: t.CallExpression,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): void => {
|
||||
if (state.linkedRequireCalls.has(node)) return;
|
||||
const required = semanticRequireOrigin(node, state);
|
||||
if (required === undefined) return;
|
||||
addModuleLink(
|
||||
state,
|
||||
{
|
||||
kind: "require",
|
||||
specifier: required.origin.specifier,
|
||||
importedName: null,
|
||||
localName: null,
|
||||
exportedName: null,
|
||||
location: range(node),
|
||||
},
|
||||
node,
|
||||
);
|
||||
state.linkedRequireCalls.add(node);
|
||||
};
|
||||
|
||||
const requirePatternBindings = (
|
||||
@@ -382,8 +408,9 @@ const collectCommonJsExport = (
|
||||
node.operator === "=" && receiverEffect !== "uncertain" ? node.right : null;
|
||||
while (t.isAssignmentExpression(value, { operator: "=" }))
|
||||
value = value.right;
|
||||
const origin =
|
||||
const required =
|
||||
value === null ? undefined : semanticRequireOrigin(value, state);
|
||||
const origin = required?.origin;
|
||||
addModuleLink(
|
||||
state,
|
||||
{
|
||||
@@ -397,6 +424,7 @@ const collectCommonJsExport = (
|
||||
},
|
||||
node,
|
||||
);
|
||||
if (required !== undefined) state.linkedRequireCalls.add(required.call);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user