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

Method matchesSymbol

src/mcp/tools.ts:4639–4674  ·  view source on GitHub ↗

* Check if a node matches a symbol query. * * Accepts simple names (`run`) and three flavors of qualifier: * - dotted `Session.request` (TS/JS/Python) * - colon-pair `stage_apply::run` (Rust, C++, Ruby) * - slash `configurator/stage_apply` (path-ish) *

(node: Node, symbol: string)

Source from the content-addressed store, hash-verified

4637 * Python — `stage_apply::run` matches a `run` in `stage_apply.rs`)
4638 */
4639 private matchesSymbol(node: Node, symbol: string): boolean {
4640 // Simple name match
4641 if (node.name === symbol) return true;
4642 // File basename match (e.g., "product-card" matches "product-card.liquid")
4643 if (node.kind === 'file' && node.name.replace(/\.[^.]+$/, '') === symbol) return true;
4644
4645 // Qualified-name lookups: split on any supported separator. `\w` keeps
4646 // identifier chars (incl. `_`) intact; everything else is treated as
4647 // a separator we tolerate.
4648 if (!/[.\/]|::/.test(symbol)) return false;
4649 const parts = symbol.split(/::|[./]/).filter((p) => p.length > 0);
4650 if (parts.length < 2) return false;
4651
4652 const lastPart = parts[parts.length - 1]!;
4653 if (node.name !== lastPart) return false;
4654
4655 // Stage 1: qualified-name suffix match. The extractor joins the
4656 // semantic hierarchy with `::`, so `Session.request` and
4657 // `Session::request` both become `Session::request` here.
4658 const colonSuffix = parts.join('::');
4659 if (node.qualifiedName.includes(colonSuffix)) return true;
4660
4661 // Stage 2: file-path containment. Rust modules and Python packages
4662 // are not in `qualifiedName` — they're encoded in the file path. So
4663 // `stage_apply::run` matches a `run` in any file whose path
4664 // contains a `stage_apply` segment (with or without an extension).
4665 //
4666 // Filter out Rust path prefixes that have no file-system equivalent.
4667 const containerHints = parts.slice(0, -1).filter((p) => !RUST_PATH_PREFIXES.has(p));
4668 if (containerHints.length === 0) return false;
4669
4670 const segments = node.filePath.split('/').filter((s) => s.length > 0);
4671 return containerHints.every((hint) =>
4672 segments.some((seg) => seg === hint || seg.replace(/\.[^.]+$/, '') === hint)
4673 );
4674 }
4675
4676 /**
4677 * Find ALL definitions matching a name, ranked, so codegraph_node can return

Callers 2

findSymbolMatchesMethod · 0.95
findAllSymbolsMethod · 0.95

Calls 2

hasMethod · 0.80
joinMethod · 0.45

Tested by

no test coverage detected