# Control Flow Graph (CFG)
Version: 1.1.1
Last Updated: January 23, 2026
Label-Level Scaffold (v0.6.8)
- Nodes: labels (+
__ENTRY__), edges fromjump/call. - Entry preference:
startlabel, else first label. - Detections:
RENPY:UNDEFINED_JUMP_TARGET,RENPY:UNREACHABLE_LABEL. - Debug:
branchpy analyze <project> --debug-cfg cfg.dot(visualize with Graphviz).
Statement-Level SAE CFG
- Nodes: every statement (say, python, jump, return, menu, choice).
- Edge types:
SEQ,JUMP,JUMP_DYNAMIC,BRANCH_TRUE/BRANCH_FALSE,CALL(future). - Terminal nodes (jump/return) do not emit
SEQedges. - Menu decomposition: menu node plus choice nodes per option; nested menus supported.
- Dynamic jump resolution: semantics catalog + dataflow transforms; unresolved jumps marked warning, not fatal.
Metadata
- Node metadata: file, line, kind, text/snippet, parent label, indentation.
- Edge metadata: resolution method, confidence, original expression for dynamic jumps.
Validation Rules
- Unresolved dynamic jump → warning (
dynamic_jump_unresolved). - Semantics miss → info (
semantics_miss) for functions not in catalog. - Orphaned statements after terminal nodes flagged as unreachable.
Metrics
- Path count, cyclomatic complexity, branching factor, nesting depth, incoming/outgoing jumps/calls per label.
- Cached propagation yields O(1) lookups on repeat analyses; cache clearing supported.
CLI Hooks
branchpy semantics2 flow --project <path> [--json] [--label <name>]— flow metrics and warnings.branchpy analyze --debug-cfg cfg.dot— export DOT for visualization.
Invariants
- Dynamic resolution never blocks analysis; unresolved paths are surfaced as warnings.
- No SEQ edges after terminal statements; menu branching explicitly modeled.
- CFG outputs are deterministic for a given source tree and semantics catalog.