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

Method findAllSymbols

src/mcp/tools.ts:4498–4554  ·  view source on GitHub ↗

* Find ALL symbols matching a name. Used by callers/callees/impact to aggregate * results across all matching symbols (e.g., multiple classes with an `execute` method).

(cg: CodeGraph, symbol: string)

Source from the content-addressed store, hash-verified

4496 * results across all matching symbols (e.g., multiple classes with an `execute` method).
4497 */
4498 private findAllSymbols(cg: CodeGraph, symbol: string): { nodes: Node[]; note: string } {
4499 // Nix option paths: the declaration is stored as `options.<path>` and
4500 // config writes carry longer/quoted tails (`<path>."git/config".text`),
4501 // so a dotted option token (`xdg.configFile`, `launchd.user.agents`) has
4502 // no exact-name node and would degrade to bare-tail FTS soup — burying
4503 // the declaration hub the nix-option-path edges hang off. Resolve the
4504 // convention directly: declaration first, then the exact write, then a
4505 // capped prefix scan of write sites. Three index hits; non-nix graphs
4506 // fall straight through.
4507 if (/^[a-z][\w'-]*(?:\.[\w'-]+)+$/.test(symbol)) {
4508 const optionHits = [
4509 ...cg.getNodesByName(`options.${symbol}`),
4510 ...cg.getNodesByName(symbol),
4511 ...cg.getNodesByNamePrefix(`${symbol}.`, 12),
4512 ].filter((n) => n.language === 'nix');
4513 if (optionHits.length > 0) {
4514 const seen = new Set<string>();
4515 const nodes = optionHits.filter((n) => !seen.has(n.id) && !!seen.add(n.id)).slice(0, 10);
4516 return { nodes, note: '' };
4517 }
4518 }
4519 let results = cg.searchNodes(symbol, { limit: 50 });
4520
4521 // Mirror the fallback in `findSymbol` for qualified queries — FTS
4522 // strips colons, so a module-qualified lookup needs a second pass
4523 // by the bare last part.
4524 if (results.length === 0 && /[.\/]|::/.test(symbol)) {
4525 const tail = lastQualifierPart(symbol);
4526 if (tail && tail !== symbol) results = cg.searchNodes(tail, { limit: 50 });
4527 }
4528
4529 if (results.length === 0) {
4530 return { nodes: [], note: '' };
4531 }
4532
4533 const exactMatches = results.filter(r => this.matchesSymbol(r.node, symbol));
4534
4535 if (exactMatches.length <= 1) {
4536 const node = exactMatches[0]?.node ?? results[0]!.node;
4537 return { nodes: [node], note: '' };
4538 }
4539
4540 // Same generated-file down-rank as findSymbol — keeps callers/callees
4541 // /impact aggregation aligned (a query against "Send" returns the
4542 // hand-written implementations before the protobuf scaffold).
4543 const ranked = [...exactMatches].sort((a, b) => {
4544 const aGen = isGeneratedFile(a.node.filePath) ? 1 : 0;
4545 const bGen = isGeneratedFile(b.node.filePath) ? 1 : 0;
4546 return aGen - bGen;
4547 });
4548
4549 const locations = ranked.map(r =>
4550 `${r.node.kind} at ${r.node.filePath}:${r.node.startLine}`
4551 );
4552 const note = `\n\n> **Note:** Aggregated results across ${ranked.length} symbols named "${symbol}": ${locations.join(', ')}`;
4553 return { nodes: ranked.map(r => r.node), note };
4554 }
4555

Callers 5

handleCallersMethod · 0.95
handleCalleesMethod · 0.95
handleImpactMethod · 0.95
handleExploreMethod · 0.95

Calls 8

matchesSymbolMethod · 0.95
isGeneratedFileFunction · 0.90
lastQualifierPartFunction · 0.85
hasMethod · 0.80
getNodesByNameMethod · 0.65
getNodesByNamePrefixMethod · 0.45
searchNodesMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected