/** * CodeGraph * * Wraps a CircleIR and provides lazily-computed indexes over its graph data. * Built once per file analysis. All analysis passes consume it — none * rebuild their own lookup maps. * * Design invariants: * - `ir` is readonly; CodeGraph never mutates the underlying CircleIR. * - All indexes are computed once on first access (null-check lazy init). * - No platform-specific APIs: browser + Node.js + Cloudflare Workers safe. */ import type { CircleIR, CFGBlock, DFGDef, DFGUse, DFGChain, CallInfo, TypeInfo, TaintSanitizer } from '../types/index.js'; import type { MethodInfo } from '../types/index.js'; export declare class CodeGraph { readonly ir: CircleIR; constructor(ir: CircleIR); private _defById; get defById(): Map; private _defsByLine; get defsByLine(): Map; private _defsByVar; get defsByVar(): Map; private _usesByLine; get usesByLine(): Map; private _usesByDefId; get usesByDefId(): Map; private _chainsByFromDef; get chainsByFromDef(): Map; /** * Mirror of chainsByFromDef keyed by chain.to_def. Enables backward * walks from a use's reaching def to earlier defs in the chain * (cognium-dev #238 — DFG-walk sanitizer credit). */ private _chainsByToDef; get chainsByToDef(): Map; private _callsByLine; get callsByLine(): Map; private _callsByMethod; get callsByMethod(): Map; private _methodsByName; get methodsByName(): Map>; /** * Returns the TypeInfo + MethodInfo whose line range contains `line`, or null. * Used by passes that need the enclosing method context for a given line. */ methodAtLine(line: number): { type: TypeInfo; method: MethodInfo; } | null; private _sanitizersByLine; get sanitizersByLine(): Map; /** All DFGDefs at a given line. Returns [] if none. */ defsAtLine(line: number): DFGDef[]; /** All DFGUses at a given line. Returns [] if none. */ usesAtLine(line: number): DFGUse[]; /** All DFGUses that reach a specific definition ID. Returns [] if none. */ usesOfDef(defId: number): DFGUse[]; /** All CallInfos at a given line. Returns [] if none. */ callsAtLine(line: number): CallInfo[]; /** DFGChains outgoing from a definition ID. Returns [] if none. */ chainsFrom(defId: number): DFGChain[]; /** * All definitions of `variable` that appear strictly after `afterLine` * and at or before `upToLine`. Used to detect whether a variable is * redefined between a taint source and a sink. */ laterDefsOfVar(variable: string, afterLine: number, upToLine: number): DFGDef[]; private _blockById; get blockById(): Map; /** * Returns the line range of each detected loop body in the file. * * A loop is identified by CFG back-edges (type = "back"). For each back edge * `A → B`, B is the loop header and A is the last block before the back-jump. * The loop body spans from `header.start_line` to `A.end_line` (inclusive). * * Returns `{ start_line, end_line }` — one entry per back-edge. * Overlapping ranges are returned separately; callers can merge as needed. * * Usage: check whether line L is inside any loop with * `graph.loopBodies().some(r => L >= r.start_line && L <= r.end_line)` */ loopBodies(): Array<{ start_line: number; end_line: number; }>; /** * Propagate a set of tainted definition IDs through DFGChains to a fixpoint. * * Returns a new Set (does not mutate the input). Each chain edge * `from_def → to_def` spreads taint: if `from_def` is tainted, `to_def` * becomes tainted. Iterates until no new IDs are added. */ propagateTaintedDefIds(seed: Set): Set; } //# sourceMappingURL=code-graph.d.ts.map