searchByType
uses node:path
Terms whose type has the query's shape. Codebase types in the query are found by name; names that aren't types become type variables. Exact matches (up to renaming) come first, then ones with arguments reordered, a Promise result, or a more general or more specific type.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import { MAX_MATCH_COST } from "#codebase/tcmts/cli/search"; import type { TypeHit } from "#codebase/tcmts/cli/search"; import { matchShapes, queryShape } from "#codebase/tcmts/core/shape"; import path_1 from "node:path"; export function searchByType(cb: Codebase, text: string): { variables: string[]; hits: TypeHit[] } { if (!text.trim()) throw new Error("find :<type>, e.g. tcm find ':(xs: T[]) => T'"); const names = cb.store.names(); const types = names.filter((n) => n.kind !== "term"); const resolve = (name: string) => { const hits = types.filter((n) => n.path === name || n.path.endsWith(`.${name}`)); const exact = hits.filter((n) => n.path === name); const paths = [...new Set((exact.length ? exact : hits).map((n) => n.path))]; if (paths.length > 1) throw new Error( `'${name}' in the query could be ${paths.join(", ")}; write the one you mean`, ); if (!paths.length) return undefined; const segs = paths[0]!.split("."); return { module: ["#codebase", ...segs.slice(0, -1)].join("/"), export: segs.at(-1)! }; }; cb.refreshShim(); const q = queryShape(text, path_1.join(cb.lay.tcmDir, "query.ts"), cb.compilerOptions(), resolve); const terms = names.filter((n) => n.kind === "term"); // (received code comes without shapes: worked out the first time a search needs them) cb.fillShapes(terms.map((n) => n.hash)); const hits = terms .map((n) => { const def = cb.store.getDef(n.hash)!; const m = def.shape ? matchShapes(q.shape, def.shape) : undefined; return m && m.cost <= MAX_MATCH_COST ? { path: n.path, hash: n.hash, signature: cb.store.shownSignature(def), cost: m.cost, notes: m.notes, } : undefined; }) .filter((h): h is TypeHit => !!h) .sort((a, b) => a.cost - b.cost || (a.path < b.path ? -1 : 1)); return { variables: q.variables, hits }; }
uses
- tcmts.cli.codebase.Codebase
- tcmts.cli.search.MAX_MATCH_COST
- tcmts.cli.search.TypeHit
- tcmts.core.shape.matchShapes
- tcmts.core.shape.queryShape