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

Method matchesSymbol

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

4400 * Python — `stage_apply::run` matches a `run` in `stage_apply.rs`)
4401 */
4402 private matchesSymbol(node: Node, symbol: string): boolean {
4403 // Simple name match
4404 if (node.name === symbol) return true;
4405 // File basename match (e.g., "product-card" matches "product-card.liquid")
4406 if (node.kind === 'file' && node.name.replace(/\.[^.]+$/, '') === symbol) return true;
4407
4408 // Qualified-name lookups: split on any supported separator. `\w` keeps
4409 // identifier chars (incl. `_`) intact; everything else is treated as
4410 // a separator we tolerate.
4411 if (!/[.\/]|::/.test(symbol)) return false;
4412 const parts = symbol.split(/::|[./]/).filter((p) => p.length > 0);
4413 if (parts.length < 2) return false;
4414
4415 const lastPart = parts[parts.length - 1]!;
4416 if (node.name !== lastPart) return false;
4417
4418 // Stage 1: qualified-name suffix match. The extractor joins the
4419 // semantic hierarchy with `::`, so `Session.request` and
4420 // `Session::request` both become `Session::request` here.
4421 const colonSuffix = parts.join('::');
4422 if (node.qualifiedName.includes(colonSuffix)) return true;
4423
4424 // Stage 2: file-path containment. Rust modules and Python packages
4425 // are not in `qualifiedName` — they're encoded in the file path. So
4426 // `stage_apply::run` matches a `run` in any file whose path
4427 // contains a `stage_apply` segment (with or without an extension).
4428 //
4429 // Filter out Rust path prefixes that have no file-system equivalent.
4430 const containerHints = parts.slice(0, -1).filter((p) => !RUST_PATH_PREFIXES.has(p));
4431 if (containerHints.length === 0) return false;
4432
4433 const segments = node.filePath.split('/').filter((s) => s.length > 0);
4434 return containerHints.every((hint) =>
4435 segments.some((seg) => seg === hint || seg.replace(/\.[^.]+$/, '') === hint)
4436 );
4437 }
4438
4439 /**
4440 * 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