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

Method findAllSymbols

src/mcp/tools.ts:4735–4791  ·  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

4733 * results across all matching symbols (e.g., multiple classes with an `execute` method).
4734 */
4735 private findAllSymbols(cg: CodeGraph, symbol: string): { nodes: Node[]; note: string } {
4736 // Nix option paths: the declaration is stored as `options.<path>` and
4737 // config writes carry longer/quoted tails (`<path>."git/config".text`),
4738 // so a dotted option token (`xdg.configFile`, `launchd.user.agents`) has
4739 // no exact-name node and would degrade to bare-tail FTS soup — burying
4740 // the declaration hub the nix-option-path edges hang off. Resolve the
4741 // convention directly: declaration first, then the exact write, then a
4742 // capped prefix scan of write sites. Three index hits; non-nix graphs
4743 // fall straight through.
4744 if (/^[a-z][\w'-]*(?:\.[\w'-]+)+$/.test(symbol)) {
4745 const optionHits = [
4746 ...cg.getNodesByName(`options.${symbol}`),
4747 ...cg.getNodesByName(symbol),
4748 ...cg.getNodesByNamePrefix(`${symbol}.`, 12),
4749 ].filter((n) => n.language === 'nix');
4750 if (optionHits.length > 0) {
4751 const seen = new Set<string>();
4752 const nodes = optionHits.filter((n) => !seen.has(n.id) && !!seen.add(n.id)).slice(0, 10);
4753 return { nodes, note: '' };
4754 }
4755 }
4756 let results = cg.searchNodes(symbol, { limit: 50 });
4757
4758 // Mirror the fallback in `findSymbol` for qualified queries — FTS
4759 // strips colons, so a module-qualified lookup needs a second pass
4760 // by the bare last part.
4761 if (results.length === 0 && /[.\/]|::/.test(symbol)) {
4762 const tail = lastQualifierPart(symbol);
4763 if (tail && tail !== symbol) results = cg.searchNodes(tail, { limit: 50 });
4764 }
4765
4766 if (results.length === 0) {
4767 return { nodes: [], note: '' };
4768 }
4769
4770 const exactMatches = results.filter(r => this.matchesSymbol(r.node, symbol));
4771
4772 if (exactMatches.length <= 1) {
4773 const node = exactMatches[0]?.node ?? results[0]!.node;
4774 return { nodes: [node], note: '' };
4775 }
4776
4777 // Same generated-file down-rank as findSymbol — keeps callers/callees
4778 // /impact aggregation aligned (a query against "Send" returns the
4779 // hand-written implementations before the protobuf scaffold).
4780 const ranked = [...exactMatches].sort((a, b) => {
4781 const aGen = isGeneratedFile(a.node.filePath) ? 1 : 0;
4782 const bGen = isGeneratedFile(b.node.filePath) ? 1 : 0;
4783 return aGen - bGen;
4784 });
4785
4786 const locations = ranked.map(r =>
4787 `${r.node.kind} at ${r.node.filePath}:${r.node.startLine}`
4788 );
4789 const note = `\n\n> **Note:** Aggregated results across ${ranked.length} symbols named "${symbol}": ${locations.join(', ')}`;
4790 return { nodes: ranked.map(r => r.node), note };
4791 }
4792

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