reexportClassifier
uses tcmts.core.analyze.externalModule, which uses node:module
What a project module re-exports from a package under a name: export { x as name } from "pkg", a name of
pkg's in export * from "pkg", or the package's namespace in export * as name from "pkg". Using it through
the module is using the package's export.
import { externalModule } from "#codebase/tcmts/core/analyze"; import type { AnalyzeHost } from "#codebase/tcmts/core/analyze"; import type { TypeChecker } from "#codebase/tcmts/core/ts"; import type { ExtRef } from "#codebase/tcmts/core/types"; import { isExportDeclaration as ts_isExportDeclaration, isNamedExports as ts_isNamedExports, isStringLiteral as ts_isStringLiteral, } from "typescript/ast"; import type { Node as ts_Node, SourceFile as ts_SourceFile } from "typescript/ast"; export function reexportClassifier(checker: TypeChecker, host: AnalyzeHost) { const cache = new Map<string, ExtRef | undefined>(); const exportsOf = new Map<string, Set<string>>(); return (sf: ts_SourceFile, name: string, at: ts_Node): ExtRef | undefined => { const key = `${sf.path}\0${name}`; if (cache.has(key)) return cache.get(key); let r: ExtRef | undefined; for (const st of sf.statements) { if ( !ts_isExportDeclaration(st) || !st.moduleSpecifier || !ts_isStringLiteral(st.moduleSpecifier) ) continue; const spec = st.moduleSpecifier.text; if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("#")) continue; if (st.exportClause) { if (ts_isNamedExports(st.exportClause)) { const el = st.exportClause.elements.find((e) => e.name.text === name); if (el) r = externalModule(spec, sf.fileName, at, (el.propertyName ?? el.name).text, host); } else if (st.exportClause.name.text === name) { r = externalModule(spec, sf.fileName, at, "*", host); } } else { const k = `${sf.path}\0${spec}`; if (!exportsOf.has(k)) { const mod = checker.getSymbolAtLocation(st.moduleSpecifier); exportsOf.set(k, new Set(mod ? checker.getExportsOfModule(mod).map((e) => e.name) : [])); } if (exportsOf.get(k)!.has(name)) r = externalModule(spec, sf.fileName, at, name, host); } if (r) break; } cache.set(key, r); return r; }; }
uses
- tcmts.core.analyze.AnalyzeHost
- tcmts.core.analyze.externalModule
- tcmts.core.ts.TypeChecker
- tcmts.core.types.ExtRef