MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / resolveModuleImportToFile

Function resolveModuleImportToFile

src/resolution/import-resolver.ts:1950–2004  ·  view source on GitHub ↗
(
  ref: UnresolvedRef,
  imports: ImportMapping[],
  context: ResolutionContext
)

Source from the content-addressed store, hash-verified

1948}
1949
1950function resolveModuleImportToFile(
1951 ref: UnresolvedRef,
1952 imports: ImportMapping[],
1953 context: ResolutionContext
1954): ResolvedRef | null {
1955 if (ref.referenceKind !== 'imports') return null;
1956 if (ref.referenceName.includes('.')) return null;
1957
1958 for (const imp of imports) {
1959 if (imp.localName !== ref.referenceName) continue;
1960
1961 let modulePath: string;
1962 if (imp.isNamespace || imp.isDefault) {
1963 // `import * as ns from './x'` (namespace) or `import x from './x'`
1964 // (default) — the dependency is on the MODULE FILE. A default import binds
1965 // a (possibly renamed) local to whatever the module's default export is
1966 // (`import articlesController from './article.controller'` ← `export
1967 // default router`), so the binding name can't be found as a symbol — link
1968 // the file the import resolves to instead. External modules don't resolve
1969 // (no file), so `import React from 'react'` creates no edge.
1970 modulePath = imp.source;
1971 } else if (ref.language === 'python') {
1972 // `from . import certs` — the imported NAME is a submodule of the source.
1973 // As in resolvePythonModuleMember, use the exported name so an alias
1974 // still links to the real module file (#1626).
1975 const moduleName = imp.exportedName === '*' ? imp.localName : imp.exportedName;
1976 modulePath = imp.source.endsWith('.')
1977 ? imp.source + moduleName
1978 : imp.source + '.' + moduleName;
1979 } else {
1980 // A named TS/JS import binds a symbol, not a module — leave it alone.
1981 continue;
1982 }
1983
1984 const resolvedPath = resolveImportPath(modulePath, ref.filePath, ref.language, context);
1985 if (resolvedPath && resolvedPath !== ref.filePath) {
1986 const fileNode = context.getNodesInFile(resolvedPath).find((n) => n.kind === 'file');
1987 if (fileNode) {
1988 return { original: ref, targetNodeId: fileNode.id, confidence: 0.9, resolvedBy: 'import' };
1989 }
1990 }
1991
1992 // Python absolute `from a.b import submodule` (a FastAPI router aggregator's
1993 // `from app.api.routes import authentication`): resolveImportPath only maps
1994 // RELATIVE dotted paths to a file, so resolve the absolute dotted module
1995 // directly to its file node.
1996 if (ref.language === 'python') {
1997 const modFile = findPythonModuleFile(modulePath, context, ref.filePath);
1998 if (modFile) {
1999 return { original: ref, targetNodeId: modFile.id, confidence: 0.9, resolvedBy: 'import' };
2000 }
2001 }
2002 }
2003 return null;
2004}
2005
2006/**
2007 * Find the file node for a Python dotted module path `a.b.c` — a module file

Callers 1

resolveViaImportFunction · 0.85

Calls 3

resolveImportPathFunction · 0.85
findPythonModuleFileFunction · 0.85
getNodesInFileMethod · 0.65

Tested by

no test coverage detected