import type { AgencyProgram } from "../types.js"; import type { SymbolTable } from "../symbolTable.js"; export type PropagationNode = { effects: string[]; /** Keys into the same dictionary. What a key means is the caller's business: * the type checker uses local names, the cross-file pass uses file-and-name * pairs. */ calleeKeys: string[]; }; /** * Give every entry the effects of everything it calls, until nothing more can * be learned. * * Worklist rather than repeated full sweeps. Sweeping was measurably quadratic: * on a chain of N functions where only the last one raises, each sweep moves * the effect one link, so it takes N sweeps of N entries. Re-queueing only the * callers of an entry that grew makes the work proportional to the call edges * instead. See lib/perf/symbolTable.perf.test.ts, which measures the chained * shape specifically because that is where the difference shows. * * Terminates because effect lists only grow and the label set is finite, so an * entry can be re-queued only finitely often. Returns the object it was given, * so a caller can read the result as a value rather than relying on call order. */ export declare function propagateToFixpoint(nodes: Record): Record; /** Where a name is really defined, after renaming and re-export. */ export type Origin = { file: string; name: string; }; /** * Make each callable's recorded effects include everything it can reach by * calling, not just what its own body raises. * * Runs once at the end of SymbolTable.build, over the parse trees the crawl * already produced. Before this existed, an imported function arrived at the * type checker as a leaf: `h` wrapping `read` reported nothing, and so did * `agency policy gen` for a program that reads your filesystem through it. * GitHub issue 680. */ export declare function propagateEffects(table: SymbolTable, programs: Record): void; /** * Follow `reExportedFrom` to where a name is really defined. A barrel can * re-export a barrel, so this repeats. * * No depth guard: SymbolTable.build already detects a re-export cycle and * throws with the chain in the message, before this runs. */ export declare function originOf(table: SymbolTable, at: Origin): Origin; /** * Every name this file can call: the functions and nodes it declares, plus * every imported name that resolves to one. * * The file's own symbols are not enough — `read` reaches a file through the * injected prelude import, so a check that only looked locally would decide * `read` is not callable. */ export declare function callableNamesIn(table: SymbolTable, program: AgencyProgram, file: string): string[]; /** * Every function the given one can reach by calling, itself included. * * Scoped by call graph rather than by file on purpose. Every file reaches the * prelude and passing a function as a value is ordinary Agency, so a * file-scoped rule would refuse every generator ever written. */ export declare function reachableFrom(table: SymbolTable, programs: Record, start: Origin): Origin[];