This page is the authoritative reference for the core graph types of
libcpg — the CodePropertyGraph
container, its nodes and edges, and the identifier, location, language, and
error types that surround them. Every signature below is transcribed from
src/graph/ (and the crate-root re-exports in src/lib.rs); nothing here is
aspirational.
If you are looking for how graphs are built, see the Builder reference; for how they are analyzed (matching, similarity, GoF, algorithms, GNN) see the Pattern reference. Conceptual definitions of every term live in the Glossary.
Figure — the four overlays of a CPG share one node set; each edge kind projects a different program view. Source: diagrams/cpg-overlay.dot.
Every type on this page is re-exported from the crate root, so a single use
suffices:
use libcpg::{
CodePropertyGraph, CpgStats, CpgEdges, CfgNeighbors, DfgNeighbors,
CpgNode, CpgNodeKind, CpgNodeKindTag, LiteralKind,
CpgEdge, CpgEdgeKind, CfgEdgeKind, DfgEdgeKind,
NodeId, EdgeId, SourceRange,
Language, Paradigm,
TypeInfo, MethodSignature, Visibility, ScopeId,
PropertyKey, PropertyValue,
Error, Result,
};They also remain reachable at their defining paths (libcpg::graph::…), but the
root re-exports are canonical.
The central container. It is not a bag of vectors: it wraps a
petgraph DiGraph<CpgNode, CpgEdge>, one FxHashMap
that translates stable NodeId values into petgraph's internal NodeIndex,
and a lazy exact-edge projection cache. All fields are private; you interact
through the methods below.
pub struct CodePropertyGraph { /* private: DiGraph + node index + lazy edge cache + metadata */ }Besides the topology it records: the Language it was built for, an
optional source path and retained source string, the AST root node, and the
CFG entry/exit node lists.
| Method | Signature | Notes |
|---|---|---|
new |
fn new(language: Language) -> Self |
Empty graph for language. |
with_source_path |
fn with_source_path(self, path: impl Into<Arc<str>>) -> Self |
Records the source file path. |
with_source_code |
fn with_source_code(self, code: impl Into<Arc<str>>) -> Self |
Retains the source string (opt-in; off by default). |
language |
fn language(&self) -> Language |
The graph's language. |
source_path |
fn source_path(&self) -> Option<&str> |
The recorded path, if any. |
source_code |
fn source_code(&self) -> Option<&str> |
The retained source, if any. |
root |
fn root(&self) -> Option<NodeId> |
The AST root (the first node added). |
node_count |
fn node_count(&self) -> usize |
Number of nodes. |
edge_count |
fn edge_count(&self) -> usize |
Number of edges. |
CodePropertyGraph also implements Clone, Debug, and Default (a Default
graph has Language::Unknown).
| Method | Signature | Notes |
|---|---|---|
add_node |
fn add_node(&mut self, node: CpgNode) -> NodeId |
Assigns a fresh NodeId, overwriting node.id. Sets root if this is the first node. |
add_node_with_id |
fn add_node_with_id(&mut self, node: CpgNode) -> NodeId |
Keeps node.id (for reconstruction from serialized data). |
node |
fn node(&self, id: NodeId) -> Option<&CpgNode> |
Look up a node. Returns Option, not Result. |
node_tag |
fn node_tag(&self, id: NodeId) -> Option<CpgNodeKindTag> |
Copy the complete one-byte variant tag without cloning the kind's payload. |
node_mut |
fn node_mut(&mut self, id: NodeId) -> Option<&mut CpgNode> |
Mutable lookup. |
contains_node |
fn contains_node(&self, id: NodeId) -> bool |
Membership test. |
nodes |
fn nodes(&self) -> impl Iterator<Item = &CpgNode> |
Iterate all nodes. |
node_ids |
fn node_ids(&self) -> impl Iterator<Item = NodeId> + '_ |
Iterate all node ids. |
merge_from |
fn merge_from(&mut self, other: &CodePropertyGraph) -> FxHashMap<NodeId, NodeId> |
Appends a collision-free copy in sorted source-id order and returns the complete source-to-destination map. |
There is no
remove_node/remove_edge: a CPG is built once and analyzed; extraction stages add overlay edges rather than mutate topology in place.
The stable-id domain includes u32::MAX. Explicit reconstruction may insert
that maximum id. Once the monotonic allocator reaches an already-assigned
maximum, a subsequent automatic node insertion panics rather than wrapping and
aliasing an existing node. Applications admitting hostile reconstructed graphs
should enforce an aggregate node/edge limit far below the identity ceiling.
CpgNodeKind::tag() -> CpgNodeKindTag and the graph-level node_tag accessor
classify all 45 variants one-to-one. They are intended for control-flow
dispatch that needs no variant payload, particularly when a copied tag lets a
caller release its immutable node borrow before mutating the graph. This
complete tag is distinct from libcpg::pattern::NodeKindTag: the pattern tag is
an intentionally coarser 29-way vocabulary that maps unsupported template
kinds to Unknown.
| Method | Signature | Notes |
|---|---|---|
add_edge |
fn add_edge(&mut self, edge: CpgEdge) -> Option<EdgeId> |
Assigns a fresh EdgeId. None if either endpoint is absent. |
add_edge_with_id |
fn add_edge_with_id(&mut self, edge: CpgEdge) -> Option<EdgeId> |
Keeps edge.id (reconstruction). |
connect |
fn connect(&mut self, source: NodeId, target: NodeId, kind: CpgEdgeKind) -> Option<EdgeId> |
Convenience constructor + insert. Returns None if an endpoint is missing. |
edges_between |
fn edges_between(&self, source: NodeId, target: NodeId) -> CpgEdges<'_> |
Allocation-free exact-size view of all parallel edges from source to target. |
edges |
fn edges(&self) -> impl Iterator<Item = &CpgEdge> |
Iterate all edges. |
There is no edge(id) accessor; look edges up by endpoint with edges_between,
outgoing_edges, or incoming_edges.
EdgeId::new(u32::MAX) is likewise representable during reconstruction; after
the monotonic allocator reaches an already-assigned maximum, the next automatic
insertion panics rather than wrapping. Rejected insertions with a missing
endpoint do not change topology or invalidate an already-valid projection
cache.
Because petgraph iterates outgoing edges newest-first, insertion maintains a
separate child index in ascending EdgeId order. ast_children borrows that
index directly, with no scan, allocation, or sort. This preserves true
source order — analyses rely on, e.g., an If's children being
[condition, then, else] — and returns &[] for an unknown node. Explicit-id
reconstruction reorders the index by EdgeId, independent of edge storage
order.
| Method | Signature | Notes |
|---|---|---|
ast_children |
fn ast_children(&self, id: NodeId) -> &[NodeId] |
Borrowed children in source order; empty for an unknown node. |
ast_parent |
fn ast_parent(&self, id: NodeId) -> Option<NodeId> |
Reads the node's parent pointer. |
ast_descendants |
fn ast_descendants(&self, id: NodeId) -> Vec<NodeId> |
Depth-first descendants. |
ast_ancestors |
fn ast_ancestors(&self, id: NodeId) -> Vec<NodeId> |
Chain toward the root. |
CFG edges carry a CfgEdgeKind; the successor/predecessor
accessors return the neighbour paired with the edge kind, so a caller can branch
on, e.g., ConditionalTrue vs LoopBack.
| Method | Signature | Notes |
|---|---|---|
cfg_successors |
fn cfg_successors(&self, id: NodeId) -> CfgNeighbors<'_> |
Allocation-free outgoing control flow in deterministic target/edge-id order. |
cfg_predecessors |
fn cfg_predecessors(&self, id: NodeId) -> CfgNeighbors<'_> |
Allocation-free incoming control flow in deterministic source/edge-id order. |
cfg_entries |
fn cfg_entries(&self) -> &[NodeId] |
Function entry nodes. |
cfg_exits |
fn cfg_exits(&self) -> &[NodeId] |
Recorded exit nodes. |
add_cfg_entry |
fn add_cfg_entry(&mut self, id: NodeId) |
Register an entry (dedup). |
add_cfg_exit |
fn add_cfg_exit(&mut self, id: NodeId) |
Register an exit (dedup). |
cfg_nodes |
fn cfg_nodes(&self) -> impl Iterator<Item = &CpgNode> |
Nodes with any incident CFG edge. |
| Method | Signature | Notes |
|---|---|---|
reaching_definitions |
fn reaching_definitions(&self, use_site: NodeId) -> Vec<NodeId> |
Definitions reaching use_site (incoming DefUse/ReachingDef). |
uses_of_definition |
fn uses_of_definition(&self, def: NodeId) -> Vec<NodeId> |
Uses reached by def (outgoing DefUse). |
dfg_successors |
fn dfg_successors(&self, id: NodeId) -> DfgNeighbors<'_> |
Allocation-free outgoing data flow in deterministic target/edge-id order. |
dfg_predecessors |
fn dfg_predecessors(&self, id: NodeId) -> DfgNeighbors<'_> |
Allocation-free incoming data flow in deterministic source/edge-id order. |
See reaching definitions for the semantics these edges encode.
| Method | Signature | Notes |
|---|---|---|
call_sites |
fn call_sites(&self, function: NodeId) -> Vec<NodeId> |
Call nodes in function's subtree. |
callees |
fn callees(&self, call_site: NodeId) -> Vec<NodeId> |
Targets via CallSite/StaticCall/DynamicCall. |
callers |
fn callers(&self, function: NodeId) -> Vec<NodeId> |
Call sites that reach function. |
nodes_by_kind takes a predicate over the kind, not a kind value — there is
no nodes_of_kind(kind).
| Method | Signature | Notes |
|---|---|---|
functions |
fn functions(&self) -> impl Iterator<Item = &CpgNode> |
All Function nodes. |
classes |
fn classes(&self) -> impl Iterator<Item = &CpgNode> |
All Class nodes. |
variables |
fn variables(&self) -> impl Iterator<Item = &CpgNode> |
All Variable nodes. |
calls |
fn calls(&self) -> impl Iterator<Item = &CpgNode> |
All Call nodes. |
nodes_by_kind |
fn nodes_by_kind<F: Fn(&CpgNodeKind) -> bool>(&self, predicate: F) -> impl Iterator<Item = &CpgNode> |
Filter by a kind predicate. |
| Method | Signature | Notes |
|---|---|---|
node_at_offset |
fn node_at_offset(&self, offset: u32) -> Option<&CpgNode> |
Smallest node covering a byte offset. |
nodes_in_range |
fn nodes_in_range(&self, range: SourceRange) -> Vec<&CpgNode> |
Nodes overlapping a range. |
scope_at_offset |
fn scope_at_offset(&self, offset: u32) -> Option<&CpgNode> |
Innermost Block/Function at an offset. |
| Method | Signature | Notes |
|---|---|---|
outgoing_edges |
fn outgoing_edges(&self, id: NodeId) -> CpgEdges<'_> |
Allocation-free exact-size view of all outgoing edges. |
incoming_edges |
fn incoming_edges(&self, id: NodeId) -> CpgEdges<'_> |
Allocation-free exact-size view of all incoming edges. |
edges_by_kind |
fn edges_by_kind<F: Fn(&CpgEdgeKind) -> bool>(&self, predicate: F) -> impl Iterator<Item = &CpgEdge> |
Filter edges by a kind predicate. |
CpgEdges, CfgNeighbors, and DfgNeighbors are borrowed, cloneable,
double-ended, exact-size iterators. is_empty, len, iter, and ordinary
iterator combinators do not allocate. CFG/DFG views additionally provide
to_vec() for callers that need ownership before mutating the graph. The first
cached traversal after construction or mutation builds deterministic
compressed-sparse-row (CSR) indices; subsequent reads borrow their rows. See
ADR-0056 for the
invalidation and ordering contract.
| Method | Signature | Notes |
|---|---|---|
ast_depth |
fn ast_depth(&self) -> usize |
Longest root-to-leaf AST path. |
cyclomatic_complexity |
fn cyclomatic_complexity(&self) -> usize |
McCabe's metric over the CFG (below). |
stats |
fn stats(&self) -> CpgStats |
Aggregate counts (see CpgStats). |
cyclomatic_complexity computes McCabe's metric [2]
where cfg_nodes().count()); when there are no CFG nodes it returns
The feature-free program API combines independently built file CPGs without colliding their local identifiers:
| Function | Signature | Result |
|---|---|---|
merge_programs |
fn(Vec<CodePropertyGraph>) -> ProgramCpg |
Unified append-only CPG plus one ordered FileScope per input. |
build_import_graph |
fn(&mut ProgramCpg) -> ImportGraph |
Ordered exact/ambiguous/external evidence plus idempotent Imports/Exports overlays. |
FileScope retains path, source, language, translated root, sorted member
nodes, and its node_map. ImportResolution records the matched alias,
candidate files, and selected declarations. Exact declaration-level Imports
edges carry the symbol's local binding as their label, so renamed imports feed
ExactViaImport correctly. See the complete
program-composition component guide
and usage guide.
The feature-free resolver turns parsed call syntax into definite call topology
only when one target is uniquely supported. It is exported from the crate root
and libcpg::analysis:
| Function | Signature | Result |
|---|---|---|
build_symbol_table |
fn(&mut CodePropertyGraph, &ResolveConfig) -> SymbolTable |
Deterministic lexical, represented-import, and global function index; idempotently emits EnclosingScope and ContainedIn. |
resolve_calls |
fn(&mut CodePropertyGraph, &ResolveConfig) -> CallGraphResolution |
Per-call evidence records plus uniquely supported Reference, StaticCall/DynamicCall, and CallSite edges. |
devirtualize consumes C1 records without mutating the CPG:
pub fn devirtualize(
cpg: &CodePropertyGraph,
resolution: &CallGraphResolution,
mode: DevirtualizationMode,
) -> CallGraphResolution| Mode | Evidence | Confidence |
|---|---|---|
Cha |
represented concrete descendants through Inherits/Implements |
ClassHierarchy |
Rta |
CHA types intersected with CpgNode::allocation_type |
RapidType |
Vta |
RTA types intersected with receiver-reaching definition allocations | VariableType |
The returned candidates are sorted and exact for the represented closed-world
mode; target is set only for a singleton; topology_edges is zero. See the
component contract.
ResolveConfig exposes max_scope_depth,
max_candidates_per_name, max_calls, and resolve_methods.
Confidence has ten stable tiers. C1 uses ExactInFile, ExactViaImport,
ExactViaBinding, BareNameUnique, BareNameAmbiguous, External, and
Unresolved; immutable type refinement adds ClassHierarchy, RapidType, and
VariableType. ExactInFile, ExactViaImport, ExactViaBinding,
ClassHierarchy, RapidType, VariableType, and BareNameUnique return
true from creates_topology(), but only the four C1 tiers are materialized by
resolve_calls; devirtualize emits no edges.
CallResolution records callee_name, scope, confidence,
target, retained candidates, the full candidate_count, and
candidates_truncated. CallGraphResolution stores those records in a
BTreeMap<NodeId, CallResolution> and counts newly emitted topology edges,
ambiguous calls, external calls, and unresolved calls. See the complete
call-resolution component guide for
the evidence matrix, ordering and cap contracts, pseudocode, complexity,
examples, and validation.
Names are exact, case-sensitive str values. The table is call-local; the API
does not expose prefix or fuzzy lookup, normalization, a retained global index,
or index invalidation. max_candidates_per_name limits only retained node ids;
candidate_count remains the ambiguity authority. See
Usage 32 and
ADR-0064.
export_datalog(&CodePropertyGraph) -> DatalogFacts is a feature-free,
immutable export of represented graph relations. DatalogFacts
contains typed nodes, edges, ast_child,
cfg, dfg, dependence, call, type, reference, scope,
import/export, and embedded declared-type vectors.
DatalogFacts::souffle_files returns twenty canonical in-memory RFC 4180
tab-separated fact files; consuming Soufflé input directives must set
rfc4180=true and delimiter="\t". It performs no I/O.
DatalogFacts::cpg_edges and
DatalogEdgeFact::to_cpg_edge reconstruct the lossless ordered edge
snapshot. Its generic family/detail columns include
rewrite_dep/dependency_pair and rewrite_dep/critical_conflict when that
typed overlay exists. See Usage 33, the
component contract, and
ADR-0065.
noninterference(&CodePropertyGraph, &SecurityLabels) -> Vec<FlowViolation>
is a feature-free immutable reachability query over represented
DataDependence, exact labeled SDG summary, and ControlDependence edges.
SecurityLabels contains ordered high_sources, low_sinks, and
declassifiers. A declassifier is a hard cut vertex; labels outside the graph
are ignored.
FlowViolationKind distinguishes Explicit, Implicit, and
ExplicitAndImplicit. Each result retains separate canonical shortest
InformationFlowWitness values for the explicit and implicit path classes.
Every InformationFlowStep names its source, target, and
InformationFlowEdgeKind (DataDependence, Summary, or
ControlDependence).
constant_time(&CodePropertyGraph, &BTreeSet<NodeId>) -> Vec<LeakSite>
reports every represented secret-reachable branch edge and IndexAccess node.
LeakSiteKind::ConditionalTrue and ConditionalFalse retain the exact CFG
target; IndexAccess identifies the timing-sensitive index site.
Declassification does not suppress timing evidence.
Both APIs return every represented finding in stable order, mutate no graph state, and use heap-resident queues/parents with constant native call depth. They are advisory: zero findings do not prove source- or machine-level non-interference. See Usage 34, the component contract, ADR-0066, and the security boundary.
The feature-free interprocedural framework evaluates a caller-defined
SummaryDomain over the current resolved call graph:
| Function | Signature | Result |
|---|---|---|
solve_summaries |
fn<D: SummaryDomain>(&CodePropertyGraph, &D, &SccDecomposition, &IfdsCaps) -> IfdsOutput<D> |
Ordered summaries and completeness evidence using the built-in call-site resolver. |
solve_summaries_with_resolver |
fn<D: SummaryDomain>(&CodePropertyGraph, &D, &SccDecomposition, &IfdsCaps, &dyn Fn(NodeId) -> CalleeRef) -> IfdsOutput<D> |
The same fixed point with caller-authoritative external/unresolved resolution. |
SummaryDomain declares an ordered finite Fact, a summary implementing
analysis::ifds::Lattice, seed_facts, and summarize. The crate-root alias
for that lattice is IfdsLattice; the existing root Lattice remains the
block-CFG data-flow trait. SummaryCtx exposes current summaries, the resolver,
and caps without mutating the CPG.
IfdsCaps bounds functions, distinct seed facts per point, scheduler work,
recursive SCC rounds, and default resolver depth. IfdsOutput::is_complete()
requires no IfdsCapEvent and no IfdsIssue. CalleeRef distinguishes
represented Resolved, caller-identified External, and evidence-insufficient
Unresolved calls. See the complete
IFDS/IDE component guide and
usage guide.
The feature-free effect domain specializes the shared summary solver for observable reads/writes, transitive purity, parameter-to-return flow, and scalar return constants:
| Function | Signature | Result |
|---|---|---|
analyze_effects |
fn(&CodePropertyGraph, &SccDecomposition, &IfdsCaps) -> EffectAnalysis |
Ordered summaries plus processed-function, iteration, work, cap, and issue evidence. |
effect_summaries |
fn(&CodePropertyGraph, &SccDecomposition, &IfdsCaps) -> BTreeMap<NodeId, EffectSummary> |
Convenience projection of the summary map; it can be a capped prefix. |
Place::{Global, Param, Field} identifies abstract storage. Purity is ordered
as Pure < ReadsGlobal < WritesGlobal < Impure. EffectSummary also exposes a
64-bit param_to_return mask, const_return, an explicit flat-lattice
const_return_overdefined bit, and truncation/cap flags. Only
EffectAnalysis::is_complete() licenses a negative claim; positive evidence
in a capped result remains useful. Return dependence and scalar folding use
typed heap continuation machines: accepted AST/def-use depth does not grow the
native call stack, while IfdsCaps::{max_call_depth,max_worklist_steps} still
bound logical evidence and work. See the
effect-summary component guide and
usage guide.
The feature-free taint domains consume the same resolved call graph and typed AST/DFG evidence. They never scan retained source text:
| Function | Signature | Result |
|---|---|---|
analyze_taint_report |
fn(&CodePropertyGraph, &CallGraphResolution, &TaintCatalog, &IfdsCaps) -> TaintAnalysis |
Ordered source-to-sink findings, per-function summaries, shared solver evidence, and domain-local cap state. |
analyze_taint |
fn(&CodePropertyGraph, &CallGraphResolution, &TaintCatalog, &IfdsCaps) -> Vec<TaintFlow> |
Convenience finding vector; inspect the report API before making negative claims. |
analyze_null_flows_report |
fn(&CodePropertyGraph, &CallGraphResolution, &IfdsCaps) -> NullAnalysis |
Ordered maybe-null dereference candidates with summaries and completeness evidence. |
analyze_null_flows |
fn(&CodePropertyGraph, &CallGraphResolution, &IfdsCaps) -> Vec<NullFlow> |
Convenience finding vector with the same positive evidence boundary. |
TaintCatalog owns ordered call sources, categorical literal_sources,
sinks, sanitizers, and externals. LiteralSourceRule classifies a typed
LiteralKind category without copying or matching its value.
Rules select call paths with Pattern::{Exact, Segment, Suffix, Substring} and
use open Arc<str> classes; external calls use
ExternalModel::{Passthrough, Havoc, Source, Sink, Sanitizer}. Every finding
retains concrete source/sink ids, optional CWE metadata, confidence, and a
canonical TaintWitness. NullOriginKind distinguishes literal,
uninitialized-variable, and typed nullable-return evidence.
TaintAnalysis::is_complete() and NullAnalysis::is_complete() are the only
licenses for absence claims. The Vec conveniences deliberately preserve
positive findings while omitting that qualification. See the component
guide, usage guide,
and security boundary.
The heap domain consumes typed allocation, null, dereference, exact release, CFG, DFG, and resolved-call evidence. It returns finite separation-logic anti-frames and postconditions plus qualified null-dereference, use-after-free, and leak findings.
pub fn analyze_heap(
cpg: &CodePropertyGraph,
call_graph: &SccDecomposition,
caps: &IfdsCaps,
) -> HeapAnalysis;
pub fn materialize_heap_overlay(
cpg: &mut CodePropertyGraph,
summaries: &BTreeMap<NodeId, HeapSummary>,
) -> Result<usize, HeapOverlayError>;| API or type | Stable contract |
|---|---|
analyze_heap / analyze_heap_with_model |
Default or caller-owned exact release vocabulary with full solver evidence. |
biabduction_summaries |
Ordered summary-map projection; insufficient by itself for a negative claim. |
memory_safety |
Canonical findings; malformed caller-supplied references become capped InvalidSummaryReference evidence. |
HeapAnalysis |
Summary map, solver order/work/SCC rounds, cap events, domain-capped functions, and structural issues. |
HeapSummary |
Anti-frame, postconditions, allocations, composed callees, overlay relations, findings, and local completeness. |
HeapLocation / HeapPredicate |
Parameter or allocation-site abstraction with Valid/Invalid spatial state. |
HeapModel |
Ordered exact full or terminal names treated as release calls. |
materialize_heap_overlay |
Transactional, idempotent append of typed Heap edges over existing nodes. |
HeapOverlayError |
Exact missing source or target; no edge is added on failure. |
All source/graph depth is stored in explicit heap queues, sets, and maps.
Recursive must-invalidate evidence is marked partial. Require
HeapAnalysis::is_complete() before interpreting an empty finding set as a
clean modeled result. See the component
guide, usage
guide, and security
boundary.
The feature-free SDG surface composes PDG, parameter, return, and effect summary evidence without creating a parallel graph:
| Function | Signature | Result |
|---|---|---|
build_summary_edges |
fn(&mut CodePropertyGraph, &BTreeMap<NodeId, EffectSummary>) -> usize |
Number of new DataDependence(label="summary") actual-to-call edges. |
interprocedural_backward_slice |
fn(&CodePropertyGraph, NodeId, &SliceCaps) -> BTreeSet<NodeId> |
Deterministic two-pass predecessor slice. |
interprocedural_forward_slice |
fn(&CodePropertyGraph, NodeId, &SliceCaps) -> BTreeSet<NodeId> |
Deterministic direction-dual successor slice. |
SliceCaps::new(max_nodes, max_call_depth) bounds distinct result nodes and
Parameter/ReturnValue boundary crossings. SUMMARY_EDGE_LABEL is the
stable summary label. Summary construction is append-only and idempotent;
unknown criteria and zero node caps return an empty set. See the
component guide, usage
guide, and security
boundary.
Language frontends attach optional MsgKind metadata to existing CPG nodes;
the feature-free concurrency surface resolves stable Variable identities
through Identifier::definition, DefUse/ReachingDef, and Reference:
| Function | Signature | Result |
|---|---|---|
extract_events |
fn(&CodePropertyGraph) -> BTreeMap<NodeId, Vec<ChannelEvent>> |
Top-level processes and statement sites in NodeId order; unresolved channel evidence remains None. |
channel_report |
fn(&CodePropertyGraph) -> Vec<ChannelFinding> |
Ordered OrphanSend, BlockedRecv, and NondeterministicConsumption evidence. |
ChannelId is the defining Variable NodeId. ChannelEvent carries kind,
optional channel, site, and SourceRange; ChannelFinding carries channel,
sorted process/site ids, and detail. Both functions are read-only and advisory.
See the component guide, usage
guide, and security
boundary.
The frontend records restrictions, fresh binders, quote/drop reflection, and message roles as typed metadata. The analyzer follows definition identity and matched payload scope extrusion without parsing source text.
| Function | Signature | Result |
|---|---|---|
analyze_name_flow |
fn(&CodePropertyGraph) -> NameFlowAnalysis |
Qualified fresh-origin fixed point with default caps. |
analyze_name_flow_with_caps |
fn(&CodePropertyGraph, NameFlowCaps) -> NameFlowAnalysis |
Same analysis with caller-selected origin/relation/match/dependency/work bounds. |
materialize_name_flow_overlay |
fn(&mut CodePropertyGraph, &NameFlowAnalysis) -> Result<usize, NameFlowOverlayError> |
Transactional, idempotent append of seven typed NameFlow relations. |
analyze_deadlock_freedom |
fn(&CodePropertyGraph) -> DeadlockFreedomAnalysis |
Qualified fresh-name report, canonical levels, cyclic channels, and witnesses. |
analyze_deadlock_freedom_with_caps |
fn(&CodePropertyGraph, NameFlowCaps) -> DeadlockFreedomAnalysis |
Same analysis with caller-selected bounds. |
deadlock_freedom |
fn(&CodePropertyGraph) -> Vec<DeadlockWitness> |
Positive cyclic-witness projection; empty is advisory only. |
NameFlowAnalysis retains sorted origins, relations, issues, work, and
communication-match counts. DeadlockFreedomAnalysis adds per-channel equal
capability/obligation ranks when the dependency graph is acyclic, or None
levels and statement-precise ObligationCapability witnesses for cyclic SCCs.
Every source-shaped traversal uses explicit heap worklists. See the component
contract, usage
guide, and security
boundary.
The analyzer consumes normalized MeTTa rule functions already present in the CPG. It does not parse source text. Every term is a flat arena and every traversal, unification, SCC pass, and joinability search uses explicit heap-owned work state.
| Function | Signature | Result |
|---|---|---|
dependency_pairs |
fn(&CodePropertyGraph) -> DpGraph |
Ordered dependency pairs, SCCs, issues, and completeness under default caps. |
dependency_pairs_with_caps |
fn(&CodePropertyGraph, RewriteAnalysisCaps) -> DpGraph |
Same analysis with explicit rule, term, pair, and unification bounds. |
terminates |
fn(&CodePropertyGraph) -> TerminationVerdict |
Polynomial reduction-pair proof, concrete self-loop nontermination witness, or qualified Unknown. |
terminates_with_caps |
fn(&CodePropertyGraph, RewriteAnalysisCaps) -> TerminationVerdict |
Same decision with caller-selected bounds. |
critical_pairs |
fn(&CodePropertyGraph) -> Vec<CriticalPair> |
Positive projection of proven non-joinable critical overlaps; absence alone is not a confluence claim. |
analyze_critical_pairs |
fn(&CodePropertyGraph) -> CriticalPairAnalysis |
Proven conflicts and completeness under default caps. |
analyze_critical_pairs_with_caps |
fn(&CodePropertyGraph, RewriteAnalysisCaps) -> CriticalPairAnalysis |
Same bounded symmetric rewrite search with caller-selected caps. |
materialize_rewrite_dep_overlay |
fn(&mut CodePropertyGraph, &DpGraph, &CriticalPairAnalysis) -> Result<usize, RewriteDepOverlayError> |
Transactional, idempotent append of typed dependency and proven-conflict edges. |
Termination succeeds only when every source rule is weakly oriented and every dependency pair inside a cyclic SCC is strict under one fixed polynomial interpretation. A non-joinable critical pair requires exhaustion of both finite reachable spaces; a cap, unsupported shape, or non-left-linear rule makes the relevant negative claim incomplete. See the component contract, usage guide, and security boundary.
The Rust frontend attaches OwnershipOperationKind and structured reference
flags to existing nodes. The feature-free analyzer reconstructs source places
from DFG/Reference identity and orders advisory evidence with the function's
CFG; it never parses source text.
| Function | Signature | Result |
|---|---|---|
place_capability_graph |
fn(&CodePropertyGraph, NodeId) -> Result<Pcg, AnalysisError> |
Canonical existing-node places, capability relations, and typed issues for one function. |
borrow_check |
fn(&CodePropertyGraph, NodeId) -> Result<Vec<BorrowViolation>, AnalysisError> |
Ordered advisory use-after-move and conflicting-live-borrow witnesses. |
materialize_place_capability_overlay |
fn(&mut CodePropertyGraph, &Pcg) -> Result<usize, PlaceCapabilityOverlayError> |
Transactional, idempotent append of five typed relations. |
PlaceCapabilityEdgeKind::{Move, SharedBorrow, MutableBorrow, SharedReborrow, MutableReborrow} is append-only. Pcg::is_complete() covers represented
source/copy evidence only; it is not compiler borrow-check completeness. Query
materialized edges with place_capability_edges,
place_capability_successors, and place_capability_predecessors. See the
component contract, usage
guide, and security
boundary.
LockKind::{AcquireRead, AcquireWrite, Release} is optional typed metadata on a
Call; LockMode::{Read, Write} appears in witnesses. A frontend or semantic
adapter attaches the operation after resolving the synchronization API. The
analyzer never infers it from a call's source spelling.
| Function | Signature | Result |
|---|---|---|
communication_deadlocks |
fn(&CodePropertyGraph) -> Vec<DeadlockFinding> |
Communication wait-for SCCs followed by conflicting lock-order SCCs, all deterministically ordered. |
DeadlockFinding contains a DeadlockFindingKind, sorted processes, sorted
channel/lock resources, DeadlockWitness values, and explanatory detail.
Communication witnesses preserve waiter/producer/channel and receive/send
sites/ranges. Lock witnesses preserve holder/acquirer/resource/mode evidence,
both acquisition sites/ranges, and an optional interprocedural call site.
The function constructs GraphProjection::External values and reuses
projection_sccs; it is feature-free, read-only, and advisory. See the
component guide, usage
guide, theory,
and security boundary.
may_happen_in_parallel(&CodePropertyGraph) -> MhpRelation recognizes typed
parallel regions (Block plus MsgKind::Spawn) and relates execution sites in
different direct operand subtrees. Direct process roots and wrapper blocks are
both valid operands; nested Function bodies are excluded.
| Item | Contract |
|---|---|
MhpPair |
One canonical unordered pair with first < second. |
MhpRelation::pairs |
Lexicographically sorted, deduplicated canonical pairs. |
MhpRelation::contains(left, right) |
Symmetric membership; self-pairs are false. |
MhpRelation::partners(node) |
Stable iterator over all sites related to node. |
MhpRelation::capped |
True when the public pair ceiling omitted later valid pairs. |
MAX_MHP_PAIRS |
One-million-pair materialization ceiling. |
Execution sites are statement nodes plus Variable, Assignment, Call,
Await, and Yield. The relation is feature-free, read-only, and out of graph.
A capped result contains no false pairs but is incomplete. See the component
guide, usage
guide, theory,
and security boundary.
Both feature-free APIs consume an immutable CPG and a caller-supplied
MhpRelation. They return sorted advisory records without adding graph edges.
| Function | Signature | Result |
|---|---|---|
race_candidates |
fn(&CodePropertyGraph, &MhpRelation) -> Vec<RaceCandidate> |
Exact same-location MHP conflicts containing a write and lacking a common excluding lock. |
atomicity_candidates |
fn(&CodePropertyGraph, &MhpRelation) -> Vec<AtomicityCandidate> |
Adjacent same-location read/write updates split across release/reacquire with represented MHP interference. |
| Type | Stable fields/meaning |
|---|---|
ConcurrentAccessKind |
Read, Write, or ReadWrite; reads()/writes() expose the conflict bits. |
HeldLock |
Exact resource, LockMode, acquisition site, and acquisition SourceRange. |
RaceCandidate |
access_a < access_b, exact location, and RaceWitness. |
RaceWitness |
Underlying expressions, access kinds, endpoint ranges/locksets, and mhp_capped. |
AtomicityCandidate |
read, later write, exact location, and AtomicityWitness. |
AtomicityWitness |
Expressions, interfering access/kind/lockset, boundary lock, release/reacquire sites/ranges, endpoint locksets, and mhp_capped. |
Field/index facts require a typed DFG access relation and one exact Reference;
channel facts require typed MsgKind and resolved identity. Iterative parent
walks lift expressions to executable MHP sites and execution strands. Typed
lock events are replayed in source order. Ambiguous identity/site/strand input
is suppressed, hostile public MHP pairs are normalized, and unresolved releases
clear held state conservatively.
See the component guide, usage guide, Theory 43, and security boundary.
The graph export surface returns ordinary vectors and exact stable identities;
it has no PyTorch, PyG, ndarray, random, parser, or gnn dependency.
pub fn export_pyg(cpg: &CodePropertyGraph) -> PygExport;
pub fn export_pyg_with_options(
cpg: &CodePropertyGraph,
options: PygExportOptions,
) -> Result<PygExport, AnalysisError>;
pub fn export_heterogeneous_gnn(
cpg: &CodePropertyGraph,
) -> HeteroGnnExport;
pub fn distance_to_targets(
cpg: &CodePropertyGraph,
targets: &[NodeId],
) -> BTreeMap<NodeId, f64>;
pub fn ast_paths(
cpg: &CodePropertyGraph,
function: NodeId,
options: AstPathOptions,
) -> Result<Vec<PathContext>, AnalysisError>;| Type or registry | Stable contract |
|---|---|
PygExport::node_features |
77 finite f32 columns per canonical node row |
PygExport::edge_index |
sorted (source_dense, target_dense, relation_class) tuples with parallel multiplicity |
PygExport::node_ids / source_ranges |
ascending stable ids and ranges aligned with every row |
PygExport::slice_node_ids |
sorted complete backward-PDG slice, empty without a criterion |
pagerank_converged / reverse_pagerank_converged |
convergence qualification for the two structural columns |
PygExport::dense_index |
stable-id lookup into aligned rows |
PygExport::feature_index |
exact schema-name lookup |
PYG_NODE_FEATURE_NAMES |
canonical 77-name registry |
edge_kind_class / EDGE_KIND_CLASS_COUNT / EDGE_KIND_CLASS_NAMES |
exhaustive 67-relation append-only map, names, and bound |
node_kind_class |
exhaustive 45-node-kind map |
HeteroGnnExport |
aligned ids/ranges/types/tokens, 109-column rows, and 67 complete relation buckets |
HeteroRelationEdges |
stable class/name plus sorted dense endpoints with parallel multiplicity |
HETERO_NODE_FEATURE_COUNT |
109: 45 exact kind columns plus 64 token-hash columns |
HETERO_TOKEN_EMBEDDING_DIM |
fixed deterministic token-hash width 64 |
distance_to_targets |
zero targets, harmonic reachable CFG/call shortest paths, positive infinity otherwise |
PathContext |
exact terminal ids/tokens, complete AST node path, aligned kind classes, ancestor id/index |
AstPathOptions |
length/width filters plus terminal, pair, context, retained-node, and ancestor-step caps |
export_pyg_with_options computes a complete slice before comparing it with
max_slice_nodes; over-budget localization is an error, not truncation.
ast_paths suppresses missing, ambiguous, or cyclic terminal parent chains,
and returns an error before any partial vector on a cap violation. Every
source-depth traversal uses heap state, and neither API mutates the CPG.
See the component guide, usage guide, Theory 44, and security boundary.
See Theory 55 and Usage 40 for the heterogeneous and directed-fuzzing surfaces.
The graph-diff surface reuses bounded GED correspondence, then compares exact node payloads and directed typed/labelled edge multisets in aligned coordinates.
pub fn cpg_diff(
old: &CodePropertyGraph,
new: &CodePropertyGraph,
options: &CpgDiffOptions,
) -> Result<CpgDiff, AnalysisError>;| Type or constant | Stable contract |
|---|---|
CpgDiffOptions |
independent max_nodes, max_edges, and aggregate max_edits complete-or-error caps |
CpgDiff |
canonical alignment/cost plus added, removed, changed, and classified evidence |
NodeAlignment |
graph-local old/new node-id pair selected by the symmetric GED script |
DiffNode / DiffEdge |
complete owned represented payload snapshots |
CpgElement / CpgChange |
insertion/deletion or exact node/edge substitution |
NodeChangeField / EdgeChangeField |
canonical exact field vocabularies |
ChangeKind |
represented-PDG edge edit (BehaviorChanging) or no such edit (Refactoring) |
MAX_CPG_DIFF_NODES |
512-node hard ceiling inherited from Hungarian GED alignment |
MAX_CPG_DIFF_EDGES / MAX_CPG_DIFF_EDITS |
2,000,000 hard ceilings for each input's edge index and complete output |
IDs are coordinates, not semantic identity. Embedded node ids compare through
the alignment, exact parallel edge multiplicity is preserved, and no partial
script is returned. ChangeKind requires comparable PDGs and is not a proof of
runtime equivalence or difference. Container language/source/root/CFG side
tables are outside the structural result.
See the component guide, usage guide, Theory 45, and security boundary.
With feature = "rholang", session_sketches(&CodePropertyGraph) -> Vec<SessionSketch> groups definition-resolved channel events into deterministic
per-process action vectors and checks ordinary binary linear duality.
| Item | Contract |
|---|---|
SessionSketch |
Resolved channel, sorted endpoints, three-valued verdict, and ordered issues. |
SessionEndpoint |
Top-level process plus actions sorted by event-site id. |
SessionAction |
Direction, exact MsgKind, shallow payload vector, site, and source range. |
SessionPayloadType |
Literal category, normalized explicit/named type, or Unknown. |
SessionConformance |
Conformant, Nonconformant, or Inconclusive. |
SessionIssueKind |
Cardinality, length, direction, arity, type, unknown-type, or non-linear-receive evidence. |
The API is read-only and out of graph. Conformant requires exactly two
equal-length linear traces with opposite directions and equal known payload
types. Concrete mismatches dominate uncertainty. See the component
guide, usage
guide, theory,
and security boundary.
The feature-free typestate API evaluates a caller-defined PropertyFsm over
typed allocation, object-flow, call, and canonical intraprocedural CFG
evidence.
| Item | Contract |
|---|---|
PropertyFsm |
Ordered closed vocabularies, partial ordinary transitions, allocation seeds, accepting states, and one absorbing error state. |
PropertyFsm::validate |
Deterministic set of every structural property issue. |
analyze_typestate |
fn(&CodePropertyGraph, &PropertyFsm, &IfdsCaps) -> TypestateAnalysis; retains findings, terminal states, caps, issues, and work evidence. |
check_typestate |
Positive-finding convenience projection; use the report before a negative claim. |
TypestateViolation |
Allocation object, violating site, prior state, event, canonical witness, and cap qualifier. |
TypestateAnalysis::is_complete |
True only when no resource or structural/evidence boundary qualifies the result. |
TypestateAnalysis::object_is_accepting |
Whether all represented terminal states for one object belong to the policy's accepting set. |
Missing ordinary transitions enter the absorbing error state. Branch joins retain may-unions, so one legal and one forbidden path can coexist. The analysis is read-only, out of graph, deterministic, and stack-safe over graph depth. See the component guide, usage guide, theory, and security boundary.
The feature-free bug-detector APIs compose existing typestate, variable-fact, reaching-definition, call-SCC, type, inheritance, and normalized exception evidence. Every report is read-only and deterministic.
| Item | Contract |
|---|---|
analyze_resource_leaks |
fn(&CodePropertyGraph, &PropertyFsm, &IfdsCaps) -> ResourceLeakAnalysis; projects non-accepting typestate terminals while retaining the complete typestate report. |
resource_leaks |
Positive-only leak projection; inspect ResourceLeakAnalysis::is_complete() before an absence claim. |
analyze_uninitialized_uses |
fn(&CodePropertyGraph) -> UninitializedUseAnalysis; reports binder-aware executable uses with no in-scope reaching definition. |
uninitialized_uses |
Positive-only use projection. |
analyze_exception_flow |
fn(&CodePropertyGraph, &IfdsCaps) -> ExceptionFlowAnalysis; returns finite escaping-type summaries, uncaught root propagation, reached/dead catches, work, caps, and issues. |
uncaught_exceptions / dead_catches |
Positive-only exception finding projections. |
ResourceLeak |
Allocation object, semantic exit, non-accepting state, canonical witness, and cap qualifier. |
UninitializedUse |
Function, executable use site, canonical variable name, and out-of-scope definitions. |
UncaughtException |
Root entry, escaping origin/type, canonical call/throw witness, and cap qualifier. |
DeadCatch |
Function, catch node, accepted types or catch-all marker, and cap qualifier. |
Unknown types, ambiguous calls, missing typed catch-entry edges, missing witnesses, and shared-solver failures prevent exception completeness. See the component guide, usage guide, theory, and security boundary.
The feature-free population APIs compose caller-owned taint policy, typed API identity, PDG checks, CFG reachability, and forward DFG/PDG value evidence. They are deterministic, read-only, stack-safe over represented depth, and exact at rational support boundaries.
| Item | Contract |
|---|---|
analyze_missing_checks |
fn(&CodePropertyGraph, &MissingCheckConfig) -> Result<MissingCheckAnalysis, AnalysisError>; returns qualified I6 findings, admitted sites, and typed issues. |
missing_checks |
Positive-only Vec<MissingCheck> projection; inspect the report before an absence claim. |
MissingCheckConfig |
Taint catalog/classes, exact support, minimum population, peer scope, and fingerprint/callee bounds. |
PeerScope |
WholeProgram or CallGraph { max_distance } over owner functions. |
CheckFingerprint |
Flat postorder semantic check tape; local spellings are abstracted while behavior-bearing payloads remain exact. |
analyze_deviant_behavior |
fn(&CodePropertyGraph, &DeviantBehaviorConfig) -> Result<DeviantBehaviorAnalysis, AnalysisError>; returns I7 order/return beliefs, deviations, sites, and issues. |
deviant_behaviors |
Positive-only Vec<DeviantBehavior> projection. |
CallOrderBelief |
Exact support for a later CFG-reachable API after a predecessor API. |
ReturnCheckBelief |
Exact support for call-result value evidence reaching a represented guard. |
ApiIdentity |
Sorted represented target set or typed named external path. |
PopulationFraction / PopulationThreshold |
Exact observed and required support; ratio() is presentation-only. |
Incomplete occurrences do not vote and remain visible as issues. See the component guide, usage guide, theory, and security boundary.
The feature-free I8/I9 APIs consume normalized graph evidence and return
read-only, canonically ordered reports. A positive-only convenience projection
discards issues; use the qualified analyzer and is_complete() for an absence
claim.
| API/type | Meaning |
|---|---|
analyze_inconsistent_clones / inconsistent_clone_bugs |
Qualified I8 report / positive finding projection. |
CloneBugConfig |
Clone/GED options, exact edit/rename thresholds, occurrence minimum, AST/alignment caps. |
CloneBugAnalysis |
Findings, evaluated exact pairs, typed issues, is_complete(). |
InconsistentCloneBug / InconsistentCloneKind |
Pair-local clone/GED/edit evidence and exact rename or guard witness. |
ClonePairEvidence / CloneBugIssue |
Evaluated pair admission and explicit evidence gaps. |
analyze_infeasible_paths / infeasible_paths |
Qualified I9 report / positive finding projection. |
InfeasiblePathConfig |
Condition-node, alternative-state, and machine-step caps. |
InfeasiblePathAnalysis |
Findings, analyzed functions/conditions, typed issues, is_complete(). |
InfeasiblePathFinding / InfeasiblePathKind |
Function/source/guard, branch/redundancy/contradiction kind, proof, and witnesses. |
FeasibilityProofSource |
SCCP, intervals, or their combined evidence. |
IntervalContradiction / IntervalPredicateEvidence |
Ordered empty-alternative proof and exact normalized predicates/regions. |
See the component guide, usage guide, theory, and security boundary.
The feature-free I12 API builds one centered typed API Usage Graph (AUG) per complete call site, mines exact strict-majority fragments per anchor API, emits advisory deviations, and delegates named temporal properties to typestate.
| API/type | Meaning |
|---|---|
analyze_api_usage_mining |
Qualified AUG, pattern, deviation, temporal-analysis, temporal-finding, and issue report. |
api_usage_misuses |
Positive-only usage-deviation projection; never use alone for an absence claim. |
ApiUsageMiningConfig |
Exact support/population policy; call, CFG, AUG, callee, property, and delegated typestate caps. |
ApiUsageMiningAnalysis |
Ordered graphs/patterns/findings/temporal evidence/admitted sites/issues; is_complete() composes both analysis paths. |
ApiUsageGraph |
Anchor/function/API plus dense typed local nodes and labeled edges; is_acyclic() is iterative. |
ApiUsageNodeKind |
Anchor action, following action, normalized data shape, or normalized control context. |
ApiUsageEdgeKind |
Receiver, positional parameter, selection, or represented order. |
ApiUsagePattern / ApiUsagePatternKind |
Exact support and supporting sites for following-call, arity, argument, receiver, or control fragments. |
ApiUsageMisuse / ApiUsageMisuseKind |
Deviating site with expected/observed evidence, exact peer support, supporting sites, and witness. |
NamedTemporalProperty |
Unique report name paired with a validated PropertyFsm. |
TemporalPropertyFindingKind |
Forbidden transition or non-accepting represented exit. |
TemporalPropertyAnalysis |
Complete delegated resource/typestate evidence for one name. |
ApiUsageMiningIssue |
Atomic inventory or site-local owner/identity/CFG/AUG incompleteness. |
See the component guide, usage guide, theory, and security boundary.
The feature-free CWE API intersects bounded structural embeddings with shared semantic analysis evidence. It never parses source or mutates the target CPG.
| API/type | Meaning |
|---|---|
builtin_cwe_templates |
Owned canonical registry for CWE-22, 78, 79, 89, 190, 416, 476, 502, 787, and 798. |
analyze_builtin_cwes |
Qualified analysis of the complete shipped registry. |
analyze_cwe_templates |
Qualified analysis of a validated caller-supplied template set. |
CweTemplate / CweRole / CwePrimitive |
Stable identity and CWE metadata, source/neutralizer/sink role predicates, structural alternatives, and selected shared primitive. |
CweStructuralPattern / CwePatternEdge |
Dense exact node tags, typed directed relations, and designated mapped sink. |
CweAnalysisConfig |
CWE structural/origin caps plus delegated IfdsCaps. |
CweAnalysis |
Ordered templates, embeddings, candidates, delegated reports, typed issues, and aggregate is_complete(). |
CweStructuralMatch |
Template/pattern identity, mapped sink, and dense pattern-index-to-target mapping. |
CweCandidate / CweEvidence |
Immutable represented site/origin/witness, integer evidence score, and primitive-specific evidence. |
CweAnalysisError |
Invalid request rejected before evaluation. |
CweAnalysisIssue |
Missing, contradictory, unsupported, failed, or capped represented evidence. |
CweTypestateAnalysis |
Template identity paired with the complete delegated typestate report. |
See the component guide, usage guide, theory, and security boundary.
The feature-free crypto API composes finite-state call order, typed positional constraints, and literal-origin data flow. It does not parse source or mutate the graph.
| API/type | Meaning |
|---|---|
builtin_crypto_rules |
Owned cross-language default policy. |
analyze_builtin_crypto |
Runs the shipped policy. |
analyze_crypto_misuse |
Runs a caller-supplied CryptoRuleSet. |
CryptoArgumentRule |
Stable name, typed call patterns, and zero-based argument positions. |
CryptoRuleSet |
Property FSM, weak-hash/mode/IV/key rules, random sources, and forbidden names. |
CryptoAnalysisConfig |
Local call/origin bounds plus delegated IfdsCaps. |
CryptoFinding / CryptoMisuseKind |
Canonical advisory category, site, rule, optional argument, and qualification. |
CryptoEvidence |
Typed call path, literal origins, taint witness, or typestate witness. |
CryptoAnalysisIssue |
Invalid policy, bounded path/call/origin, or qualification evidence. |
CryptoAnalysis |
Findings plus complete typestate/taint reports and aggregate is_complete(). |
LiteralPattern / LiteralSourceRule |
General categorical literal provenance for TaintCatalog. |
See the component guide, usage guide, theory, and security boundary.
The feature-free J3/J4 APIs compose typed literal qualification with shared taint and specialize shared population inference for authN/authZ guards. They do not parse source, copy secret values into findings, or mutate the CPG.
| API/type | Meaning |
|---|---|
builtin_secret_rules / analyze_builtin_secrets |
Owned cross-language secret policy and its analysis entry point. |
analyze_secret_flows |
Runs a caller-supplied SecretRuleSet. |
SecretSinkRule / SecretSinkFamily |
Stable rule, typed paths, optional zero-based positions, and authentication/network/crypto-key family. |
SecretAnalysisConfig |
Integer entropy thresholds, literal/context bounds, and delegated IfdsCaps. |
SecretLiteralEvidence |
Value-minimizing high-entropy or typed name-hint evidence. |
SecretFinding / SecretAnalysis |
Canonical source-to-sink witness plus complete delegated taint and issues. |
builtin_authz_rules / analyze_builtin_authz |
Owned mutation/access defaults and their analysis entry point. |
analyze_missing_authz |
Runs a caller-supplied AuthzRuleSet. |
AuthzMutationRule / AuthzRuleSet |
Typed mutating APIs and access-guard fingerprint patterns. |
AuthzAnalysisConfig |
Exact population support, peer topology, and fingerprint/path bounds. |
AuthzFinding / AuthzAnalysis |
Missing normalized access guards, exact support, peers, witnesses, and translated issues. |
See the component guide, usage guide, theory, and security boundary.
The feature-free J5 API ranks function PDGs against one caller-labeled seed. Weisfeiler--Lehman (WL) label histograms are canonicalized in a shared seed/candidate vocabulary; equal-size candidates above a threshold can receive bounded relaxed VF2 confirmation. Reports are immutable and advisory.
| API/type | Meaning |
|---|---|
extrapolate |
Compact ranked (NodeId, f64) positive-discovery result. |
analyze_vulnerability_extrapolation |
Detailed ranking with analyzed functions, seed dimensions, invocation count, issues, and completeness. |
ExtrapolationOptions |
Admission/VF2 thresholds, WL rounds, and explicit request capacities. |
ExtrapolationCandidate |
Final/WL scores, confirmation flag, and candidate PDG dimensions. |
ExtrapolationIssue |
Invalid seed/options or function, PDG, VF2, and result-cap evidence. |
ExtrapolationAnalysis |
Ordered candidates and issue set; is_complete() requires no issue. |
Use the detailed API for every negative or completeness-sensitive interpretation. See the component guide, usage guide, theory, and security boundary.
GraphProjection is the feature-free, payload-free compressed-sparse-row view
used by exact graph analyses. These constructors are exported from the crate
root and libcpg::analysis:
| Function | Signature | Projection |
|---|---|---|
call_graph_projection |
fn(&CodePropertyGraph) -> GraphProjection |
resolved calls between all functions |
module_graph_projection |
fn(&CodePropertyGraph) -> GraphProjection |
Imports between Root / Module nodes |
cfg_projection |
fn(&CodePropertyGraph, NodeId) -> Result<GraphProjection, ProjectionError> |
one intraprocedural CFG |
dfg_projection |
fn(&CodePropertyGraph, Option<NodeId>) -> GraphProjection |
global or AST-scoped DFG |
pdg_projection |
fn(&CodePropertyGraph, NodeId) -> Result<GraphProjection, ProjectionError> |
one function's PDG |
projection_of |
generic node / edge / weight predicates | caller-selected relation |
GraphProjection::from_edges is the external-graph adapter. Accessors include
dense_index, node_id, successors, predecessors, successor_weights,
edges, transpose, undirected, and the total is_well_formed validator.
Parallel edges are merged by summing
their weights; sorted nodes and adjacency make the result independent of input
enumeration order. See the complete projection component guide
for field invariants, scope boundaries, complexity, pseudocode, and examples.
The feature-free dominance API is exported from the crate root and
libcpg::analysis:
| Function | Signature | Result |
|---|---|---|
dominator_tree |
fn(&GraphProjection, NodeId) -> Result<DominatorTree, AnalysisError> |
Dominators of projection nodes reachable from the selected root. |
post_dominator_tree |
fn(&CodePropertyGraph, NodeId) -> Result<PostDominatorTree, AnalysisError> |
Post-dominators and reverse dominance frontier for the shared reachable function CFG; returns UnknownNode / NotAFunction for invalid selectors. |
DominatorTree exposes deterministic idom, children, and frontier maps,
plus immediate_dominator, constant-time dominates, and the
dominators_of ancestor iterator. PostDominatorTree exposes sorted exits,
real ipdom relations, virtual_children, and its reverse frontier, plus
constant-time post_dominates, control_dependence_edges, and is_empty.
PdgBuilder uses that public control-dependence relation directly.
See the dominator component guide for exit modeling, unreachable-node semantics, CHK/Cytron pseudocode, complexity, validation, and examples.
These feature-free functions compute exact SCC partitions over CPG-specific or caller-supplied graph projections:
| Function | Signature | Projection |
|---|---|---|
control_flow_sccs |
fn control_flow_sccs(&CodePropertyGraph, NodeId) -> Result<SccDecomposition, SccAnalysisError> |
One function's intraprocedural CFG; nested functions and interprocedural call edges are excluded. |
call_graph_sccs |
fn call_graph_sccs(&CodePropertyGraph) -> SccDecomposition |
All functions and resolved caller-to-callee relations in the CPG. |
projection_sccs |
fn projection_sccs(&GraphProjection) -> SccDecomposition |
Any constructor-valid deterministic projection, preserving specialized CFG/call provenance or recording Projection(kind). |
SccDecomposition exposes deterministic components, a
component_by_node membership map, cycle-only iteration, and the condensation
DAG's condensation_edges. Multi-node SCCs identify loop or recursion
clusters; singleton SCCs are marked cyclic only when they have a self-loop.
See the SCC component guide for projection
boundaries, accepted call encodings, complexity, and examples.
These feature-free functions consume the SCC result without mutating or re-projecting the CPG:
| Function | Signature | Result |
|---|---|---|
condensation_metrics |
fn(&SccDecomposition, &CondensationOptions) -> CondensationMetrics |
Source-oriented longest-path levels, SCC-member-weighted critical path, height/width, and an optional CG schedule; total incomplete/capped signaling. |
coffman_graham |
fn(&SccDecomposition, u32) -> Result<CgLayering, AnalysisError> |
Sink-first width-bounded layers, or explicit invalid-input/budget error. |
CondensationOptions exposes max_components and
coffman_graham_width. CondensationMetrics exposes levels,
critical_path, critical_path_weight, height, width,
coffman_graham, complete, and capped. CgLayering exposes
width_limit, sorted layers, direct layer_of, and height() / width().
The hard ceiling is the root-exported
MAX_CONDENSATION_COMPONENTS = 1_000_000.
See the condensation component guide for orientation, Kahn and Coffman–Graham pseudocode, malformed-input policy, complexity, examples, and exhaustive path/schedule oracles.
| Item | Signature / purpose |
|---|---|
infer_layering |
fn(&SccDecomposition, &CondensationMetrics) -> LayeringReport — reverse source levels into bottom-first layers and classify cycle, skip, and non-downward evidence. |
LayeringReport |
layers, layer_of, sorted violations, plus complete/capped state. |
LayeringViolation |
Component endpoints, bottom-first endpoint layers, absolute distance, and a LayeringViolationKind. |
LayeringViolationKind |
CyclicComponent, SkipLayer, or Upward. |
The input decomposition is structurally revalidated. Consumed level fields must
have the component domain, dense bounded levels, and consistent height/width.
Every non-violating condensation edge descends exactly one layer. A cyclic
witness names its exact contracted component rather than fabricating an
internal edge that SccDecomposition no longer stores. See the layering
component guide.
These feature-free functions consume a valid GraphProjection without
mutating it or its source CPG:
| Function | Signature | Result |
|---|---|---|
analyze_dsm |
fn(&GraphProjection) -> DsmAnalysis |
Non-reflexive transitive visibility fan-out/fan-in and propagation cost via repeated forward BFS. |
classify_core_periphery |
fn(&GraphProjection, &DsmAnalysis) -> CorePeripheryResult |
Inclusive-median Core/Shared/Control/Peripheral roles plus the largest multi-vertex SCC. |
DsmAnalysis exposes stable nodes, aligned visibility_fan_out and
visibility_fan_in, propagation_cost, n, complete, and capped.
CorePeripheryResult exposes stable nodes, aligned classes, both median
thresholds, dense cyclic_core, complete, and capped; class_of and
cyclic_core_nodes provide stable-identifier lookup. CorePeriphery::as_str
returns stable lowercase labels.
The hard ceiling is MAX_DSM_NODES = 50_000. Oversized input produces an
explicitly capped incomplete result; malformed public CSR or mismatched
analysis provenance/count/scalar consistency produces an uncapped incomplete
result. Derived vectors are empty in both cases, never partial. See the DSM component
guide for formulae, edge direction,
literate BFS/SCC composition, degenerate median semantics, examples, tests,
and interpretation limits.
These feature-free functions combine a caller-selected dependency projection with an explicit assignment of stable node IDs to architectural modules:
| Function | Signature | Result |
|---|---|---|
martin_metrics |
fn(&CodePropertyGraph, &ModuleAssignment, &GraphProjection) -> Vec<MartinMetrics> |
Lexically ordered module coupling, instability, abstractness, and main-sequence distance. |
sdp_violations |
fn(&[MartinMetrics], &GraphProjection, &ModuleAssignment) -> Vec<SdpViolation> |
Ordered violating module pairs with dependency multiplicity and one stable edge witness. |
ModuleAssignment exposes canonical buckets: Vec<Arc<str>> and
of_node: BTreeMap<NodeId, u32>. from_pairs accepts caller policy;
by_module_nodes uses the nearest enclosing CPG module and
by_source_path uses retained graph provenance. MartinMetrics exposes
module, ca, ce, instability, abstractness, and distance.
SdpViolation exposes the module pair, smallest stable source/target witness,
dependency count, and both instability values.
Coupling counts distinct external projection vertices and ignores weights and intra-module edges. Abstractness counts abstract classes plus traits over all class/struct/enum/trait declarations assigned to a module. Malformed projections return no results; invalid assignment indices are inert; duplicate or invalid metric values suppress SDP verdicts. See the Martin component guide for formulae, assignment policy, pseudocode, examples, complexity, and interpretation limits.
The feature-free metrics API consumes nominal ownership, resolved calls, typed field flow, and common CPG node kinds without reparsing source:
| Function | Signature | Result |
|---|---|---|
method_field_graph |
fn(&CodePropertyGraph, NodeId) -> MethodFieldGraph |
Sorted method/field partitions, concrete access witnesses with read/write flags, and resolved internal method calls; MethodFieldGraph::lcom() projects that exact evidence to LCOM1–5. |
ck_metrics |
fn(&CodePropertyGraph, &CkOptions) -> Vec<ClassMetrics> |
Class-ID-sorted WMC, DIT, NOC, CBO, RFC, and LCOM1–5 rows. |
function_metrics |
fn(&CodePropertyGraph, NodeId) -> Result<FunctionMetrics, AnalysisError> |
Semantic Halstead, cyclomatic, cognitive, source-span/comment, and maintainability values for one function. |
CkOptions exposes include_structs, include_enums, and
include_implements. Defaults include structs, exclude enums, and treat only
Inherits as inheritance. MethodFieldAccess preserves method, access,
field, reads, and writes; it exists only when Reference and typed field
DFG evidence agree. MethodCall preserves resolved internal endpoints.
ClassMetrics exposes class, wmc, dit, noc, cbo, rfc, and
LcomSuite. FunctionMetrics exposes function, cyclomatic_complexity,
cognitive_complexity, halstead, logical_lines, comment_lines, and
maintainability_index. HalsteadMetrics retains all four primitive counts so
derived values can be independently audited.
Invalid function selectors use the shared analysis errors; invalid nominal selectors return an empty evidence graph. Inheritance cycles are condensed, all public vectors use stable ID order, and floating results have defined zero-denominator cases. See the code-metrics component guide for exact formulae, semantic classification, pseudocode, and interpretation limits.
The feature-free smell API composes a directed projection with its exact SCC decomposition, an explicit module assignment, and Martin metrics:
| Item | Signature / purpose |
|---|---|
architecture_smells |
fn(&GraphProjection, &SccDecomposition, &[MartinMetrics], &ModuleAssignment, &SmellOptions) -> Vec<ArchSmell> — validate one evidence snapshot and return canonical advisory findings. |
ArchSmellKind |
CyclicDependency { component }, HubLikeDependency, UnstableDependency, or GodComponent. |
ArchSmell |
One kind, a sorted non-empty Vec<NodeId>, finite severity, and detector-specific BTreeMap<&'static str, f64> evidence. |
SmellOptions |
Non-negative fan-in/fan-out sigma multipliers, a less-stable share in 0.0..=1.0, and a non-negative component-size sigma multiplier. |
Cycles require at least two SCC members. Hubs must exceed both configured population degree thresholds. Unstable findings group one source module's cross-module edges whose target has greater Martin instability. God components are high-side outliers in assigned projection-node count because this API has no lines-of-code table. Comparisons are strict; weights and self-loops do not affect fan/module-edge rules.
Malformed CSR, stale SCCs, missing assignment/metrics, duplicate metric names, or invalid numerics fail closed with an empty result. Findings sort by kind, descending severity, smallest node, then the whole node vector. See the architectural-smell component guide for evidence keys, a complete example, formulae, and advisory boundaries.
This feature-free path API compares a declared layered architecture with an observed directed dependency multiset:
| Function | Signature | Result |
|---|---|---|
reflexion |
fn(&ReflexionRules, impl IntoIterator<Item=(Arc<str>, Arc<str>)>) -> ReflexionSummary |
Input-order-invariant convergence/unlayered counts, path-sorted divergences, and ordered realized allowed pairs. |
ReflexionRules::layer_of |
fn(&self, &str) -> Option<&str> |
First layer whose textual prefix matches the path. |
ReflexionRules::classify |
fn(&self, &str, &str) -> ReflexionVerdict |
SameLayer, Allowed, Divergence, or Unlayered. |
ReflexionRules::absences |
fn(&self, &BTreeSet<(Arc<str>, Arc<str>)>) -> Vec<(Arc<str>, Arc<str>)> |
Sorted, deduplicated declared pairs not realized by observed edges. |
LayerSpec exposes name and ordered prefixes; ReflexionRules exposes
ordered layers and directed allow pairs. ReflexionDivergence preserves
both paths plus their mapped layers. Paths are opaque strings: the API performs
no filesystem lookup or normalization, and duplicate observations preserve
multiplicity. See the reflexion component guide
for syntax, semantics, pseudocode, security limits, examples, and evidence.
These feature-free functions consume a valid GraphProjection without
mutating it or its source CPG:
| Function | Signature | Result |
|---|---|---|
wl_labels |
fn(&GraphProjection, usize) -> Vec<u64> |
Final deterministic labels aligned with projection nodes after the bounded requested round count. |
structural_clone_classes |
fn(&GraphProjection, usize, usize) -> Vec<Vec<NodeId>> |
Equal-label stable-id classes ordered by size and smallest member. |
The directed in/out degree pair seeds each label. Refinement folds the sorted
incoming-plus-outgoing neighbor-label multiset through a fixed wrapping mixer,
then assigns sorted raw-value ranks. MAX_WL_ITERATIONS = 16 clamps hostile
requests; min_class has an effective floor of two. Edge weights are ignored,
and malformed public projection values return empty results before indexed
traversal. Nonzero-round calls allocate two call-local dense label matrices and
reuse their capacities plus the canonical vocabulary across all rounds;
zero-round calls return the seed vector without that scratch allocation. No
state survives the call and graph depth does not drive native recursion. Equal
labels are structural candidates, not a proof of exact isomorphism or
behavioral equivalence. See the complete WL component
guide for formulas, pseudocode, examples,
collision limits, properties, and benchmark evidence.
The feature-free centrality family returns stable node-aligned vectors or
canonical stable edge pairs. Every function is exported from the crate root and
libcpg::analysis.
| Function | Signature | Topology |
|---|---|---|
pagerank |
fn(&GraphProjection, PageRankOptions) -> CentralityScores |
directed |
reverse_pagerank |
fn(&GraphProjection, PageRankOptions) -> CentralityScores |
directed transpose |
personalized_pagerank |
fn(&GraphProjection, &[(NodeId, f64)], PageRankOptions) -> Result<CentralityScores, AnalysisError> |
directed with seed restart |
betweenness_centrality |
fn(&GraphProjection, BetweennessOptions) -> Result<CentralityScores, AnalysisError> |
directed shortest paths |
accumulate_for_sources |
fn(&GraphProjection, &[NodeId], BetweennessOptions) -> Result<CentralityScores, AnalysisError> |
directed source partition |
edge_betweenness |
fn(&GraphProjection, CentralityBudget) -> Result<EdgeCentralityScores, AnalysisError> |
undirected shortest paths |
eigenvector_centrality |
fn(&GraphProjection, IterationOptions) -> CentralityScores |
weighted undirected |
katz_centrality |
fn(&GraphProjection, KatzOptions) -> CentralityScores |
weighted undirected |
closeness_centrality |
fn(&GraphProjection, CentralityBudget) -> Result<CentralityScores, AnalysisError> |
unweighted undirected |
harmonic_centrality |
fn(&GraphProjection, CentralityBudget) -> Result<CentralityScores, AnalysisError> |
unweighted undirected |
hits |
fn(&GraphProjection, IterationOptions) -> HitsScores |
directed hub/authority |
burt_constraint |
fn(&GraphProjection, CentralityBudget) -> Result<CentralityScores, AnalysisError> |
weighted undirected |
CentralityScores exposes kind, aligned nodes and scores, iterations,
and converged. HitsScores exposes hubs and authorities in that format.
EdgeCentralityScores exposes sorted canonical edges, aligned scores,
source iterations, and converged.
PageRankOptions, IterationOptions, and KatzOptions carry numerical
convergence controls. BetweennessOptions carries directed normalization and
a work cap; CentralityBudget carries the corresponding cap for undirected
all-sources and local-neighborhood kernels. Iteration requests are clamped to
MAX_CENTRALITY_ITERATIONS = 10_000; the default traversal ceiling is
DEFAULT_CENTRALITY_WORK_LIMIT = 2_000_000_000 modeled operations.
Unknown personalized or Brandes source ids return UnknownNode. Malformed
public projections, overflowing restart mass, non-finite weighted-matrix
input, and over-budget traversals are rejected before indexed work where the
signature is fallible. Total scalar APIs return a non-converged aligned result
for invalid numerical options or non-finite weights. Brandes rescales path
weights per breadth-first layer, preserving predecessor ratios while
preventing path-count overflow.
See the complete centrality component guide
for formulas, direction and weight policy, literate pseudocode, examples,
complexity, validation, and interpretation limits.
The feature-free community family consumes a validated GraphProjection as a
weighted undirected graph. Reciprocal directed weights are summed; negative,
non-finite, or overflowing weights are rejected.
| Function | Signature | Result |
|---|---|---|
louvain |
fn(&GraphProjection, LouvainOptions) -> Result<CommunityAssignment, AnalysisError> |
Deterministic multi-level Louvain partition aligned with the original projection. |
try_refine_connected |
fn(&GraphProjection, &CommunityAssignment) -> Result<CommunityAssignment, AnalysisError> |
Checked split of every assigned group into induced connected components. |
refine_connected |
fn(&GraphProjection, &CommunityAssignment) -> CommunityAssignment |
Total convenience boundary; malformed public input yields a canonical singleton fallback. |
CommunityAssignment exposes kind, aligned nodes and community,
num_communities, and generalized modularity. Community identifiers are
contiguous and ordered by smallest stable member. LouvainOptions controls
nonnegative finite resolution, max_passes, and max_levels; requests are
clamped to MAX_LOUVAIN_PASSES = 50 and MAX_LOUVAIN_LEVELS = 10.
The checked refinement requires exact node alignment and canonical input
labels, inherits the resolution stored in CommunityKind, and recomputes the
score of the refined partition. See the community component
guide for formulas, pseudocode,
examples, complexity, and evidence boundaries.
The feature-free cohesion family validates a GraphProjection and returns
out-of-graph, canonically ordered evidence. Topological operations forget
direction, deduplicate reciprocal relations, and ignore self-loops. Weighted
minimum cut instead sums reciprocal weights and rejects negative, non-finite,
or overflowing values.
| Function | Signature | Result |
|---|---|---|
k_core_decomposition |
fn(&GraphProjection) -> Result<KCoreDecomposition, AnalysisError> |
node-aligned core numbers |
k_truss_decomposition |
fn(&GraphProjection) -> Result<KTrussDecomposition, AnalysisError> |
canonical edge trussness |
cut_vertices_and_bridges |
fn(&GraphProjection) -> Result<CutStructure, AnalysisError> |
sorted articulation vertices and bridges |
two_edge_connected_components |
fn(&GraphProjection) -> Result<TwoEdgeConnectedComponents, AnalysisError> |
smallest-member-ordered robust blocks |
global_min_cut |
fn(&GraphProjection) -> Result<Option<GlobalMinCut>, AnalysisError> |
minimum weight and canonical cut side, or None below two nodes |
degree_assortativity |
fn(&GraphProjection) -> Result<f64, AnalysisError> |
endpoint-degree correlation in [-1,1] |
attack_simulation |
fn(&GraphProjection, &[NodeId], usize) -> Result<AttackResult, AnalysisError> |
ordered largest-component trace and normalized area |
MAX_K_TRUSS_EDGES is 200,000, MAX_MIN_CUT_NODES is 1,024, and
MAX_ATTACK_STEPS is 10,000. Excessive work returns
AnalysisError::BudgetExceeded. AttackResult::truncated describes a
caller-requested prefix shorter than the validated removal order; it is not
silent resource truncation. See the cohesion component
guide for definitions, literate
algorithms, examples, complexity, and interpretation boundaries.
The feature-free spectral family validates a GraphProjection, derives its
simple undirected unweighted topology, and returns immutable node-aligned
numerical evidence.
| Function | Signature | Result |
|---|---|---|
algebraic_connectivity |
fn(&GraphProjection, &SpectralOptions) -> Option<Spectral> |
total convenience result, or None below two nodes/on invalid input |
try_algebraic_connectivity |
fn(&GraphProjection, &SpectralOptions) -> Result<Option<Spectral>, AnalysisError> |
checked algebraic connectivity, Fiedler vector/sign partition, iterations, convergence, and residual |
MAX_SPECTRAL_ITERATIONS is 1,000 per start and MAX_SPECTRAL_STARTS is eight;
larger requests are deterministically clamped. Disconnected graphs return exact zero with a canonical component
contrast and no iteration. Connected graphs use bounded sparse deflated power
iteration over the combinatorial Laplacian. See the spectral component
guide for formulas, pseudocode,
closed forms, convergence policy, and interpretation boundaries.
The feature-free cycle API validates directed CSR topology, reuses SCC decomposition, and returns canonical stable-identifier witnesses.
| Function | Signature | Result |
|---|---|---|
simple_cycles |
fn(&GraphProjection, &CycleOptions) -> Result<CycleSet, AnalysisError> |
cycles sorted by length/lexicographic order plus effective caps and first-omission evidence |
CycleOptions defaults to max_length = 10 and max_cycles = 10_000.
Requests clamp to MAX_CYCLE_LENGTH = 32 and
MAX_SIMPLE_CYCLES = 100_000. CycleSet::truncated and
first_dropped_cycle make a binding count limit explicit; individual retained
cycles remain valid witnesses. See the cycle component
guide for directed semantics,
canonicalization, literate pseudocode, complexity, and validation boundaries.
The feature-free motif API validates directed CSR topology, ignores weights and self-loops, and returns the complete sixteen-class triad census plus two selected four-node graphlet counts.
| Function | Signature | Result |
|---|---|---|
motif_census |
fn(&GraphProjection, &MotifOptions) -> Result<MotifCensus, AnalysisError> |
triads: [u64; 16] in TRIAD_NAMES order and graphlets_4: [u64; 2] |
MotifOptions defaults to max_nodes_triads = 512 and
max_nodes_graphlets = 50; requests above the corresponding hard ceilings are
clamped. Because one call requests both families, exceeding either effective
limit returns AnalysisError::BudgetExceeded rather than a partial census.
graphlets_4[0] is the complete bidirected four-clique count and index one is
the source-compatible out-star count. See the motif component
guide for the complete index table,
conservation law, pseudocode, and interpretation boundaries.
The feature-free loop API uses the shared reachable function CFG and dominator engine:
| Function | Signature | Result |
|---|---|---|
loop_forest |
fn loop_forest(&CodePropertyGraph, NodeId) -> Result<LoopForest, AnalysisError> |
Dominator-qualified natural loops, whole-SCC irreducible regions, strict nesting, innermost membership, and exit edges for one function. |
LoopForest exposes loops, loop_of_node, and roots, plus
innermost, max_depth, and is_back_edge. Each NaturalLoop records its
stable id, header, entries, latches, body, exits, parent,
children, depth, and irreducible flag. Each LoopExitEdge records
source, target, and the original CfgEdgeKind. Invalid selectors return the
same UnknownNode / NotAFunction variants as post-dominance.
See the natural-loop component guide
for definitions, natural and irreducible pseudocode, builder LoopExit
semantics, nesting invariants, complexity, citations, and validation oracles.
The feature-free reachability API partitions the complete function-scoped CFG universe without mutating the CPG:
| Function | Signature | Result |
|---|---|---|
unreachable_code |
fn unreachable_code(&CodePropertyGraph, NodeId) -> Result<ReachabilityReport, AnalysisError> |
Sorted reachable and unreachable CFG nodes plus conditional edges in unreachable islands. |
ReachabilityReport exposes function, reachable, unreachable, and
dead_branches; is_reachable(NodeId) performs a binary search over the sorted
reachable partition. Each DeadBranch records guard, edge_kind, and
target. The universe unions the entry-reachable projection with scoped
non-Call CFG endpoints, excludes nested functions when AST scope evidence
exists, and preserves every CPG node and edge.
Invalid selectors return UnknownNode or NotAFunction.
See the reachability component guide for partition laws, builder termination semantics, pseudocode, complexity, examples, security boundaries, and independent property-test oracles.
The feature-free block API groups the shared reachable function CFG without changing CPG nodes or edges:
| Function | Signature | Result |
|---|---|---|
block_cfg |
fn block_cfg(&CodePropertyGraph, NodeId) -> Result<BlockCfg, AnalysisError> |
Deterministic id-preserving blocks, typed block edges, node membership, entry/exits, and traversal orders. |
BlockCfg::blocks is sorted by leader and each BlockId equals its vector
index. block_of_node is a complete BTreeMap partition. edges is a sorted,
deduplicated Vec<BlockEdge> that retains the original CfgEdgeKind for every
transition except adjacent internal Sequential steps. Accessors include
block, successors, predecessors, nodes_in(petgraph::Direction),
reverse_post_order, and post_order. Invalid selectors return UnknownNode
or NotAFunction.
See the basic-block component guide for leader rules, field invariants, pseudocode, complexity, traversal semantics, the compatibility API, citations, and property-test oracles.
The feature-free framework solves caller-defined analyses over BlockCfg:
| API | Signature or role |
|---|---|
solve |
fn(&CodePropertyGraph, &BlockCfg, &A, &SolverConfig, Option<&LoopForest>) -> Result<DataflowSolution<A::Domain>, AnalysisError> |
Lattice |
Clone + PartialEq + Debug domain with join and leq |
DataflowAnalysis |
direction, confluence, bottom/boundary, block transfer, optional edge transfer and widening |
SolverConfig |
per-block visit cap, loop-header widening threshold, bounded narrowing passes |
DataflowSolution<D> |
before, after, visits, and node-level state_at replay |
FactUniverse<T> |
sorted, deduplicated facts with stable dense u32 ids |
BitSetDomain / MustBits |
union/subset may domain and intersection/reverse-subset must domain |
variable_facts / expression_facts |
canonical variable definition/use and structural expression universes |
Direction::{Forward, Backward} selects RPO or post-order propagation.
Confluence::{May, Must} documents path semantics; Lattice::join implements
the meet-over-predecessor/successor algebra. Exceeding
max_visits_per_block returns AnalysisError::IterationLimitExceeded.
See the data-flow component guide for equations, trait laws, exact fact classification, pseudocode, complexity, security controls, citations, and validation oracles.
The first built-in feature-free solver instance computes backward-May variable liveness and derives read-only dead-store evidence:
| API | Signature | Result |
|---|---|---|
liveness |
fn(&CodePropertyGraph, NodeId) -> Result<LivenessResult, AnalysisError> |
Sorted live_in and live_out variable names for every reachable CFG node. |
dead_stores |
fn(&CodePropertyGraph, NodeId) -> Result<DeadStoreReport, AnalysisError> |
Reachable non-parameter definitions whose variable is absent from node live_out. |
LivenessResult exposes function, live_in, and live_out as
BTreeMap<NodeId, Vec<Arc<str>>>. Each DeadStore exposes its node,
variable, and original DefinitionKind. The report is advisory: volatile,
atomic, reflective, foreign, and language-specific setter effects require
caller policy before any source transformation.
See Variable liveness and dead stores for equations, the batched node-state replay, example code, complexity, limitations, benchmark oracle, and citations.
Two feature-free Must analyses derive read-only expression-optimization
evidence from canonical ExprKey facts:
| API | Signature | Result |
|---|---|---|
expression_facts |
fn(&CodePropertyGraph, NodeId) -> Result<ExprFacts, ExprKeyError> |
one shared flat ExprUniverse, generated occurrences, and operand-variable dependencies |
expression_facts_with_limits |
fn(&CodePropertyGraph, NodeId, ExprKeyLimits) -> Result<ExprFacts, ExprKeyError> |
the same facts with caller-selected node, operand, string-byte, encoded-byte, and work limits |
available_expressions |
fn(&CodePropertyGraph, NodeId) -> Result<AvailableExpressions, AnalysisError> |
available_in structural keys for every reachable node plus dominating redundant CSE pairs. |
very_busy_expressions |
fn(&CodePropertyGraph, NodeId) -> Result<VeryBusyExpressions, AnalysisError> |
busy_out structural keys for every reachable node plus dominance-backed hoistable PRE placements. |
ExprKey::try_new constructs a flat key; operator() and operands() expose
borrowed logical views. ExprOperand::Expression contains another flat key
handle, not a recursive box. ExprKeyLimits, ExprKeyMetrics, and
ExprKeyError make construction and canonical CEK1 persistence explicit.
ExprUniverse assigns stable dense fact ids with exact bottom-up structural
classes and shares one arena across occurrences. See
ADR-0041.
Forward availability intersects predecessor outputs; backward anticipability intersects successor inputs. Defining any operand kills its expression. Reports are deterministic and advisory: callers must validate language-specific side effects, traps, floating-point behavior, and concurrency before transforming source.
See Available and very-busy expressions for equations, candidate invariants, example code, complexity, independent path-enumeration oracles, limitations, and citations.
The feature-free SCCP API couples executable CFG edges with sparse definition and expression values:
| API | Signature | Result |
|---|---|---|
sccp |
fn(&CodePropertyGraph, NodeId) -> Result<SccpResult, AnalysisError> |
Proven scalar constants, executable CFG edges, dead conditional edges, and unreachable CFG nodes. |
ReachabilityReport::refine_with_sccp |
fn(&self, &SccpResult) -> Result<ReachabilityReport, AnalysisError> |
A new structural report refined by same-function SCCP path evidence. |
ConstValue::{Int, Float, Bool, Str, Char, Null} preserves exact scalar
payloads; ConstLattice::{Unknown, Constant, Overdefined} implements the public
Lattice trait. SccpResult fields are public and deterministic. Mismatching
the two functions during reachability refinement returns
AnalysisError::FunctionMismatch.
See Sparse conditional constant propagation for transfer semantics, checked arithmetic, the dual-worklist algorithm, complexity, validation, and limitations.
The feature-free interval API computes sound integer ranges at reachable basic-block entries:
| API | Signature | Result |
|---|---|---|
value_ranges |
fn(&CodePropertyGraph, NodeId) -> Result<IntervalReport, AnalysisError> |
Canonical variable-name intervals keyed by block leader. |
IntervalReport::interval_at |
fn(&self, NodeId, &str) -> Option<Interval> |
One named range at one reported block entry. |
Bound::{NegInf, Finite(i128), PosInf} defines extended endpoints.
Interval exposes checked construction, top, singleton, hull, meet, widening,
narrowing, subset, and membership operations. IntervalEnv is a sorted
pointwise Lattice over stable variable ids. The built-in analysis refines
integer comparison edges, widens only at LoopForest headers after three
visits, performs two bounded narrowing sweeps, and enforces a 64-visit cap.
Unary/binary expressions use typed heap continuation frames, so accepted AST
depth does not grow the native call stack; cycles or required machine-state
allocation failure conservatively become top.
See Interval value-range analysis for the domain equations, transfer table, literate algorithm, examples, validation, and semantic limits.
The feature-free loop-induction API composes a caller-supplied LoopForest
with semantic AST, CFG, DefUse DFG, canonical variable facts, and dominance
evidence:
| API | Signature | Result |
|---|---|---|
loop_induction |
fn(&CodePropertyGraph, NodeId, &LoopForest) -> Result<InductionAnalysis, AnalysisError> |
One immutable function report containing per-loop invariants, basic/derived IVs, and counted-trip evidence. |
InductionAnalysis exposes function, invariants, ivs, and bounds.
LoopInvariants exposes a stable loop_id, sorted invariant_nodes, and a
sorted advisory hoistable subset. InductionVariable records its loop_id,
canonical variable, update_node, checked step: Option<i64>,
IvDirection::{Increasing, Decreasing, Stationary, Unknown}, and sorted
outside-loop init_defs. LoopBoundEvidence contains either
TripEvidence::Counted { iv, comparison, bound_node } or Unknown.
The analysis recognizes additive explicit recurrences, semantic step-one
ranges, and one level of affine derivation. A counted record is structural
direction/bound evidence, not an exact trip count or termination proof. Every
forest node and exit endpoint is validated against the function; foreign
references return AnalysisError::UnknownNode. Candidate-use summaries,
depth-three affine recognition, and arbitrary-depth signed integer constants
use typed heap continuations with cycle guards; input depth does not consume
native call frames. The CPG is never mutated.
See Loop invariants, induction variables, and trip evidence for fixed-point equations, supported forms, hoist obligations, pseudocode, complexity, validation, and limitations.
| Method | Signature | Notes |
|---|---|---|
subgraph |
fn subgraph(&self, node_ids: &[NodeId]) -> Self |
Induced subgraph over node_ids (edges kept via add_edge_with_id, preserving ids). |
function_cfg |
fn function_cfg(&self, function: NodeId) -> Self |
Control-flow/expression subtree of function. |
function_dfg |
fn function_dfg(&self, function: NodeId) -> Self |
Subtree nodes carrying DFG edges. |
Every method above is available with default = []; only parsing needs a
lang-* feature. This builds a two-node CPG by hand and reads it back:
// requires: no features (the feature-free hand-built surface)
use libcpg::{
CodePropertyGraph, CpgNode, CpgNodeKind, CpgEdgeKind,
Language, NodeId, ScopeId, SourceRange, MethodSignature, Visibility,
};
let mut cpg = CodePropertyGraph::new(Language::Rust);
let func = cpg.add_node(CpgNode::new(
NodeId::new(0), // id is reassigned by add_node
CpgNodeKind::Function {
signature: Box::new(MethodSignature {
name: "main".into(),
params: Default::default(),
return_type: None,
is_static: false,
is_async: false,
visibility: Visibility::Public,
}),
},
SourceRange::default(),
));
let body = cpg.add_node(CpgNode::new(
NodeId::new(0),
CpgNodeKind::Block { scope: ScopeId::GLOBAL },
SourceRange::default(),
));
cpg.connect(func, body, CpgEdgeKind::AstChild);
assert_eq!(cpg.node_count(), 2);
assert_eq!(cpg.ast_children(func), vec![body]);
assert_eq!(cpg.functions().count(), 1);A node is a plain struct with public fields — read node.kind, not
node.kind().
pub struct CpgNode {
pub id: NodeId,
pub kind: CpgNodeKind,
pub range: SourceRange,
pub text: Option<Arc<str>>,
pub message_kind: Option<MsgKind>,
pub name_operation: Option<NameOperationKind>,
pub lock_kind: Option<LockKind>,
pub allocation_type: Option<Box<TypeInfo>>,
pub properties: Option<Box<FxHashMap<PropertyKey, PropertyValue>>>,
pub children: SmallVec<[NodeId; 4]>,
pub parent: Option<NodeId>,
}| Field | Type | Meaning |
|---|---|---|
id |
NodeId |
Unique identifier within the graph. |
kind |
CpgNodeKind |
The node's tagged variant + payload. |
range |
SourceRange |
Byte/line/column span in source. |
text |
Option<Arc<str>> |
Verbatim source text (terminals). |
message_kind |
Option<MsgKind> |
Frontend-normalized channel action, orthogonal to syntax kind. |
name_operation |
Option<NameOperationKind> |
Frontend-normalized restriction, fresh binder, quote, or drop operation. |
lock_kind |
Option<LockKind> |
Frontend/adapter-normalized lock action, orthogonal to syntax kind. |
allocation_type |
Option<Box<TypeInfo>> |
Frontend-normalized nominal type allocated by this expression. |
properties |
Option<Box<FxHashMap<PropertyKey, PropertyValue>>> |
Extra metadata, allocated only when nonempty. |
children |
SmallVec<[NodeId; 4]> |
AST child ids (source order). |
parent |
Option<NodeId> |
AST parent id. |
| Method | Signature | Notes |
|---|---|---|
new |
fn new(id: NodeId, kind: CpgNodeKind, range: SourceRange) -> Self |
Constructor. |
with_text |
fn with_text(self, text: impl Into<Arc<str>>) -> Self |
Builder: set source text. |
with_message_kind |
fn with_message_kind(self, kind: MsgKind) -> Self |
Builder: set normalized channel semantics. |
with_name_operation |
fn with_name_operation(self, kind: NameOperationKind) -> Self |
Builder: set normalized restriction/reflection semantics. |
with_lock_kind |
fn with_lock_kind(self, kind: LockKind) -> Self |
Builder: set normalized lock semantics. |
with_allocation_type |
fn with_allocation_type(self, type_info: TypeInfo) -> Self |
Builder: set normalized constructor type. |
with_property |
fn with_property(self, key: PropertyKey, value: PropertyValue) -> Self |
Builder: add a property. |
with_child |
fn with_child(self, child: NodeId) -> Self |
Builder: append a child id. |
with_parent |
fn with_parent(self, parent: NodeId) -> Self |
Builder: set the parent id. |
name |
fn name(&self) -> Option<&str> |
Name for named kinds (below); None otherwise. |
is_declaration |
fn is_declaration(&self) -> bool |
Module/Class/Struct/Enum/Trait/Function/Variable/Field/Parameter. |
is_statement |
fn is_statement(&self) -> bool |
Return/If/While/For/Loop/Match/Break/Continue/Throw/Try. |
is_expression |
fn is_expression(&self) -> bool |
BinaryOp/UnaryOp/Assignment/Call/MemberAccess/IndexAccess/Identifier/Literal/Lambda/Await/Yield. |
is_control_flow |
fn is_control_flow(&self) -> bool |
If/While/For/Loop/Match/Break/Continue/Return/Throw/Try. |
is_error |
fn is_error(&self) -> bool |
Error (parser recovery). |
Function signatures and node-owned TypeInfo values use heap indirection so
rare, large payloads do not determine the inline size of every graph node.
Box<T> implements Deref<Target = T>, so ordinary field reads such as
signature.name remain direct. For an optional boxed type, use
var_type.as_deref() when an API expects Option<&TypeInfo>. Serde treats the
box as transparent: JSON and other data-model formats retain their prior wire
shape and contain no wrapper object.
The open-ended properties map is also cold. None is the canonical empty
state; with_property allocates the map on first insertion. To inspect the
public field, use node.properties.as_deref() and then ordinary map methods.
Its custom Serde adapter preserves the earlier wire shape: an empty store is
still {}, a nonempty store is still the map itself, and there is no option or
box wrapper in serialized data.
The node kind is a 45-variant enum mixing
unit variants (e.g. Root, If, Return, Await) with data-carrying
variants (e.g. Function { signature }, Call { target, is_method }). Kinds
drive every query, pattern, and complexity heuristic.
Figure — the node-kind taxonomy: structural, function-level, variable, statement, expression, type, and special categories. Source: diagrams/node-kind-taxonomy.puml.
| Variant | Payload fields | name() |
|---|---|---|
Root |
— | — |
Module |
name: Arc<str> |
✓ |
Class |
name: Arc<str>, is_abstract: bool |
✓ |
Struct |
name: Arc<str> |
✓ |
Enum |
name: Arc<str> |
✓ |
Trait |
name: Arc<str> |
✓ |
Impl |
for_type: Option<Arc<str>>, trait_name: Option<Arc<str>> |
— |
| Variant | Payload fields | name() |
|---|---|---|
Function |
signature: Box<MethodSignature> |
✓ (from signature.name) |
Parameter |
name: Arc<str>, param_type: Option<Box<TypeInfo>>, is_variadic: bool |
✓ |
Block |
scope: ScopeId |
— |
| Variant | Payload fields | name() |
|---|---|---|
Variable |
name: Arc<str>, var_type: Option<Box<TypeInfo>>, scope: ScopeId, is_mutable: bool |
✓ |
Field |
name: Arc<str>, field_type: Option<Box<TypeInfo>>, visibility: Visibility |
✓ |
Return, If, Else, While, For, Loop, Match, MatchArm, Break,
Continue, Throw, Try, Catch, Finally.
| Variant | Payload fields | name() |
|---|---|---|
BinaryOp |
operator: Arc<str> |
— |
UnaryOp |
operator: Arc<str> |
— |
Assignment |
operator: Arc<str> |
— |
Call |
target: Option<NodeId>, is_method: bool |
— |
MemberAccess |
member: Arc<str> |
✓ (the member) |
IndexAccess |
— | — |
Identifier |
name: Arc<str>, definition: Option<NodeId> |
✓ |
Literal |
kind: LiteralKind |
— |
Lambda |
captures: SmallVec<[NodeId; 4]> |
— |
Await |
— | — |
Yield |
— | — |
| Variant | Payload fields | name() |
|---|---|---|
TypeAnnotation |
type_info: Box<TypeInfo> |
— |
GenericParam |
name: Arc<str> |
✓ |
| Variant | Payload fields | name() |
|---|---|---|
Comment |
is_doc: bool |
— |
Import |
path: Arc<str> |
✓ (the path) |
Attribute |
name: Arc<str> |
✓ |
Macro |
name: Arc<str> |
✓ |
Error |
message: Arc<str> |
— |
Unknown |
kind: Arc<str> |
— |
Total: 7 + 3 + 2 + 14 + 11 + 2 + 6 = 45 variants.
The payload of CpgNodeKind::Literal { kind }.
| Variant | Payload | Meaning |
|---|---|---|
Integer |
i64 |
Integer literal. |
Float |
f64 |
Float literal. |
String |
Arc<str> |
String literal. |
Char |
char |
Character literal. |
Bool |
bool |
Boolean literal. |
Null |
— | null / nil / None. |
Array |
— | Array/list literal. |
Object |
— | Object/map literal. |
Regex |
Arc<str> |
Regex literal. |
The four copy-sized values are Restriction, FreshBinder, Quote, and
Drop. Rholang records them orthogonally on structural nodes so NameFlow can
consume typed frontend evidence without source-text parsing.
pub struct TypeInfo {
pub name: Arc<str>,
pub is_reference: bool,
pub is_mutable: bool,
pub generics: SmallVec<[Arc<str>; 2]>,
}Builder methods: new(name: impl Into<Arc<str>>), with_reference(bool),
with_mutable(bool), with_generic(impl Into<Arc<str>>).
pub struct MethodSignature {
pub name: Arc<str>,
pub params: SmallVec<[TypeInfo; 4]>,
pub return_type: Option<TypeInfo>,
pub is_static: bool,
pub is_async: bool,
pub visibility: Visibility,
}Carried by CpgNodeKind::Function { signature }.
Unit enum: Public, Private (the Default), Protected, Package, Crate.
pub struct ScopeId(pub u32). Constant ScopeId::GLOBAL == ScopeId(0);
constructor ScopeId::new(u32).
CpgNode::properties maps keys to values:
PropertyKey:Name,Type,Scope,Visibility,Mutable,Static,Async,Custom(Arc<str>).PropertyValue: a logicalString,Int,Uint,Bool,Float,List, orNull, owned as flat postorder node and edge tapes. Historical constructor spellings remain (PropertyValue::List(vec![...])); observation useskind() -> PropertyValueKind,as_list() -> Option<PropertyList>, or the scalaras_str,as_int,as_uint,as_bool, andas_floataccessors.PropertyValueLimits,PropertyValueMetrics, andPropertyValueErrorexpose independent node, edge, string-byte, encoded-byte, and work accounting.encode/decodeuse canonical versioned CPV1 bytes with no logical-depth native recursion. See ADR-0040.
Edges, like nodes, expose public fields — use edge.source, not
edge.source().
pub struct CpgEdge {
pub id: EdgeId,
pub source: NodeId,
pub target: NodeId,
pub kind: CpgEdgeKind,
pub label: Option<Box<str>>,
}| Method | Signature | Notes |
|---|---|---|
new |
fn new(id: EdgeId, source: NodeId, target: NodeId, kind: CpgEdgeKind) -> Self |
General constructor. |
with_label |
fn with_label(self, label: impl Into<Box<str>>) -> Self |
Builder: set a label. |
ast_child |
fn ast_child(id: EdgeId, parent: NodeId, child: NodeId) -> Self |
AstChild edge. |
control_flow |
fn control_flow(id: EdgeId, from: NodeId, to: NodeId, kind: CfgEdgeKind) -> Self |
ControlFlow(kind) edge. |
data_flow |
fn data_flow(id: EdgeId, from: NodeId, to: NodeId, kind: DfgEdgeKind) -> Self |
DataFlow(kind) edge. |
def_use |
fn def_use(id: EdgeId, def: NodeId, use_site: NodeId) -> Self |
DataFlow(DefUse) shortcut. |
reference |
fn reference(id: EdgeId, use_site: NodeId, def: NodeId) -> Self |
Reference edge. |
call_site |
fn call_site(id: EdgeId, call: NodeId, callee: NodeId) -> Self |
CallSite edge. |
is_forward |
fn is_forward(&self) -> bool |
false for AstParent, AstPrevSibling, DataFlow(UseDef). |
Most edges are unlabeled. A present label therefore uses Box<str> so an
unlabeled edge does not carry a three-word String representation. Read it as
edge.label.as_deref() -> Option<&str>. Serde represents the box as the same
JSON string used by the former Option<String> field.
When you use
connectoradd_edge, pass anyEdgeId(e.g.EdgeId::new(0)) — the graph reassigns it.
A 25-variant enum. Five variants wrap a finer kind:
ControlFlow(CfgEdgeKind), DataFlow(DfgEdgeKind),
Heap(HeapEdgeKind), NameFlow(NameFlowEdgeKind), and
RewriteDep(RewriteDepEdgeKind).
Figure — the edge-kind taxonomy across the AST, CFG, DFG, PDG, Heap,
NameFlow, RewriteDep, call, type, reference, scope, and import families. Source:
diagrams/edge-kind-taxonomy.puml.
| Family | Variants |
|---|---|
| AST | AstChild, AstParent, AstNextSibling, AstPrevSibling |
| CFG | ControlFlow(CfgEdgeKind) |
| DFG | DataFlow(DfgEdgeKind) |
| PDG | ControlDependence, DataDependence |
| Heap | Heap(HeapEdgeKind) |
| NameFlow | NameFlow(NameFlowEdgeKind) |
| Rewrite dependency | RewriteDep(RewriteDepEdgeKind) |
| Call | StaticCall, DynamicCall, CallSite |
| Type | TypeOf, Inherits, Implements, GenericInstance |
| Reference | Reference, Definition, Declaration |
| Scope | EnclosingScope, ContainedIn |
| Import | Imports, Exports |
Predicates on the kind, useful with edges_by_kind:
| Method | True for |
|---|---|
is_ast(&self) -> bool |
the four AST variants |
is_cfg(&self) -> bool |
ControlFlow(_) |
is_dfg(&self) -> bool |
DataFlow(_) |
is_pdg(&self) -> bool |
ControlDependence, DataDependence |
is_heap(&self) -> bool |
Heap(_) |
is_name_flow(&self) -> bool |
NameFlow(_) |
is_rewrite_dep(&self) -> bool |
RewriteDep(_) |
is_call(&self) -> bool |
StaticCall, DynamicCall, CallSite |
is_type(&self) -> bool |
TypeOf, Inherits, Implements, GenericInstance |
The 14 control-flow edge kinds carried by
CpgEdgeKind::ControlFlow(_).
| Variant | Meaning |
|---|---|
Sequential |
Fallthrough between statements. |
ConditionalTrue |
Branch taken when a condition holds. |
ConditionalFalse |
Branch taken when a condition fails. |
LoopBack |
Back edge to a loop head. |
LoopExit |
Edge leaving a loop. |
Break |
break to loop exit. |
Continue |
continue to loop head. |
Return |
Edge to function exit. |
Throw |
Exception raise edge. |
Catch |
Edge into a handler. |
Call |
Edge into a callee. |
CallReturn |
Return from a callee. |
Case |
Match/switch case edge. |
DefaultCase |
Default case edge. |
Helpers: is_conditional() (ConditionalTrue/ConditionalFalse/Case/DefaultCase),
is_loop() (LoopBack/LoopExit/Break/Continue), is_exception()
(Throw/Catch).
The 13 data-flow edge kinds carried by
CpgEdgeKind::DataFlow(_).
| Variant | Meaning |
|---|---|
DefUse |
Definition → use. |
UseDef |
Use → definition (reverse). |
ReachingDef |
A reaching definition. |
DataDependency |
Generic data dependency. |
Parameter |
Argument → parameter. |
ReturnValue |
Return expression → caller. |
FieldRead |
Receiver → member access (the base-object read). |
FieldWrite |
Assignment → first-child member-access l-value. |
IndexRead |
Array receiver → index access. |
IndexWrite |
Assignment → first-child index-access l-value. |
Alias |
Alias relationship. |
Dereference |
Pointer dereference. |
AddressOf |
Address-of. |
Helpers: is_read() (DefUse/FieldRead/IndexRead/Dereference),
is_write() (UseDef/FieldWrite/IndexWrite).
With DfgExtractorConfig::include_field_access enabled (the default), the same
pass also emits Reference from a self/this member access to the unique
same-name Field declaration of its enclosing class/implemented type. This is
not a DataFlow edge and therefore is not returned by dfg_successors; inspect
outgoing_edges(access) or edges_between(access, field) when querying
declaration identity. Missing or ambiguous owner/type/field evidence emits no
reference.
pub struct NodeId(pub u32);
pub struct EdgeId(pub u32);Both provide new(u32) and as_u32(self) -> u32. NodeId implements
From<u32> and From<NodeId> for u32 (both directions); EdgeId implements
From<u32>. There is no .index() method — use as_u32() (or the .0
tuple field).
Six u32 fields (byte offsets are half-open [start, end); lines/columns are
0-indexed):
pub struct SourceRange {
pub start: u32,
pub end: u32,
pub start_line: u32,
pub start_col: u32,
pub end_line: u32,
pub end_col: u32,
}Constructors and helpers: new(start, end, start_line, start_col, end_line, end_col),
from_bytes(start, end) (lines/cols zeroed), len() -> u32, is_empty() -> bool,
to_text_range() -> text_size::TextRange, and Default (all zeros).
A #[non_exhaustive] enum of ~40 languages spanning systems, JVM, scripting,
functional, .NET, Apple, shell, query, markup/config, and the F1R3FLY.io
languages Rholang and MeTTa, plus Unknown (the Default).
| Method | Signature | Notes |
|---|---|---|
name |
fn name(&self) -> &'static str |
Display name (e.g. "C++"). |
extensions |
fn extensions(&self) -> &'static [&'static str] |
Common file extensions (plural). |
from_extension |
fn from_extension(ext: &str) -> Language |
Detect from an extension; returns Unknown (not Option) when unmatched. Leading . and case are ignored. |
is_systems |
fn is_systems(&self) -> bool |
Rust/C/C++/Go/Zig. |
is_jvm |
fn is_jvm(&self) -> bool |
Java/Kotlin/Scala/Groovy/Clojure. |
is_scripting |
fn is_scripting(&self) -> bool |
Python/JS/TS/Ruby/PHP/Perl/Lua. |
is_functional |
fn is_functional(&self) -> bool |
Haskell/OCaml/F#/Elixir/Erlang/Clojure/Lisp/Scheme. |
is_markup |
fn is_markup(&self) -> bool |
JSON/YAML/TOML/XML/HTML/CSS/Markdown. |
is_f1r3fly |
fn is_f1r3fly(&self) -> bool |
Rholang/MeTTa. |
paradigms |
fn paradigms(&self) -> &'static [Paradigm] |
Primary paradigms. |
Language also implements Display (via name()).
Imperative, Procedural, ObjectOriented, Functional, Logic,
Concurrent, Reactive, ProcessCalculus, Declarative, EventDriven. Method
name() -> &'static str; implements Display. Rholang reports
[Concurrent, ProcessCalculus]; MeTTa reports [Logic, Functional].
pub type Result<T> = std::result::Result<T, Error>;
pub enum Error {
Analysis(#[from] analysis::AnalysisError),
Construction(String),
PatternMatch(String),
#[cfg(feature = "gnn")] Gnn(String),
InvalidNodeId(NodeId),
InvalidEdgeId(EdgeId),
UnsupportedLanguage(String),
Io(#[from] std::io::Error), // From<std::io::Error>
#[cfg(feature = "serde")] Serialization(String),
}Error derives thiserror::Error (so it implements std::error::Error and
Display). There is no CpgError type. Gnn exists only with the gnn
feature; Serialization only with serde. From<std::io::Error> lets ?
propagate I/O errors from, e.g., build_file.
| Variant | Raised when |
|---|---|
Analysis(AnalysisError) |
An exact analysis rejects its node, projection, iteration limit, or resource budget. |
Construction(String) |
Parse failure, oversized input, or malformed graph construction. |
PatternMatch(String) |
A pattern-matching operation failed. |
Gnn(String) (gnn) |
A GNN operation failed. |
InvalidNodeId(NodeId) |
A referenced node id is absent. |
InvalidEdgeId(EdgeId) |
A referenced edge id is absent. |
UnsupportedLanguage(String) |
No grammar registered for a language (e.g. its lang-* feature is off). |
Io(std::io::Error) |
Filesystem read failure. |
Serialization(String) (serde) |
(De)serialization failure. |
Returned by CodePropertyGraph::stats(); a Debug + Clone + Default snapshot of
aggregate counts.
pub struct CpgStats {
pub node_count: usize,
pub edge_count: usize,
pub ast_edges: usize,
pub cfg_edges: usize,
pub dfg_edges: usize,
pub heap_edges: usize,
pub name_flow_edges: usize,
pub call_edges: usize,
pub function_count: usize,
pub class_count: usize,
pub cyclomatic_complexity: usize,
}Each edge count is edges().filter(kind_predicate).count(); function_count and
class_count come from functions()/classes(); cyclomatic_complexity
mirrors cyclomatic_complexity().
With the serde feature, all types on this page derive Serialize/Deserialize
(the vector field of GNN embeddings is the only exception, and lives in the
Pattern reference). There is no
bespoke export/import function or on-disk format — round-trip through your own
serde_json. To reconstruct a graph while preserving ids, use add_node_with_id
and add_edge_with_id rather than add_node/add_edge.
- Builder reference — how these graphs are constructed and how CFG/DFG/PDG overlays are added.
- Pattern reference — matching, similarity, GoF, algorithm detection, and GNN embeddings over the graph.
- Glossary — definitions of AST, CFG, DFG, PDG, and every other term used here.
- Architecture overview and data flow — the design behind the model.
- Component guides: graph overview, nodes, edges, traversal, deterministic projections, Martin package metrics, dominator analysis, and SCC analysis.
- Yamaguchi, F., Golde, N., Arp, D., Rieck, K. (2014). Modeling and Discovering Vulnerabilities with Code Property Graphs. 2014 IEEE Symposium on Security and Privacy. DOI: 10.1109/SP.2014.44
- McCabe, T. J. (1976). A Complexity Measure. IEEE Transactions on Software Engineering SE-2(4). DOI: 10.1109/TSE.1976.233837
- Martin, R. C. (1994). OO Design Quality Metrics: An Analysis of Dependencies. Object Mentor technical report. Archived report PDF. No DOI assigned.