feat(semantic/cfg): add Condition instruction. (#3567)

This commit is contained in:
Ali Rezvani 2024-06-13 11:47:24 +03:30 committed by GitHub
parent f2dfd667df
commit d9c5b33394
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 312 additions and 181 deletions

View file

@ -276,6 +276,7 @@ impl GetterReturn {
| InstructionKind::Break(_)
| InstructionKind::Continue(_)
| InstructionKind::Iteration(_)
| InstructionKind::Condition
| InstructionKind::Statement => {}
}
}

View file

@ -127,6 +127,7 @@ fn contains_return_statement<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> b
| InstructionKind::Break(_)
| InstructionKind::Continue(_)
| InstructionKind::Iteration(_)
| InstructionKind::Condition
| InstructionKind::Statement => {}
}
}

View file

@ -569,7 +569,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let start_of_condition_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
self.record_ast_nodes();
self.visit_expression(&stmt.test);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(start_of_condition_graph_ix, test_node);
/* cfg */
let end_of_condition_graph_ix = self.cfg.current_node_ix;
@ -675,10 +678,18 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let kind = AstKind::ConditionalExpression(self.alloc(expr));
self.enter_node(kind);
/* cfg - condition basic block */
let before_conditional_graph_ix = self.cfg.current_node_ix;
let start_of_condition_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
self.record_ast_nodes();
self.visit_expression(&expr.test);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(start_of_condition_graph_ix, test_node);
/* cfg */
let before_conditional_expr_graph_ix = self.cfg.current_node_ix;
let after_condition_graph_ix = self.cfg.current_node_ix;
// conditional expression basic block
let before_consequent_expr_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
@ -696,7 +707,12 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let after_alternate_graph_ix = self.cfg.current_node_ix;
/* bb after conditional expression joins consequent and alternate */
let after_conditional_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
self.cfg.add_edge(
before_conditional_graph_ix,
start_of_condition_graph_ix,
EdgeType::Normal,
);
self.cfg.add_edge(
after_consequent_expr_graph_ix,
@ -704,17 +720,15 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
EdgeType::Normal,
);
self.cfg.add_edge(
before_conditional_expr_graph_ix,
after_condition_graph_ix,
before_consequent_expr_graph_ix,
EdgeType::Normal,
EdgeType::Jump,
);
self.cfg.add_edge(
before_conditional_expr_graph_ix,
start_alternate_graph_ix,
EdgeType::Normal,
);
self.cfg.add_edge(after_condition_graph_ix, start_alternate_graph_ix, EdgeType::Normal);
self.cfg.add_edge(after_alternate_graph_ix, after_conditional_graph_ix, EdgeType::Normal);
/* cfg */
self.leave_node(kind);
}
@ -735,7 +749,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let test_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
if let Some(test) = &stmt.test {
self.record_ast_nodes();
self.visit_expression(test);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(test_graph_ix, test_node);
}
/* cfg */
@ -916,10 +933,18 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let kind = AstKind::IfStatement(self.alloc(stmt));
self.enter_node(kind);
/* cfg - condition basic block */
let before_if_stmt_graph_ix = self.cfg.current_node_ix;
let start_of_condition_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
self.record_ast_nodes();
self.visit_expression(&stmt.test);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(start_of_condition_graph_ix, test_node);
/* cfg */
let before_if_stmt_graph_ix = self.cfg.current_node_ix;
let after_test_graph_ix = self.cfg.current_node_ix;
let before_consequent_stmt_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
@ -944,13 +969,11 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
/* cfg - bb after if statement joins consequent and alternate */
let after_if_graph_ix = self.cfg.new_basic_block_normal();
self.cfg.add_edge(before_if_stmt_graph_ix, start_of_condition_graph_ix, EdgeType::Normal);
self.cfg.add_edge(after_consequent_stmt_graph_ix, after_if_graph_ix, EdgeType::Normal);
self.cfg.add_edge(
before_if_stmt_graph_ix,
before_consequent_stmt_graph_ix,
EdgeType::Normal,
);
self.cfg.add_edge(after_test_graph_ix, before_consequent_stmt_graph_ix, EdgeType::Jump);
if let Some((start_of_alternate_stmt_graph_ix, after_alternate_stmt_graph_ix)) =
else_graph_ix
@ -1105,13 +1128,16 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
self.enter_node(kind);
if let Some(expr) = &case.test {
self.record_ast_nodes();
self.visit_expression(expr);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(self.cfg.current_node_ix, test_node);
}
/* cfg */
let after_test_graph_ix = self.cfg.current_node_ix;
let statements_in_switch_graph_ix = self.cfg.new_basic_block_normal();
self.cfg.add_edge(after_test_graph_ix, statements_in_switch_graph_ix, EdgeType::Normal);
self.cfg.add_edge(after_test_graph_ix, statements_in_switch_graph_ix, EdgeType::Jump);
/* cfg */
self.visit_statements(&case.consequent);
@ -1274,7 +1300,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let condition_graph_ix = self.cfg.new_basic_block_normal();
/* cfg */
self.record_ast_nodes();
self.visit_expression(&stmt.test);
let test_node = self.retrieve_recorded_ast_nodes().into_iter().next();
self.cfg.append_condition_to(condition_graph_ix, test_node);
/* cfg - body basic block */
let body_graph_ix = self.cfg.new_basic_block_normal();

