Skip to content

Commit a1cda35

Browse files
committed
docs(semantic/cfg): add documentation for EdgeType (#14859)
adds some docs to `EdgeType`​ that i noticed lacked proper docs in #
1 parent 109f452 commit a1cda35

File tree

1 file changed

+117
-9
lines changed

1 file changed

+117
-9
lines changed

crates/oxc_cfg/src/lib.rs

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,133 @@ impl fmt::Display for BasicBlockId {
4747

4848
pub type Graph = petgraph::graph::DiGraph<BasicBlockId, EdgeType>;
4949

50+
/// Represents the different types of edges in the control flow graph.
51+
///
52+
/// Edges connect basic blocks and represent the possible paths of execution
53+
/// through a program. Each edge type describes a specific kind of control flow
54+
/// transition between blocks.
5055
#[derive(Debug, Clone)]
5156
pub enum EdgeType {
52-
/// Conditional jumps
57+
/// Represents a conditional branch taken when a condition evaluates to a specific value.
58+
///
59+
/// This edge connects the block containing a conditional statement (e.g., `if`, `while`, `for`)
60+
/// to the block that executes when the condition is satisfied. Jump edges are typically
61+
/// paired with Normal edges to represent the two possible outcomes of a conditional branch.
62+
///
63+
/// # Example
64+
/// ```js
65+
/// if (x > 0) { // Jump edge to consequent when true
66+
/// foo();
67+
/// }
68+
/// ```
5369
Jump,
54-
/// Normal control flow path
70+
71+
/// Represents sequential control flow that follows the natural execution order.
72+
///
73+
/// This is the default edge type for straightforward control flow transitions, such as
74+
/// falling through from one statement to the next, or the alternative path in a conditional
75+
/// branch. Normal edges represent the "else" path or continuation after a conditional.
76+
///
77+
/// # Example
78+
/// ```js
79+
/// statement1; // Normal edge to next statement
80+
/// statement2;
81+
/// ```
5582
Normal,
56-
/// Cyclic aka loops
83+
84+
/// Represents a backward edge that creates a cycle in the control flow graph.
85+
///
86+
/// Backedges point from the end of a loop body back to the loop's entry point (the loop
87+
/// condition or loop header). These edges are essential for identifying loops and analyzing
88+
/// cyclic control flow patterns. Each loop header should have exactly one backedge pointing
89+
/// to it.
90+
///
91+
/// # Example
92+
/// ```js
93+
/// while (condition) { // Backedge from end of body back to condition
94+
/// body;
95+
/// }
96+
/// ```
5797
Backedge,
58-
/// Marks start of a function subgraph
98+
99+
/// Marks the entry into a nested function's control flow subgraph.
100+
///
101+
/// This edge type separates the control flow of nested function declarations or expressions
102+
/// from the containing function's flow. NewFunction edges help maintain proper scope
103+
/// boundaries and prevent incorrect reachability analysis across function boundaries.
104+
/// These edges are typically filtered out during reachability checks.
105+
///
106+
/// # Example
107+
/// ```js
108+
/// function outer() {
109+
/// function inner() { // NewFunction edge to inner's CFG
110+
/// // inner's control flow
111+
/// }
112+
/// }
113+
/// ```
59114
NewFunction,
60-
/// Finally
115+
116+
/// Represents control flow into a `finally` block.
117+
///
118+
/// This edge connects blocks that may transfer control to a `finally` clause, regardless
119+
/// of whether execution is normal or exceptional. Finalize edges ensure that cleanup code
120+
/// in `finally` blocks is properly represented in the control flow graph, even when the
121+
/// try or catch blocks contain early returns or throws.
122+
///
123+
/// # Example
124+
/// ```js
125+
/// try {
126+
/// risky();
127+
/// } catch (e) {
128+
/// handle(e);
129+
/// } finally { // Finalize edges from try and catch blocks
130+
/// cleanup();
131+
/// }
132+
/// ```
61133
Finalize,
62-
/// Error Path
134+
135+
/// Represents control flow along an error/exception path.
136+
///
137+
/// Error edges connect blocks that may throw exceptions to their corresponding error
138+
/// handlers (catch blocks or finally blocks). The `ErrorEdgeKind` distinguishes between
139+
/// explicit throws and implicit error paths from operations that may throw.
140+
///
141+
/// # Example
142+
/// ```js
143+
/// try {
144+
/// mayThrow(); // Error edge to catch block
145+
/// } catch (e) {
146+
/// handle(e);
147+
/// }
148+
/// ```
63149
Error(ErrorEdgeKind),
64150

65-
// misc edges
151+
/// Represents a control flow path that can never be taken.
152+
///
153+
/// Unreachable edges mark portions of the control flow graph that are statically determined
154+
/// to be impossible to execute. These edges are filtered out during reachability analysis
155+
/// to avoid false positives. Common sources include code after unconditional returns or
156+
/// in branches with constant false conditions.
157+
///
158+
/// # Example
159+
/// ```js
160+
/// return;
161+
/// unreachableCode(); // Unreachable edge to this block
162+
/// ```
66163
Unreachable,
67-
/// Used to mark the end of a finalizer. It is an experimental approach might
68-
/// move to it's respective edge kind enum or get removed altogether.
164+
165+
/// Marks the convergence point after a finalizer completes.
166+
///
167+
/// This edge type is experimental and represents the point where control flow reconverges
168+
/// after executing a `finally` block. It helps distinguish between different paths through
169+
/// finally blocks (normal completion vs. exceptional completion). This variant may be
170+
/// refactored into a more specific edge kind enum or removed in future versions.
171+
///
172+
/// # Example
173+
/// ```js
174+
/// try { a(); } finally { b(); } // Join edge after finally completes
175+
/// c(); // Execution continues here
176+
/// ```
69177
Join,
70178
}
71179

0 commit comments

Comments
 (0)