/** * Method bodies read straight from the symbol index. * * The readers resolve a method body bridge-first, then by parsing the object's * XML off disk. Both of those are Windows-VM facilities, so on an Azure * `read-only` deployment every body request fell through to "not found" — while * the answer sat in the database the whole time. Measured on a production-size * index (2.0 GB, `data/xpp-metadata.db`): 620,851 method rows, 100% of them with * a non-empty `source`, averaging 763 characters against the 331-character * `source_snippet` preview that `find_references` had been limited to. * * `source` is written at index time for every method-owning type — classes * (509k), tables (93k), forms (46k), views, queries, reports — by the indexer's * addSymbol call, and until now exactly one caller read it back, on the WRITE * path (`resolveReferences.findMethod`). These helpers give the read path the * same access. * * This is a FALLBACK, never a primary: the index is a snapshot built by a * pipeline, so the bridge and the on-disk XML both see newer state and both * still run first. It answers where they cannot reach at all. * * Index safety: `parent_name = ? AND type = 'method' AND name = ? COLLATE * NOCASE` plans as `SEARCH symbols USING INDEX idx_type_parent (type=? AND * parent_name=?)` — measured, not assumed. `idx_parent_type_name` carries the * same two columns plus `name`, but its `name` column is BINARY, so a NOCASE * comparison cannot seek on it and the third column buys nothing; the planner * picks either index for the (type, parent) equality and filters the rest. * * That is what makes this safe: the NOCASE compare runs over one owner's method * rows (222 on `CustTable`, 621 on `SalesTable` — the widest shape in the * index), never over all 639k. Callers are still expected to canonicalize the * OWNER name first (see `canonicalSymbolName`), since a NOCASE compare on * `parent_name` itself has no index to narrow it and WOULD scan every row. */ import type { DbLike } from './symbolLookup.js'; export interface IndexedMethodSource { /** The AOT's own spelling of the method name, not the caller's casing. */ name: string; source: string; signature: string | null; model: string | null; } /** * One method body from the index, or null when the row is absent or predates * the `source` column. * * A database built before `source` was added answers NULL for every row (the * column is additive — see the migration list in symbolIndex.ts), which is * "not indexed yet", not "empty method". Both collapse to null here so callers * fall through to their existing not-found path rather than rendering a blank * code fence. */ export declare function readIndexedMethodSource(db: DbLike, ownerName: string, methodName: string): IndexedMethodSource | null; /** * Indexed method bodies for one owner, keyed by lowercased method name. * * One statement for the whole set, because a per-method call would issue one * round trip per method on a class that can carry hundreds. `methodNames` * narrows it to the ones the caller will actually render: a class reader shows * a page of 15, while the owner's full set reaches 510 methods / 1.39 MB (`Tax`) * on the production index — bytes that a synchronous `node:sqlite` read pays for * in event-loop time. Omit it only when the whole set really is wanted. * * The `IN` list compares on the column's own BINARY collation, which is what the * callers want: the names they pass come out of this same table, so they are * already the AOT's spelling. */ export declare function readIndexedMethodSources(db: DbLike, ownerName: string, methodNames?: string[]): Map; /** * The `[SysObsolete]` / `[Obsolete]` banner for a body, or '' when absent. * * Shared so the index path cannot quietly omit the warning that the XML path * emits — the two render the same source text and must agree about it. */ export declare function obsoleteWarning(source: string): string; //# sourceMappingURL=indexedMethodSource.d.ts.map