fix(javascript): preserve TypeScript loader and dependency semantics
Share loader selection across static findings and module relationships: CTS static imports and re-exports use CommonJS lookup while dynamic imports retain ESM lookup. Retain runtime import-equals dependencies, bindings, and exported names; do not resolve require file-URL strings as local artifacts. Restore import-map descriptions in CLI help. Validated resolver and semantic tests, application reconstruction boundaries, and CLI help. Installed TypeScript NodeNext emission and Node require behavior were checked independently. Refs #2056, #2057, #2058, #2053.
This commit is contained in:
1 parent
966f7cc84b
commit
e4532b5376
8 files changed
+242
-13
No files matched your search
@@ -69,7 +69,8 @@ export const collectSemanticModuleLink = (
|
||||
node: t.Node,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): void => {
|
||||
if (t.isImportDeclaration(node)) collectImports(node, state);
|
||||
if (t.isTSImportEqualsDeclaration(node)) collectImportEquals(node, state);
|
||||
else if (t.isImportDeclaration(node)) collectImports(node, state);
|
||||
else if (t.isExportAllDeclaration(node))
|
||||
addModuleLink(
|
||||
state,
|
||||
@@ -103,6 +104,36 @@ export const collectSemanticModuleLink = (
|
||||
else if (t.isCallExpression(node)) collectUnboundRequireLink(node, state);
|
||||
};
|
||||
|
||||
const collectImportEquals = (
|
||||
node: t.TSImportEqualsDeclaration,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): void => {
|
||||
const specifier = semanticImportEqualsSpecifier(node);
|
||||
if (specifier === null) return;
|
||||
addModuleLink(
|
||||
state,
|
||||
{
|
||||
kind: "require",
|
||||
specifier,
|
||||
importedName: null,
|
||||
localName: node.id.name,
|
||||
exportedName: null,
|
||||
location: range(node),
|
||||
},
|
||||
node,
|
||||
);
|
||||
};
|
||||
|
||||
/** Runtime external-module target for a value import-equals declaration. */
|
||||
export const semanticImportEqualsSpecifier = (
|
||||
node: t.TSImportEqualsDeclaration,
|
||||
): string | null =>
|
||||
node.importKind !== "type" &&
|
||||
t.isTSExternalModuleReference(node.moduleReference) &&
|
||||
t.isStringLiteral(node.moduleReference.expression)
|
||||
? node.moduleReference.expression.value
|
||||
: null;
|
||||
|
||||
/** Collect lexical references after definitions exist, optionally for one name. */
|
||||
export const collectSemanticReferences = (
|
||||
program: t.Program,
|
||||
@@ -707,6 +738,11 @@ const declarationNames = (declaration: t.Declaration): string[] => {
|
||||
t.isIdentifier(declaration.id)
|
||||
)
|
||||
return [declaration.id.name];
|
||||
if (
|
||||
t.isTSImportEqualsDeclaration(declaration) &&
|
||||
semanticImportEqualsSpecifier(declaration) !== null
|
||||
)
|
||||
return [declaration.id.name];
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user