View file

@ -52,11 +52,15 @@ impl<'a> ControlFlowGraphBuilder<'a> {
ControlFlowGraph { graph: self.graph, basic_blocks: self.basic_blocks }
}
/// # Panics
pub fn current_basic_block(&mut self) -> &mut BasicBlock {
self.basic_block_mut(self.current_node_ix)
}
/// # Panics
pub fn basic_block_mut(&mut self, basic_block: BasicBlockId) -> &mut BasicBlock {
let idx = *self
.graph
.node_weight(self.current_node_ix)
.node_weight(basic_block)
.expect("expected `self.current_node_ix` to be a valid node index in self.graph");
self.basic_blocks
.get_mut(idx)
@ -145,6 +149,10 @@ impl<'a> ControlFlowGraphBuilder<'a> {
);
}
pub fn append_condition_to(&mut self, block: BasicBlockId, node: Option<AstNodeId>) {
self.push_instruction_to(block, InstructionKind::Condition, node);
}
pub fn append_iteration(&mut self, node: Option<AstNodeId>, kind: IterationInstructionKind) {
self.push_instruction(InstructionKind::Iteration(kind), node);
}
@ -195,7 +203,17 @@ impl<'a> ControlFlowGraphBuilder<'a> {
#[inline]
pub(self) fn push_instruction(&mut self, kind: InstructionKind, node_id: Option<AstNodeId>) {
self.current_basic_block().instructions.push(Instruction { kind, node_id });
self.push_instruction_to(self.current_node_ix, kind, node_id);
}
#[inline]
pub(self) fn push_instruction_to(
&mut self,
block: BasicBlockId,
kind: InstructionKind,
node_id: Option<AstNodeId>,
) {
self.basic_block_mut(block).instructions.push(Instruction { kind, node_id });
}
#[must_use]

View file

@ -27,6 +27,17 @@ impl<'a, 'b> DebugDotContext<'a, 'b> {
fn debug_ast_kind(self, id: AstNodeId) -> String {
self.0.kind(id).debug_name().into_owned()
}
fn try_eval_literal(self, id: AstNodeId) -> Option<String> {
match self.0.kind(id) {
AstKind::NumericLiteral(lit) => Some(lit.value.to_string()),
AstKind::BooleanLiteral(lit) => Some(lit.value.to_string()),
AstKind::StringLiteral(lit) => Some(lit.value.to_string()),
AstKind::BigintLiteral(lit) => Some(lit.raw.to_string()),
AstKind::NullLiteral(_) => Some("null".to_string()),
_ => None,
}
}
}
impl<'a, 'b> From<&'b AstNodes<'a>> for DebugDotContext<'a, 'b> {
@ -76,12 +87,13 @@ impl DisplayDot for Instruction {
InstructionKind::Statement => "statement",
InstructionKind::Unreachable => "unreachable",
InstructionKind::Throw => "throw",
InstructionKind::Condition => "condition",
InstructionKind::Iteration(IterationInstructionKind::Of) => "iteration <of>",
InstructionKind::Iteration(IterationInstructionKind::In) => "iteration <in>",
InstructionKind::Break(LabeledInstruction::Labeled) => "break <label>",
InstructionKind::Break(LabeledInstruction::Unlabeled) => "break",
InstructionKind::Continue(LabeledInstruction::Labeled) => "continue <label>",
InstructionKind::Continue(LabeledInstruction::Unlabeled) => "continue",
InstructionKind::Iteration(IterationInstructionKind::Of) => "iteration <of>",
InstructionKind::Iteration(IterationInstructionKind::In) => "iteration <in>",
InstructionKind::Return(ReturnInstructionKind::ImplicitUndefined) => {
"return <implicit undefined>"
}
@ -136,6 +148,12 @@ impl DebugDot for Instruction {
}
InstructionKind::Unreachable => "unreachable".to_string(),
InstructionKind::Throw => "throw".to_string(),
InstructionKind::Condition => self.node_id.map_or("None".to_string(), |id| {
format!(
"Condition({})",
ctx.try_eval_literal(id).unwrap_or_else(|| ctx.debug_ast_kind(id))
)
}),
InstructionKind::Iteration(ref kind) => {
format!(
"Iteration({} {} {})",

View file

@ -148,6 +148,7 @@ pub enum InstructionKind {
Break(LabeledInstruction),
Continue(LabeledInstruction),
Throw,
Condition,
Iteration(IterationInstructionKind),
}
#[derive(Debug, Clone)]

View file

@ -8,17 +8,20 @@ digraph {
1 [ label = "VariableDeclaration" ]
2 [ label = "" ]
3 [ label = "ExpressionStatement" ]
4 [ label = "" ]
4 [ label = "Condition(CallExpression)" ]
5 [ label = "" ]
6 [ label = "" ]
7 [ label = "" ]
1 -> 0 [ label = "Error(Implicit)" ]
3 -> 2 [ label = "Error(Implicit)" ]
1 -> 3 [ label = "NewFunction" ]
4 -> 2 [ label = "Error(Implicit)" ]
5 -> 2 [ label = "Error(Implicit)" ]
6 -> 2 [ label = "Error(Implicit)" ]
4 -> 6 [ label = "Normal" ]
7 -> 2 [ label = "Error(Implicit)" ]
3 -> 4 [ label = "Normal" ]
3 -> 5 [ label = "Normal" ]
5 -> 6 [ label = "Normal" ]
5 -> 7 [ label = "Normal" ]
4 -> 5 [ label = "Jump" ]
4 -> 6 [ label = "Normal" ]
6 -> 7 [ label = "Normal" ]
}

View file

@ -20,7 +20,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {
@ -30,3 +30,7 @@ bb5: {
bb6: {
}
bb7: {
}

View file

@ -6,15 +6,18 @@ input_file: crates/oxc_semantic/tests/integration/cfg_fixtures/conditional_expre
digraph {
0 [ label = "" ]
1 [ label = "VariableDeclaration" ]
2 [ label = "" ]
2 [ label = "Condition(CallExpression)" ]
3 [ label = "" ]
4 [ label = "VariableDeclaration" ]
4 [ label = "" ]
5 [ label = "VariableDeclaration" ]
1 -> 0 [ label = "Error(Implicit)" ]
2 -> 0 [ label = "Error(Implicit)" ]
3 -> 0 [ label = "Error(Implicit)" ]
4 -> 0 [ label = "Error(Implicit)" ]
2 -> 4 [ label = "Normal" ]
5 -> 0 [ label = "Error(Implicit)" ]
1 -> 2 [ label = "Normal" ]
1 -> 3 [ label = "Normal" ]
3 -> 4 [ label = "Normal" ]
3 -> 5 [ label = "Normal" ]
2 -> 3 [ label = "Jump" ]
2 -> 4 [ label = "Normal" ]
4 -> 5 [ label = "Normal" ]
}

View file

@ -12,7 +12,7 @@ bb1: {
}
bb2: {
condition
}
bb3: {
@ -20,5 +20,9 @@ bb3: {
}
bb4: {
}
bb5: {
statement
}

View file

@ -13,7 +13,7 @@ digraph {
6 [ label = "DoWhileStatement" ]
7 [ label = "BlockStatement\nbreak" ]
8 [ label = "unreachable" ]
9 [ label = "" ]
9 [ label = "Condition(true)" ]
10 [ label = "" ]
11 [ label = "" ]
12 [ label = "" ]

View file

@ -41,7 +41,7 @@ bb8: {
}
bb9: {
condition
}
bb10: {

View file

@ -8,7 +8,7 @@ digraph {
1 [ label = "" ]
2 [ label = "" ]
3 [ label = "ForStatement\nVariableDeclaration" ]
4 [ label = "" ]
4 [ label = "Condition(test)" ]
5 [ label = "" ]
6 [ label = "ExpressionStatement" ]
7 [ label = "ExpressionStatement" ]

View file

@ -21,7 +21,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {

View file

@ -8,36 +8,39 @@ digraph {
1 [ label = "" ]
2 [ label = "" ]
3 [ label = "IfStatement" ]
4 [ label = "" ]
4 [ label = "Condition(LogicalExpression)" ]
5 [ label = "" ]
6 [ label = "BlockStatement\nreturn <value>" ]
7 [ label = "unreachable" ]
8 [ label = "BlockStatement\nreturn <value>" ]
9 [ label = "unreachable" ]
10 [ label = "return <value>" ]
11 [ label = "unreachable" ]
12 [ label = "" ]
6 [ label = "" ]
7 [ label = "BlockStatement\nreturn <value>" ]
8 [ label = "unreachable" ]
9 [ label = "BlockStatement\nreturn <value>" ]
10 [ label = "unreachable" ]
11 [ label = "return <value>" ]
12 [ label = "unreachable" ]
13 [ label = "" ]
1 -> 0 [ label = "Error(Implicit)" ]
3 -> 2 [ label = "Error(Implicit)" ]
1 -> 3 [ label = "NewFunction" ]
4 -> 2 [ label = "Error(Implicit)" ]
5 -> 2 [ label = "Error(Implicit)" ]
3 -> 4 [ label = "Normal" ]
3 -> 5 [ label = "Normal" ]
4 -> 5 [ label = "Normal" ]
6 -> 2 [ label = "Error(Implicit)" ]
7 -> 2 [ label = "Error(Implicit)" ]
6 -> 7 [ label = "Unreachable" , style = "dotted" ]
8 -> 2 [ label = "Error(Implicit)" ]
9 -> 2 [ label = "Error(Implicit)" ]
8 -> 9 [ label = "Unreachable" , style = "dotted" ]
10 -> 2 [ label = "Error(Implicit)" ]
7 -> 10 [ label = "Normal" ]
4 -> 5 [ label = "Normal" ]
4 -> 6 [ label = "Normal" ]
5 -> 6 [ label = "Normal" ]
5 -> 8 [ label = "Normal" ]
9 -> 10 [ label = "Normal" ]
7 -> 2 [ label = "Error(Implicit)" ]
8 -> 2 [ label = "Error(Implicit)" ]
7 -> 8 [ label = "Unreachable" , style = "dotted" ]
9 -> 2 [ label = "Error(Implicit)" ]
10 -> 2 [ label = "Error(Implicit)" ]
9 -> 10 [ label = "Unreachable" , style = "dotted" ]
11 -> 2 [ label = "Error(Implicit)" ]
10 -> 11 [ label = "Unreachable" , style = "dotted" ]
12 -> 0 [ label = "Error(Implicit)" ]
1 -> 12 [ label = "Normal" ]
3 -> 4 [ label = "Normal" ]
8 -> 11 [ label = "Normal" ]
6 -> 7 [ label = "Jump" ]
3 -> 9 [ label = "Normal" ]
10 -> 11 [ label = "Normal" ]
12 -> 2 [ label = "Error(Implicit)" ]
11 -> 12 [ label = "Unreachable" , style = "dotted" ]
13 -> 0 [ label = "Error(Implicit)" ]
1 -> 13 [ label = "Normal" ]
}

View file

@ -20,7 +20,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {
@ -28,31 +28,35 @@ bb5: {
}
bb6: {
statement
return <value>
}
bb7: {
unreachable
}
bb8: {
statement
return <value>
}
bb9: {
bb8: {
unreachable
}
bb10: {
bb9: {
statement
return <value>
}
bb11: {
bb10: {
unreachable
}
bb11: {
return <value>
}
bb12: {
unreachable
}
bb13: {
}

View file

@ -11,15 +11,17 @@ digraph {
4 [ label = "" ]
5 [ label = "Iteration(IdentifierReference(array) in expr)" ]
6 [ label = "BlockStatement\nIfStatement" ]
7 [ label = "BlockStatement\nExpressionStatement\nbreak" ]
8 [ label = "unreachable" ]
9 [ label = "IfStatement" ]
10 [ label = "BlockStatement\nExpressionStatement\ncontinue" ]
11 [ label = "unreachable" ]
12 [ label = "" ]
13 [ label = "ExpressionStatement\nExpressionStatement" ]
14 [ label = "ExpressionStatement" ]
15 [ label = "" ]
7 [ label = "Condition(if cond)" ]
8 [ label = "BlockStatement\nExpressionStatement\nbreak" ]
9 [ label = "unreachable" ]
10 [ label = "IfStatement" ]
11 [ label = "Condition(else cond)" ]
12 [ label = "BlockStatement\nExpressionStatement\ncontinue" ]
13 [ label = "unreachable" ]
14 [ label = "" ]
15 [ label = "ExpressionStatement\nExpressionStatement" ]
16 [ label = "ExpressionStatement" ]
17 [ label = "" ]
1 -> 0 [ label = "Error(Implicit)" ]
3 -> 2 [ label = "Error(Implicit)" ]
1 -> 3 [ label = "NewFunction" ]
@ -28,28 +30,32 @@ digraph {
6 -> 2 [ label = "Error(Implicit)" ]
7 -> 2 [ label = "Error(Implicit)" ]
8 -> 2 [ label = "Error(Implicit)" ]
7 -> 8 [ label = "Unreachable" , style = "dotted" ]
9 -> 2 [ label = "Error(Implicit)" ]
8 -> 9 [ label = "Unreachable" , style = "dotted" ]
10 -> 2 [ label = "Error(Implicit)" ]
11 -> 2 [ label = "Error(Implicit)" ]
10 -> 11 [ label = "Unreachable" , style = "dotted" ]
12 -> 2 [ label = "Error(Implicit)" ]
11 -> 12 [ label = "Normal" ]
9 -> 10 [ label = "Normal" ]
9 -> 12 [ label = "Normal" ]
13 -> 2 [ label = "Error(Implicit)" ]
8 -> 13 [ label = "Normal" ]
6 -> 7 [ label = "Normal" ]
6 -> 9 [ label = "Normal" ]
12 -> 13 [ label = "Normal" ]
12 -> 13 [ label = "Unreachable" , style = "dotted" ]
14 -> 2 [ label = "Error(Implicit)" ]
10 -> 11 [ label = "Normal" ]
13 -> 14 [ label = "Normal" ]
11 -> 12 [ label = "Jump" ]
10 -> 14 [ label = "Normal" ]
15 -> 2 [ label = "Error(Implicit)" ]
6 -> 7 [ label = "Normal" ]
9 -> 15 [ label = "Normal" ]
7 -> 8 [ label = "Jump" ]
6 -> 10 [ label = "Normal" ]
14 -> 15 [ label = "Normal" ]
16 -> 2 [ label = "Error(Implicit)" ]
3 -> 4 [ label = "Normal" ]
4 -> 5 [ label = "Normal" ]
5 -> 6 [ label = "Jump" ]
13 -> 5 [ label = "Backedge" ]
5 -> 14 [ label = "Normal" ]
7 -> 14 [ label = "Jump" ]
10 -> 5 [ label = "Jump" ]
15 -> 0 [ label = "Error(Implicit)" ]
1 -> 15 [ label = "Normal" ]
15 -> 5 [ label = "Backedge" ]
5 -> 16 [ label = "Normal" ]
8 -> 16 [ label = "Jump" ]
12 -> 5 [ label = "Jump" ]
17 -> 0 [ label = "Error(Implicit)" ]
1 -> 17 [ label = "Normal" ]
}

View file

@ -34,42 +34,50 @@ bb6: {
}
bb7: {
condition
}
bb8: {
statement
statement
break
}
bb8: {
bb9: {
unreachable
}
bb9: {
bb10: {
statement
}
bb10: {
bb11: {
condition
}
bb12: {
statement
statement
continue
}
bb11: {
bb13: {
unreachable
}
bb12: {
}
bb13: {
statement
statement
}
bb14: {
statement
}
bb15: {
statement
statement
}
bb16: {
statement
}
bb17: {
}

View file

@ -9,27 +9,30 @@ digraph {
2 [ label = "" ]
3 [ label = "BlockStatement" ]
4 [ label = "LabeledStatement\nBlockStatement\nIfStatement" ]
5 [ label = "BlockStatement\nbreak <LABEL>" ]
6 [ label = "unreachable" ]
7 [ label = "" ]
5 [ label = "Condition(IdentifierReference(condition))" ]
6 [ label = "BlockStatement\nbreak <LABEL>" ]
7 [ label = "unreachable" ]
8 [ label = "" ]
9 [ label = "" ]
10 [ label = "" ]
1 -> 0 [ label = "Error(Implicit)" ]
3 -> 2 [ label = "Error(Explicit)" ]
4 -> 0 [ label = "Error(Implicit)" ]
2 -> 4 [ label = "Normal" ]
5 -> 0 [ label = "Error(Implicit)" ]
6 -> 0 [ label = "Error(Implicit)" ]
5 -> 6 [ label = "Unreachable" , style = "dotted" ]
7 -> 0 [ label = "Error(Implicit)" ]
6 -> 7 [ label = "Normal" ]
4 -> 5 [ label = "Normal" ]
4 -> 7 [ label = "Normal" ]
6 -> 7 [ label = "Unreachable" , style = "dotted" ]
8 -> 0 [ label = "Error(Implicit)" ]
4 -> 5 [ label = "Normal" ]
7 -> 8 [ label = "Normal" ]
5 -> 8 [ label = "Jump" ]
5 -> 6 [ label = "Jump" ]
4 -> 8 [ label = "Normal" ]
9 -> 0 [ label = "Error(Implicit)" ]
1 -> 3 [ label = "Normal" ]
3 -> 9 [ label = "Normal" ]
8 -> 9 [ label = "Normal" ]
6 -> 9 [ label = "Jump" ]
10 -> 0 [ label = "Error(Implicit)" ]
1 -> 3 [ label = "Normal" ]
3 -> 10 [ label = "Normal" ]
9 -> 10 [ label = "Normal" ]
}

View file

@ -26,16 +26,16 @@ bb4: {
}
bb5: {
condition
}
bb6: {
statement
break <label>
}
bb6: {
unreachable
}
bb7: {
unreachable
}
bb8: {
@ -45,3 +45,7 @@ bb8: {
bb9: {
}
bb10: {
}

View file

@ -6,47 +6,56 @@ input_file: crates/oxc_semantic/tests/integration/cfg_fixtures/logical_expressio
digraph {
0 [ label = "" ]
1 [ label = "IfStatement" ]
2 [ label = "" ]
2 [ label = "Condition(LogicalExpression)" ]
3 [ label = "" ]
4 [ label = "BlockStatement\nExpressionStatement" ]
5 [ label = "IfStatement" ]
6 [ label = "" ]
7 [ label = "" ]
8 [ label = "ExpressionStatement" ]
9 [ label = "IfStatement" ]
10 [ label = "" ]
11 [ label = "" ]
12 [ label = "ExpressionStatement" ]
4 [ label = "" ]
5 [ label = "BlockStatement\nExpressionStatement" ]
6 [ label = "IfStatement" ]
7 [ label = "Condition(LogicalExpression)" ]
8 [ label = "" ]
9 [ label = "" ]
10 [ label = "ExpressionStatement" ]
11 [ label = "IfStatement" ]
12 [ label = "Condition(LogicalExpression)" ]
13 [ label = "" ]
14 [ label = "" ]
15 [ label = "ExpressionStatement" ]
16 [ label = "" ]
1 -> 0 [ label = "Error(Implicit)" ]
2 -> 0 [ label = "Error(Implicit)" ]
3 -> 0 [ label = "Error(Implicit)" ]
1 -> 2 [ label = "Normal" ]
1 -> 3 [ label = "Normal" ]
2 -> 3 [ label = "Normal" ]
4 -> 0 [ label = "Error(Implicit)" ]
5 -> 0 [ label = "Error(Implicit)" ]
4 -> 5 [ label = "Normal" ]
2 -> 3 [ label = "Normal" ]
2 -> 4 [ label = "Normal" ]
3 -> 4 [ label = "Normal" ]
3 -> 5 [ label = "Normal" ]
5 -> 0 [ label = "Error(Implicit)" ]
6 -> 0 [ label = "Error(Implicit)" ]
7 -> 0 [ label = "Error(Implicit)" ]
1 -> 2 [ label = "Normal" ]
5 -> 6 [ label = "Normal" ]
5 -> 7 [ label = "Normal" ]
6 -> 7 [ label = "Normal" ]
4 -> 5 [ label = "Jump" ]
1 -> 6 [ label = "Normal" ]
7 -> 0 [ label = "Error(Implicit)" ]
8 -> 0 [ label = "Error(Implicit)" ]
9 -> 0 [ label = "Error(Implicit)" ]
8 -> 9 [ label = "Normal" ]
7 -> 8 [ label = "Normal" ]
7 -> 9 [ label = "Normal" ]
8 -> 9 [ label = "Normal" ]
10 -> 0 [ label = "Error(Implicit)" ]
11 -> 0 [ label = "Error(Implicit)" ]
9 -> 10 [ label = "Normal" ]
9 -> 11 [ label = "Normal" ]
6 -> 7 [ label = "Normal" ]
10 -> 11 [ label = "Normal" ]
9 -> 10 [ label = "Jump" ]
6 -> 11 [ label = "Normal" ]
12 -> 0 [ label = "Error(Implicit)" ]
13 -> 0 [ label = "Error(Implicit)" ]
14 -> 0 [ label = "Error(Implicit)" ]
12 -> 13 [ label = "Normal" ]
12 -> 14 [ label = "Normal" ]
13 -> 14 [ label = "Normal" ]
15 -> 0 [ label = "Error(Implicit)" ]
16 -> 0 [ label = "Error(Implicit)" ]
11 -> 12 [ label = "Normal" ]
11 -> 13 [ label = "Normal" ]
15 -> 16 [ label = "Normal" ]
14 -> 15 [ label = "Jump" ]
11 -> 16 [ label = "Normal" ]
}

View file

@ -12,7 +12,7 @@ bb1: {
}
bb2: {
condition
}
bb3: {
@ -20,42 +20,54 @@ bb3: {
}
bb4: {
statement
statement
}
bb5: {
statement
statement
}
bb6: {
statement
}
bb7: {
condition
}
bb8: {
statement
}
bb9: {
statement
}
bb10: {
statement
}
bb11: {
statement
}
bb12: {
statement
condition
}
bb13: {
}
bb14: {
}
bb15: {
statement
}
bb16: {
}

View file

@ -6,12 +6,12 @@ input_file: crates/oxc_semantic/tests/integration/cfg_fixtures/switch_in_while.j
digraph {
0 [ label = "" ]
1 [ label = "WhileStatement" ]
2 [ label = "" ]
2 [ label = "Condition(IdentifierReference(a))" ]
3 [ label = "BlockStatement\nSwitchStatement" ]
4 [ label = "" ]
4 [ label = "Condition(0)" ]
5 [ label = "ExpressionStatement\ncontinue" ]
6 [ label = "unreachable" ]
7 [ label = "" ]
7 [ label = "Condition(1)" ]
8 [ label = "ExpressionStatement" ]
9 [ label = "" ]
10 [ label = "" ]
@ -20,12 +20,12 @@ digraph {
3 -> 0 [ label = "Error(Implicit)" ]
4 -> 0 [ label = "Error(Implicit)" ]
5 -> 0 [ label = "Error(Implicit)" ]
4 -> 5 [ label = "Normal" ]
4 -> 5 [ label = "Jump" ]
6 -> 0 [ label = "Error(Implicit)" ]
5 -> 6 [ label = "Unreachable" , style = "dotted" ]
7 -> 0 [ label = "Error(Implicit)" ]
8 -> 0 [ label = "Error(Implicit)" ]
7 -> 8 [ label = "Normal" ]
7 -> 8 [ label = "Jump" ]
4 -> 7 [ label = "Normal" ]
6 -> 7 [ label = "Normal" ]
3 -> 4 [ label = "Normal" ]

View file

@ -12,7 +12,7 @@ bb1: {
}
bb2: {
condition
}
bb3: {
@ -21,7 +21,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {
@ -34,7 +34,7 @@ bb6: {
}
bb7: {
condition
}
bb8: {

View file

@ -8,18 +8,18 @@ digraph {
1 [ label = "" ]
2 [ label = "" ]
3 [ label = "SwitchStatement" ]
4 [ label = "" ]
4 [ label = "Condition(1)" ]
5 [ label = "ExpressionStatement\nbreak" ]
6 [ label = "unreachable" ]
7 [ label = "" ]
7 [ label = "Condition(2)" ]
8 [ label = "ExpressionStatement" ]
9 [ label = "" ]
9 [ label = "Condition(3)" ]
10 [ label = "ExpressionStatement\nbreak" ]
11 [ label = "unreachable" ]
12 [ label = "" ]
12 [ label = "Condition(4)" ]
13 [ label = "BlockStatement\nExpressionStatement\nVariableDeclaration\nExpressionStatement\nreturn <value>" ]
14 [ label = "unreachable" ]
15 [ label = "" ]
15 [ label = "Condition(5)" ]
16 [ label = "ExpressionStatement\nExpressionStatement\nExpressionStatement" ]
17 [ label = "" ]
18 [ label = "ExpressionStatement\nreturn <value>" ]
@ -32,28 +32,28 @@ digraph {
1 -> 3 [ label = "NewFunction" ]
4 -> 2 [ label = "Error(Implicit)" ]
5 -> 2 [ label = "Error(Implicit)" ]
4 -> 5 [ label = "Normal" ]
4 -> 5 [ label = "Jump" ]
6 -> 2 [ label = "Error(Implicit)" ]
5 -> 6 [ label = "Unreachable" , style = "dotted" ]
7 -> 2 [ label = "Error(Implicit)" ]
8 -> 2 [ label = "Error(Implicit)" ]
7 -> 8 [ label = "Normal" ]
7 -> 8 [ label = "Jump" ]
9 -> 2 [ label = "Error(Implicit)" ]
10 -> 2 [ label = "Error(Implicit)" ]
9 -> 10 [ label = "Normal" ]
9 -> 10 [ label = "Jump" ]
11 -> 2 [ label = "Error(Implicit)" ]
10 -> 11 [ label = "Unreachable" , style = "dotted" ]
12 -> 2 [ label = "Error(Implicit)" ]
13 -> 2 [ label = "Error(Implicit)" ]
12 -> 13 [ label = "Normal" ]
12 -> 13 [ label = "Jump" ]
14 -> 2 [ label = "Error(Implicit)" ]
13 -> 14 [ label = "Unreachable" , style = "dotted" ]
15 -> 2 [ label = "Error(Implicit)" ]
16 -> 2 [ label = "Error(Implicit)" ]
15 -> 16 [ label = "Normal" ]
15 -> 16 [ label = "Jump" ]
17 -> 2 [ label = "Error(Implicit)" ]
18 -> 2 [ label = "Error(Implicit)" ]
17 -> 18 [ label = "Normal" ]
17 -> 18 [ label = "Jump" ]
19 -> 2 [ label = "Error(Implicit)" ]
18 -> 19 [ label = "Unreachable" , style = "dotted" ]
4 -> 7 [ label = "Normal" ]

View file

@ -20,7 +20,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {
@ -33,7 +33,7 @@ bb6: {
}
bb7: {
condition
}
bb8: {
@ -41,7 +41,7 @@ bb8: {
}
bb9: {
condition
}
bb10: {
@ -54,7 +54,7 @@ bb11: {
}
bb12: {
condition
}
bb13: {
@ -70,7 +70,7 @@ bb14: {
}
bb15: {
condition
}
bb16: {

View file

@ -8,7 +8,7 @@ digraph {
1 [ label = "" ]
2 [ label = "" ]
3 [ label = "WhileStatement" ]
4 [ label = "" ]
4 [ label = "Condition(LogicalExpression)" ]
5 [ label = "" ]
6 [ label = "" ]
7 [ label = "BlockStatement\nreturn <value>" ]

View file

@ -20,7 +20,7 @@ bb3: {
}
bb4: {
condition
}
bb5: {