/** * Class Hierarchy Analysis (CHA) — type-hierarchy-resolved polymorphic dispatch. * (spec: add-type-hierarchy-resolved-dispatch) * * Closes the polymorphic-dispatch blind spot deterministically, from the * `ClassNode` / `InheritanceEdge` hierarchy the call graph already extracts plus * the existing type-inference engine — no LLM, no points-to solve. Classic CHA * (Dean, Grove, Chambers, ECOOP 1995): resolve a virtual call `recv.m()` to the * implementations of `m` reachable in the type subtree of `recv`'s type. * * Two additive, provenance-labeled edge kinds, both `confidence: 'synthesized'`: * * - **Virtual-dispatch** (`kind: 'calls'`): from an unpinned `recv.m()` call site * to each implementation of `m` in `recv`'s subtree. Labeled `cha-declared-type` * when the receiver type was statically recovered (so the target set is narrowed * to that type's subtree) and `cha-name-only` when it was not (a deliberately * weaker over-approximation: every implementation of `m` by method NAME across the * whole hierarchy — the call site's argument count is not recovered, so no arity * narrowing is applied here). * - **Override** (`kind: 'overrides'`): from a base method `B.m` to every overriding * `D.m` where `D <: B` and both declare `m` with compatible arity. The precise, * consistent replacement for the legacy class-level N×M adjacency cross-product. * * Bias is false-negatives over false-positives: a virtual-dispatch edge is emitted * only when `m` resolves to ≥1 implementation in the user-defined hierarchy (external * / stdlib types are not in it and never resolve); per-call-site fan-out is capped and * over-cap call sites are dropped (not partially wired) and logged. */ import type { FunctionNode, ClassNode, InheritanceEdge, CallEdge } from './call-graph.js'; import type { ImportMap } from './import-resolver-bridge.js'; /** Per-call-site / per-base-method target fan-out cap — mirrors the dynamic-dispatch bound. */ export declare const CHA_FANOUT_CAP = 8; /** A receiver-based method call recovered from the raw edges: `recv.method(...)`. */ export interface RawMethodCall { callerId: string; /** Receiver variable/expression name (`recv` in `recv.m()`); `self`/`this`/`cls` allowed. */ recv: string; /** Method name `m`. */ method: string; line: number; } /** * Extract a parameter count from a function declaration signature. Returns * `undefined` when no parameter list is recoverable, in which case arity is * treated as compatible with anything (we never *drop* a real override for an * unparseable signature — false-negative bias). */ export declare function arityFromSignature(signature: string | undefined): number | undefined; /** * Run the CHA synthesis pass: override edges + virtual-dispatch edges. Additive — * returns only new edges, never modifies the directly-resolved graph. Per-rule and * order-independent; a failure in one rule must not abort the other or the build. */ export declare function synthesizeTypeHierarchyEdges(input: { nodes: Map; classes: ClassNode[]; inheritanceEdges: InheritanceEdge[]; rawMethodCalls: RawMethodCall[]; fileContents: Map; directCalleeIdsByCaller: Map>; /** Per-file import map, so a receiver type NAME shared across files resolves to the * class the caller actually imports (precise dispatch) instead of every same-named class. */ importMap?: ImportMap; }): CallEdge[]; //# sourceMappingURL=cha.d.ts.map