/** * Intra-procedural control-flow & data-flow overlay (spec: add-intraprocedural-cfg-dataflow-overlay). * * Builds, per function and purely from AST shape (no types, no inference, no LLM): * 1. a control-flow graph (CFG): basic blocks + the edges induced by branches, * loops, early exits (return/break/continue/throw), computed while the parse * tree is live (parse trees are freed before later analysis passes); * 2. a reaching-definitions (def-use) overlay over that CFG: a deterministic * fixpoint producing data-dependence edges from each definition site to each * use it reaches without an intervening reassignment. * * Every data-dependence edge carries a precision label: `exact` for a sound * local-scalar def-use, `may` for a conservatively over-approximated dependence * (object field, array/dict element, closure capture). The cross-call `may` hop * is synthesized by the value-level consumer, not here — this overlay is strictly * intra-procedural. * * The returned {@link FunctionCfg} holds ONLY primitive data (numbers, strings): * no AST node references survive the call, so it is WASM-tree-lifetime safe and * trivially serializable to the disposable SQLite store. * * Modeled on the Elixir `walk` closure precedent in call-graph.ts — the first * real statement-level AST visitor in the analyzer. */ /** Precision provenance of a single data-dependence edge. */ export type DataFlowPrecision = 'exact' | 'may'; /** Kind of a basic block, for branch/loop/exit classification. */ export type CfgBlockKind = 'entry' | 'exit' | 'normal' | 'branch' | 'loop' | 'merge'; /** Kind of a control-flow edge between two blocks. */ export type CfgEdgeKind = 'normal' | 'true' | 'false' | 'back' | 'exit'; export interface CfgBlock { /** Index into FunctionCfg.blocks; stable within one CFG. */ id: number; kind: CfgBlockKind; } export interface CfgEdge { from: number; to: number; kind: CfgEdgeKind; } /** * A data-dependence (def-use) edge: the value assigned to `variable` at line * `defLine` reaches the read at line `useLine` without an intervening * reassignment. `precision` is a deterministic property of the analysis. */ export interface DefUseEdge { variable: string; defLine: number; useLine: number; precision: DataFlowPrecision; /** * When this use is the RHS of an assignment/declaration, the start line of the * variable it helps define. Lets a forward value slice chain through multi-line * initializers (e.g. `const ctx = {\n x: p,\n}`) where the feeding use and the * resulting def sit on different physical lines. Absent for non-feeding uses. */ useInDefLine?: number; } /** Compact per-function overlay record. Pure data — no AST nodes retained. */ export interface FunctionCfg { blocks: CfgBlock[]; edges: CfgEdge[]; /** Reaching-definitions def-use edges over the CFG. */ defUse: DefUseEdge[]; /** Parameter names, treated as definitions at function entry. */ params: string[]; /** 1-based line at which parameters are considered defined (function start). */ paramLine: number; } /** * Structural subset of tree-sitter's SyntaxNode used by the visitor. Native * `Parser.SyntaxNode` satisfies this; keeping it minimal avoids coupling to the * concrete parser type and keeps the visitor testable. */ export interface CfgNode { type: string; text: string; startIndex: number; endIndex: number; startPosition: { row: number; }; namedChildren: CfgNode[]; /** All children incl. anonymous tokens. Optional — the soft-loaded (spec-08) * node interface exposes only namedChildren. */ children?: CfgNode[]; childForFieldName(field: string): CfgNode | null; } /** Languages for which CFG construction is implemented (spec v1 scope). */ export declare function cfgSupportsLanguage(language: string): boolean; /** * Build the per-function CFG + reaching-definitions overlay from a function's * AST node, while its parse tree is live. Returns undefined for an unsupported * language or a function with no usable body (fail-soft — never throws). * * @param fnNode The function/method declaration node. * @param language Source language (TypeScript/JavaScript/Python/Go in v1). */ export declare function buildFunctionCfg(fnNode: CfgNode, language: string): FunctionCfg | undefined; /** * Structural invariants every emitted overlay must satisfy. A violation means a * builder bug or grammar drift produced a malformed CFG; returning false makes * {@link buildFunctionCfg} emit no overlay rather than wrong context. Cheap, * linear, and run on every function. Exported for the invariant test. */ export declare function isStructurallyValid(cfg: FunctionCfg): boolean; /** * Forward data-flow slice: the set of source lines a value reaches through * def-use edges within one function (a Weiser forward slice = the value's impact * set). Seeds from `target` (a parameter or local variable name) or, when * omitted, from every parameter. Propagates through chained assignments: a line * that defines a variable from a tainted read becomes tainted itself. * * Used by the value-level opt-in on `analyze_impact`/`trace_execution_path` to * narrow downstream results to the calls whose arguments are data-dependent on * the targeted value. Over-approximating (line-granular for chained defs) and * therefore sound toward "may affect". */ export declare function valueReachableLines(cfg: FunctionCfg, target?: string): Set; //# sourceMappingURL=cfg.d.ts.map