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

Function collectRustUseBindings

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

* Rust `use` declarations, flattened to `localName → full path`. * * Rust is the one supported language with NO `ImportMapping` extraction (see * `extractImportMappings`), so this is the only channel that can tell whether * a bare type name in a Rust file was brought in by a `use`. Handles neste

(content: string)

Source from the content-addressed store, hash-verified

2561 * name), and `as` aliases.
2562 */
2563function collectRustUseBindings(content: string): Map<string, string> {
2564 const out = new Map<string, string>();
2565
2566 // Expand one level of `{...}` at a time so `a::{b::{C, D}, E}` flattens.
2567 const expand = (spec: string): string[] => {
2568 const open = spec.indexOf('{');
2569 if (open === -1) return [spec.trim()];
2570 const prefix = spec.slice(0, open);
2571 let depth = 0;
2572 let close = -1;
2573 for (let i = open; i < spec.length; i++) {
2574 if (spec[i] === '{') depth++;
2575 else if (spec[i] === '}') {
2576 depth--;
2577 if (depth === 0) { close = i; break; }
2578 }
2579 }
2580 if (close === -1) return [];
2581 const suffix = spec.slice(close + 1);
2582 const inner = spec.slice(open + 1, close);
2583 const parts: string[] = [];
2584 let depth2 = 0;
2585 let start = 0;
2586 for (let i = 0; i <= inner.length; i++) {
2587 const ch = inner[i];
2588 if (ch === '{') depth2++;
2589 else if (ch === '}') depth2--;
2590 if (i === inner.length || (ch === ',' && depth2 === 0)) {
2591 const seg = inner.slice(start, i).trim();
2592 if (seg) parts.push(seg);
2593 start = i + 1;
2594 }
2595 }
2596 return parts.flatMap((p) => expand(prefix + p + suffix));
2597 };
2598
2599 // `use` items end at the first `;`. Attributes/visibility (`pub use`) are
2600 // irrelevant to the binding itself.
2601 const useRe = /(^|\n)\s*(?:pub(?:\([^)]*\))?\s+)?use\s+([^;]+);/g;
2602 let m: RegExpExecArray | null;
2603 while ((m = useRe.exec(content)) !== null) {
2604 for (const spec of expand(m[2]!.replace(/\s+/g, ' '))) {
2605 const aliasMatch = /^(.*?)\s+as\s+([A-Za-z_]\w*)$/.exec(spec);
2606 const rawPath = (aliasMatch ? aliasMatch[1]! : spec).trim();
2607 if (!rawPath || rawPath.endsWith('*')) continue;
2608 const segments = rawPath.split('::').map((s) => s.trim()).filter(Boolean);
2609 const leaf = segments[segments.length - 1];
2610 if (!leaf) continue;
2611 const local = aliasMatch ? aliasMatch[2]! : leaf;
2612 out.set(local, segments.join('::'));
2613 }
2614 }
2615 return out;
2616}
2617
2618/**
2619 * Is `name`, as used in `ref`'s file, bound by an import whose module lives

Callers 1

isBoundToOutOfRepoImportFunction · 0.85

Calls 5

expandFunction · 0.85
mapMethod · 0.80
execMethod · 0.65
setMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected