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

Function resolveRustModuleFile

src/resolution/import-resolver.ts:2149–2201  ·  view source on GitHub ↗

* Resolve a Rust module path (segments WITHOUT the leaf symbol) to the file of * the last module segment — `crate::a::b` → ` /a/b.rs` (or `.../b/mod.rs`). * Anchors on `crate` / `self` / `super`; a bare path is tried crate-relative.

(
  segments: string[],
  fromFile: string,
  context: ResolutionContext
)

Source from the content-addressed store, hash-verified

2147 * Anchors on `crate` / `self` / `super`; a bare path is tried crate-relative.
2148 */
2149function resolveRustModuleFile(
2150 segments: string[],
2151 fromFile: string,
2152 context: ResolutionContext
2153): string | null {
2154 if (segments.length === 0) return null;
2155 const projectRoot = context.getProjectRoot();
2156 const fromAbs = path.join(projectRoot, fromFile);
2157 const toRel = (p: string) => path.relative(projectRoot, p).replace(/\\/g, '/');
2158
2159 // Walk a sequence of module segments down from `startDir`, mapping each to a
2160 // `<seg>.rs` or `<seg>/mod.rs` file. Returns the leaf module's file, or null
2161 // if `startDir` is null or any segment has no file on disk.
2162 const resolveUnder = (startDir: string | null, rest: string[]): string | null => {
2163 if (!startDir) return null;
2164 let dir = startDir;
2165 let targetFile: string | null = null;
2166 for (const seg of rest) {
2167 if (seg === 'self' || seg === 'crate' || seg === 'super') continue;
2168 const asFile = toRel(path.join(dir, seg + '.rs'));
2169 const asMod = toRel(path.join(dir, seg, 'mod.rs'));
2170 if (context.fileExists(asFile)) targetFile = asFile;
2171 else if (context.fileExists(asMod)) targetFile = asMod;
2172 else return null;
2173 dir = path.join(dir, seg);
2174 }
2175 return targetFile;
2176 };
2177
2178 const first = segments[0]!;
2179 if (first === 'crate') {
2180 return resolveUnder(rustCrateRootDir(fromAbs, context), segments.slice(1));
2181 }
2182 if (first === 'self') {
2183 return resolveUnder(rustSelfModuleDir(fromAbs), segments.slice(1));
2184 }
2185 if (first === 'super') {
2186 let supers = 0;
2187 while (segments[supers] === 'super') supers++;
2188 let dir: string | null = rustSelfModuleDir(fromAbs);
2189 for (let s = 0; s < supers && dir; s++) dir = path.dirname(dir);
2190 return resolveUnder(dir, segments.slice(supers));
2191 }
2192 // Bare path. In expression position (`submodule::item()` — the router-assembly
2193 // and general cross-module-call pattern) the prefix is a SUBMODULE of the
2194 // current module, i.e. 2018 `self::`-relative — so try self-relative FIRST.
2195 // Fall back to crate-relative for 2015-edition / crate-root items. External
2196 // crate paths (`serde::de::Error`) miss both and fall through to name-matching.
2197 return (
2198 resolveUnder(rustSelfModuleDir(fromAbs), segments) ??
2199 resolveUnder(rustCrateRootDir(fromAbs, context), segments)
2200 );
2201}
2202
2203/**
2204 * Resolve a Java/Kotlin reference whose receiver is the simple name of

Callers 2

resolveRustPathReferenceFunction · 0.85
isBoundToOutOfRepoImportFunction · 0.85

Calls 5

resolveUnderFunction · 0.85
rustCrateRootDirFunction · 0.85
rustSelfModuleDirFunction · 0.85
getProjectRootMethod · 0.65
joinMethod · 0.45

Tested by

no test coverage detected