/** * Per-language tree-sitter node-mapping queries. * * The Day 2-3 skeleton defines the *declaration-kind* surface for each * language: which tree-sitter node types map to which `SymbolKind`, and how * to extract the symbol's name from that node. Ref/import/heritage emission * (calls, type references, extends/implements, include paths) landed with * P3.9, where real AST fixtures proved the mapping. * * Why no tree-sitter queries (the `.scm` query language)? * The universal visitor (`visitor.ts`) walks the tree by node-type rather * than running a `.scm` query. A query-based approach would be faster at * very large scale but adds a second AST traversal pattern and a separate * grammar file per language. Direct traversal keeps the code shape aligned * with `ts-parser.ts` and `py-parser.ts` — one recursion, one witness list. * * Each language only needs to fill in the few fields that differ from the * default (see {@link DEFAULT_QUERIES}). The block form in `LANG_QUERIES` * documents the full set of fields exhaustively so the next reader can see * at a glance what a language can override. */ import type { CallType, SymbolKind, SymbolLang } from '../schema.js'; /** * Declarations worth indexing for a language. * * `declKinds` — map of `tree-sitter node.type` → `SymbolKind`. * `nameField` — node field name that carries the identifier; defaults * to `'name'`. Some grammars expose a `declarator` field * that wraps a `pointer_declarator` or `function_declarator`. * `nameExtractor` — optional escape hatch for languages (e.g. Elixir) * whose declaration shape doesn't have a clean `name` field. * `scopeNodes` — node types that push a new scope onto the visitor's * stack. Class/struct/namespace/interface/impl/module. * `skipNamedChildren` — when true, the visitor does not recurse into * named children of a declaration node. Set for languages * where the parent itself is the only indexable unit * (rare; default false). * `refRules` — P3.9: node types that emit cross-references (calls, * imports, heritage). Absent for languages whose grammar * would turn the rule into noise (Elixir's `call` covers * operators; shell has no symbol calls). */ export interface NodeQueries { declKinds: Record; nameField?: Partial>; nameExtractor?: (node: import('web-tree-sitter').Node) => string | null; scopeNodes?: ReadonlySet; skipNamedChildren?: boolean; refRules?: Partial>; /** * Final say on a matched node's kind; `null` skips it. For node types that * are only sometimes declarations: C's `declaration` (prototype, global or * local), a Ruby `constant` (assignment target or mere reference), an * Elixir `call` (`def` or any call at all). */ resolveKind?: (node: import('web-tree-sitter').Node, kind: SymbolKind) => SymbolKind | null; /** * Names for nodes that declare several (`int a, b;`) or whose name is not an * identifier child. `undefined` falls back to single-name extraction. */ declaredNames?: (node: import('web-tree-sitter').Node) => readonly string[] | undefined; /** Scope membership decided per node; replaces `scopeNodes` when set. */ isScopeNode?: (node: import('web-tree-sitter').Node) => boolean; } /** One ref a refRule wants emitted. `callType` defaults to the rule's. */ export interface RefEmission { toName: string; callType?: CallType; module?: string; } /** * How to turn one tree-sitter node into refs. * * `callType` — the ref kind this rule emits. * `field` — field carrying the callee/target (e.g. `'function'`). * Default when no extractor: leaf-name of that field. * `nameExtractor` — full control (multi-ref nodes like heritage lists, * imports whose module must be derived from the node * text, Ruby `require` calls). Return `null`/`[]` to * emit nothing for this node. */ export interface RefRule { callType: CallType; field?: string; nameExtractor?: (node: import('web-tree-sitter').Node) => ReadonlyArray | null; } /** Resolve the queries for a language, falling back to the default. */ export declare function getQueries(lang: SymbolLang): NodeQueries; //# sourceMappingURL=queries.d.ts.map