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

Function findExportedSymbolWalk

src/resolution/import-resolver.ts:2112–2190  ·  view source on GitHub ↗
(
  filePath: string,
  want: {
    isDefault: boolean;
    isNamespace: boolean;
    exportedName: string;
    memberName: string | null;
  },
  language: Language,
  context: ResolutionContext,
  visited: Set<string>,
  depth: number
)

Source from the content-addressed store, hash-verified

2110}
2111
2112function findExportedSymbolWalk(
2113 filePath: string,
2114 want: {
2115 isDefault: boolean;
2116 isNamespace: boolean;
2117 exportedName: string;
2118 memberName: string | null;
2119 },
2120 language: Language,
2121 context: ResolutionContext,
2122 visited: Set<string>,
2123 depth: number
2124): Node | undefined {
2125 if (depth > REEXPORT_MAX_DEPTH) return undefined;
2126 if (visited.has(filePath)) return undefined;
2127 visited.add(filePath);
2128
2129 const exportIndex = getFileExportIndex(filePath, context);
2130
2131 // 1. Direct hit: the symbol is declared in this file.
2132 if (want.isDefault) {
2133 // Svelte/Vue single-file components ARE the module's default export,
2134 // but are extracted as kind 'component' (not function/class). Prefer
2135 // the component node; fall back to an exported function/class for the
2136 // `.ts`/`.tsx` `export default fn`/`class` case. Without the component
2137 // branch, an `export { default as X } from './X.svelte'` barrel never
2138 // resolves and the component shows a false 0 callers (#629).
2139 const direct = exportIndex.defaultComponent ?? exportIndex.defaultFnClass;
2140 if (direct) return direct;
2141 } else if (want.isNamespace && want.memberName) {
2142 const direct = exportIndex.byName.get(want.memberName);
2143 if (direct) return direct;
2144 } else {
2145 const direct = exportIndex.byName.get(want.exportedName);
2146 if (direct) return direct;
2147 }
2148
2149 // 2. Re-export hit: the file forwards the symbol to another module.
2150 const reExports = context.getReExports?.(filePath, language) ?? [];
2151 if (reExports.length === 0) return undefined;
2152
2153 // Look for explicit `export { want } from './other'` (with optional rename).
2154 const targetName = want.isDefault ? 'default' : want.exportedName;
2155 for (const rex of reExports) {
2156 if (rex.kind === 'named' && rex.exportedName === targetName) {
2157 const next = resolveImportPath(rex.source, filePath, language, context);
2158 if (!next) continue;
2159 // After rename: `export { foo as bar } from './x'` — to chase
2160 // `bar`, we look for `foo` in `./x`.
2161 const chained = findExportedSymbol(
2162 next,
2163 {
2164 isDefault: rex.originalName === 'default',
2165 isNamespace: false,
2166 exportedName: rex.originalName,
2167 memberName: null,
2168 },
2169 language,

Callers 1

findExportedSymbolFunction · 0.85

Calls 6

getFileExportIndexFunction · 0.85
resolveImportPathFunction · 0.85
findExportedSymbolFunction · 0.85
hasMethod · 0.80
getReExportsMethod · 0.80
getMethod · 0.65

Tested by

no test coverage detected