From 3fb9321887458c57f42a5555e7175c9b83e1274d Mon Sep 17 00:00:00 2001 From: DonIsaac <22823424+DonIsaac@users.noreply.github.com> Date: Mon, 7 Oct 2024 05:01:08 +0000 Subject: [PATCH] refactor(cfg): use IndexVec for storing basic blocks (#6323) Use an `IndexVec` when storing basic blocks. This makes the link between nodes in `.graph` and elements of `.basic_blocks` more clear. I had to rename `BasicBlockId` to `BlockNodeId` to avoid a name collision. I wasn't sure what else to name the `Idx` type for the basic blocks vec. --- Cargo.lock | 2 + crates/oxc_cfg/Cargo.toml | 2 + crates/oxc_cfg/src/block.rs | 3 -- crates/oxc_cfg/src/builder/context.rs | 36 ++++++------- crates/oxc_cfg/src/builder/mod.rs | 40 +++++++-------- crates/oxc_cfg/src/lib.rs | 51 ++++++++++++++----- crates/oxc_cfg/src/visit.rs | 6 +-- .../src/rules/eslint/no_fallthrough.rs | 14 ++--- .../src/rules/eslint/no_this_before_super.rs | 18 +++---- crates/oxc_semantic/examples/cfg.rs | 5 +- crates/oxc_semantic/src/node.rs | 12 ++--- 11 files changed, 108 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40ea6409967bd1..a5ca9086bd279a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1519,6 +1519,8 @@ version = "0.30.5" dependencies = [ "bitflags 2.6.0", "itertools", + "nonmax", + "oxc_index", "oxc_syntax", "petgraph", "rustc-hash", diff --git a/crates/oxc_cfg/Cargo.toml b/crates/oxc_cfg/Cargo.toml index cee54384e20910..714553027ca79c 100644 --- a/crates/oxc_cfg/Cargo.toml +++ b/crates/oxc_cfg/Cargo.toml @@ -21,9 +21,11 @@ test = false doctest = false [dependencies] +oxc_index = { workspace = true } oxc_syntax = { workspace = true } bitflags = { workspace = true } itertools = { workspace = true } +nonmax = { workspace = true } petgraph = { workspace = true } rustc-hash = { workspace = true } diff --git a/crates/oxc_cfg/src/block.rs b/crates/oxc_cfg/src/block.rs index eaa70011b45fb3..9d94e065c896d9 100644 --- a/crates/oxc_cfg/src/block.rs +++ b/crates/oxc_cfg/src/block.rs @@ -1,7 +1,4 @@ use oxc_syntax::node::NodeId; -use petgraph::stable_graph::NodeIndex; - -pub type BasicBlockId = NodeIndex; #[derive(Debug, Clone)] pub struct BasicBlock { diff --git a/crates/oxc_cfg/src/builder/context.rs b/crates/oxc_cfg/src/builder/context.rs index 3097f3053213bd..48cd6f659a0a0d 100644 --- a/crates/oxc_cfg/src/builder/context.rs +++ b/crates/oxc_cfg/src/builder/context.rs @@ -1,5 +1,5 @@ use super::ControlFlowGraphBuilder; -use crate::{BasicBlockId, EdgeType}; +use crate::{BlockNodeId, EdgeType}; bitflags::bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -15,9 +15,9 @@ bitflags::bitflags! { pub(super) struct Ctx<'a> { flags: CtxFlags, label: Option<&'a str>, - entries: Vec<(CtxFlags, BasicBlockId)>, - break_jmp: Option, - continue_jmp: Option, + entries: Vec<(CtxFlags, BlockNodeId)>, + break_jmp: Option, + continue_jmp: Option, } impl<'a> Ctx<'a> { @@ -29,11 +29,11 @@ impl<'a> Ctx<'a> { self.label.as_ref().is_some_and(|it| *it == label) } - fn r#break(&mut self, entry: BasicBlockId) { + fn r#break(&mut self, entry: BlockNodeId) { self.entries.push((CtxFlags::BREAK, entry)); } - fn r#continue(&mut self, entry: BasicBlockId) { + fn r#continue(&mut self, entry: BlockNodeId) { self.entries.push((CtxFlags::CONTINUE, entry)); } } @@ -41,19 +41,19 @@ impl<'a> Ctx<'a> { pub trait CtxCursor { #![allow(clippy::return_self_not_must_use)] /// Marks the break jump position in the current context. - fn mark_break(self, jmp_pos: BasicBlockId) -> Self; + fn mark_break(self, jmp_pos: BlockNodeId) -> Self; /// Marks the continue jump position in the current context. - fn mark_continue(self, jmp_pos: BasicBlockId) -> Self; + fn mark_continue(self, jmp_pos: BlockNodeId) -> Self; /// Creates a break entry in the current context. - fn r#break(self, bb: BasicBlockId) -> Self; + fn r#break(self, bb: BlockNodeId) -> Self; /// Creates a continue entry in the current context. - fn r#continue(self, bb: BasicBlockId) -> Self; + fn r#continue(self, bb: BlockNodeId) -> Self; } pub struct QueryCtx<'a, 'c>(&'c mut ControlFlowGraphBuilder<'a>, /* label */ Option<&'a str>); impl<'a, 'c> CtxCursor for QueryCtx<'a, 'c> { - fn mark_break(self, jmp_pos: BasicBlockId) -> Self { + fn mark_break(self, jmp_pos: BlockNodeId) -> Self { self.0.in_break_context(self.1, |ctx| { debug_assert!(ctx.break_jmp.is_none()); ctx.break_jmp = Some(jmp_pos); @@ -61,7 +61,7 @@ impl<'a, 'c> CtxCursor for QueryCtx<'a, 'c> { self } - fn mark_continue(self, jmp_pos: BasicBlockId) -> Self { + fn mark_continue(self, jmp_pos: BlockNodeId) -> Self { self.0.in_continue_context(self.1, |ctx| { debug_assert!(ctx.continue_jmp.is_none()); ctx.continue_jmp = Some(jmp_pos); @@ -69,14 +69,14 @@ impl<'a, 'c> CtxCursor for QueryCtx<'a, 'c> { self } - fn r#break(self, bb: BasicBlockId) -> Self { + fn r#break(self, bb: BlockNodeId) -> Self { self.0.in_break_context(self.1, |ctx| { ctx.r#break(bb); }); self } - fn r#continue(self, bb: BasicBlockId) -> Self { + fn r#continue(self, bb: BlockNodeId) -> Self { self.0.in_continue_context(self.1, |ctx| { ctx.r#continue(bb); }); @@ -192,24 +192,24 @@ impl<'a, 'c> RefCtxCursor<'a, 'c> { } impl<'a, 'c> CtxCursor for RefCtxCursor<'a, 'c> { - fn mark_break(self, jmp_pos: BasicBlockId) -> Self { + fn mark_break(self, jmp_pos: BlockNodeId) -> Self { debug_assert!(self.0.break_jmp.is_none()); self.0.break_jmp = Some(jmp_pos); self } - fn mark_continue(self, jmp_pos: BasicBlockId) -> Self { + fn mark_continue(self, jmp_pos: BlockNodeId) -> Self { debug_assert!(self.0.continue_jmp.is_none()); self.0.continue_jmp = Some(jmp_pos); self } - fn r#break(self, bb: BasicBlockId) -> Self { + fn r#break(self, bb: BlockNodeId) -> Self { self.0.r#break(bb); self } - fn r#continue(self, bb: BasicBlockId) -> Self { + fn r#continue(self, bb: BlockNodeId) -> Self { self.0.r#continue(bb); self } diff --git a/crates/oxc_cfg/src/builder/mod.rs b/crates/oxc_cfg/src/builder/mod.rs index 8497baaec13e13..c325bbe264ea87 100644 --- a/crates/oxc_cfg/src/builder/mod.rs +++ b/crates/oxc_cfg/src/builder/mod.rs @@ -2,28 +2,29 @@ mod context; use context::Ctx; pub use context::{CtxCursor, CtxFlags}; +use oxc_index::IndexVec; use oxc_syntax::node::NodeId; use petgraph::Direction; use super::{ - BasicBlock, BasicBlockId, ControlFlowGraph, EdgeType, ErrorEdgeKind, Graph, Instruction, + BasicBlock, BlockNodeId, ControlFlowGraph, EdgeType, ErrorEdgeKind, Graph, Instruction, InstructionKind, IterationInstructionKind, LabeledInstruction, }; -use crate::ReturnInstructionKind; +use crate::{BasicBlockId, ReturnInstructionKind}; #[derive(Debug, Default)] -struct ErrorHarness(ErrorEdgeKind, BasicBlockId); +struct ErrorHarness(ErrorEdgeKind, BlockNodeId); #[derive(Debug, Default)] pub struct ControlFlowGraphBuilder<'a> { pub graph: Graph, - pub basic_blocks: Vec, - pub current_node_ix: BasicBlockId, + pub basic_blocks: IndexVec, + pub current_node_ix: BlockNodeId, ctx_stack: Vec>, /// Contains the error unwinding path represented as a stack of `ErrorHarness`es error_path: Vec, /// Stack of finalizers, the top most element is always the appropriate one for current node. - finalizers: Vec>, + finalizers: Vec>, } impl<'a> ControlFlowGraphBuilder<'a> { @@ -36,7 +37,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { } /// # Panics - pub fn basic_block(&self, basic_block: BasicBlockId) -> &BasicBlock { + pub fn basic_block(&self, basic_block: BlockNodeId) -> &BasicBlock { let idx = *self .graph .node_weight(basic_block) @@ -47,7 +48,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { } /// # Panics - pub fn basic_block_mut(&mut self, basic_block: BasicBlockId) -> &mut BasicBlock { + pub fn basic_block_mut(&mut self, basic_block: BlockNodeId) -> &mut BasicBlock { let idx = *self .graph .node_weight(basic_block) @@ -57,15 +58,14 @@ impl<'a> ControlFlowGraphBuilder<'a> { .expect("expected `self.current_node_ix` to be a valid node index in self.graph") } - pub(self) fn new_basic_block(&mut self) -> BasicBlockId { + pub(self) fn new_basic_block(&mut self) -> BlockNodeId { // current length would be the index of block we are adding on the next line. - let basic_block_ix = self.basic_blocks.len(); - self.basic_blocks.push(BasicBlock::new()); + let basic_block_ix = self.basic_blocks.push(BasicBlock::new()); self.graph.add_node(basic_block_ix) } #[must_use] - pub fn new_basic_block_function(&mut self) -> BasicBlockId { + pub fn new_basic_block_function(&mut self) -> BlockNodeId { // we might want to differentiate between function blocks and normal blocks down the road. self.new_basic_block_normal() } @@ -73,7 +73,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { /// # Panics /// if there is no error harness to attach to. #[must_use] - pub fn new_basic_block_normal(&mut self) -> BasicBlockId { + pub fn new_basic_block_normal(&mut self) -> BlockNodeId { let graph_ix = self.new_basic_block(); self.current_node_ix = graph_ix; @@ -89,7 +89,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { graph_ix } - pub fn add_edge(&mut self, a: BasicBlockId, b: BasicBlockId, weight: EdgeType) { + pub fn add_edge(&mut self, a: BlockNodeId, b: BlockNodeId, weight: EdgeType) { if matches!(weight, EdgeType::NewFunction) { self.basic_block_mut(b).mark_as_reachable(); } else if matches!(weight, EdgeType::Unreachable) || self.basic_block(a).is_unreachable() { @@ -117,7 +117,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { /// Creates and push a new `BasicBlockId` onto `self.error_path` stack. /// Returns the `BasicBlockId` of the created error harness block. - pub fn attach_error_harness(&mut self, kind: ErrorEdgeKind) -> BasicBlockId { + pub fn attach_error_harness(&mut self, kind: ErrorEdgeKind) -> BlockNodeId { let graph_ix = self.new_basic_block(); self.error_path.push(ErrorHarness(kind, graph_ix)); graph_ix @@ -126,7 +126,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { /// # Panics /// if there is no error harness pushed onto the stack, /// Or last harness doesn't match the expected `BasicBlockId`. - pub fn release_error_harness(&mut self, expect: BasicBlockId) { + pub fn release_error_harness(&mut self, expect: BlockNodeId) { let harness = self .error_path .pop() @@ -139,7 +139,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { /// Creates and push a new `BasicBlockId` onto `self.finalizers` stack. /// Returns the `BasicBlockId` of the created finalizer block. - pub fn attach_finalizer(&mut self) -> BasicBlockId { + pub fn attach_finalizer(&mut self) -> BlockNodeId { let graph_ix = self.new_basic_block(); self.finalizers.push(Some(graph_ix)); graph_ix @@ -156,7 +156,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { /// # Panics /// if last finalizer doesn't match the expected `BasicBlockId`. - pub fn release_finalizer(&mut self, expect: BasicBlockId) { + pub fn release_finalizer(&mut self, expect: BlockNodeId) { // return early if there is no finalizer. let Some(finalizer) = self.finalizers.pop() else { return }; assert_eq!( @@ -166,7 +166,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { ); } - pub fn append_condition_to(&mut self, block: BasicBlockId, node: Option) { + pub fn append_condition_to(&mut self, block: BlockNodeId, node: Option) { self.push_instruction_to(block, InstructionKind::Condition, node); } @@ -228,7 +228,7 @@ impl<'a> ControlFlowGraphBuilder<'a> { #[inline] pub(self) fn push_instruction_to( &mut self, - block: BasicBlockId, + block: BlockNodeId, kind: InstructionKind, node_id: Option, ) { diff --git a/crates/oxc_cfg/src/lib.rs b/crates/oxc_cfg/src/lib.rs index 48185cefc954ab..05ce74ce157dc4 100644 --- a/crates/oxc_cfg/src/lib.rs +++ b/crates/oxc_cfg/src/lib.rs @@ -3,7 +3,11 @@ mod builder; pub mod dot; pub mod visit; +use std::fmt; + use itertools::Itertools; +use nonmax::NonMaxU32; +use oxc_index::{Idx, IndexVec}; use petgraph::{ visit::{Control, DfsEvent, EdgeRef}, Direction, @@ -23,7 +27,30 @@ pub use builder::{ControlFlowGraphBuilder, CtxCursor, CtxFlags}; pub use dot::DisplayDot; use visit::set_depth_first_search; -pub type Graph = petgraph::graph::DiGraph; +pub type BlockNodeId = petgraph::stable_graph::NodeIndex; +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct BasicBlockId(NonMaxU32); + +impl Idx for BasicBlockId { + #[allow(clippy::cast_possible_truncation)] + fn from_usize(idx: usize) -> Self { + assert!(idx < u32::MAX as usize); + // SAFETY: We just checked `idx` is valid for `NonMaxU32` + Self(unsafe { NonMaxU32::new_unchecked(idx as u32) }) + } + + fn index(self) -> usize { + self.0.get() as usize + } +} + +impl fmt::Display for BasicBlockId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +pub type Graph = petgraph::graph::DiGraph; #[derive(Debug, Clone)] pub enum EdgeType { @@ -65,7 +92,7 @@ pub enum EvalConstConditionResult { #[derive(Debug)] pub struct ControlFlowGraph { pub graph: Graph, - pub basic_blocks: Vec, + pub basic_blocks: IndexVec, } impl ControlFlowGraph { @@ -74,25 +101,25 @@ impl ControlFlowGraph { } /// # Panics - pub fn basic_block(&self, id: BasicBlockId) -> &BasicBlock { + pub fn basic_block(&self, id: BlockNodeId) -> &BasicBlock { let ix = *self.graph.node_weight(id).expect("expected a valid node id in self.graph"); self.basic_blocks.get(ix).expect("expected a valid node id in self.basic_blocks") } /// # Panics - pub fn basic_block_mut(&mut self, id: BasicBlockId) -> &mut BasicBlock { + pub fn basic_block_mut(&mut self, id: BlockNodeId) -> &mut BasicBlock { let ix = *self.graph.node_weight(id).expect("expected a valid node id in self.graph"); self.basic_blocks.get_mut(ix).expect("expected a valid node id in self.basic_blocks") } - pub fn is_reachable(&self, from: BasicBlockId, to: BasicBlockId) -> bool { + pub fn is_reachable(&self, from: BlockNodeId, to: BlockNodeId) -> bool { self.is_reachable_filtered(from, to, |_| Control::Continue) } - pub fn is_reachable_filtered Control>( + pub fn is_reachable_filtered Control>( &self, - from: BasicBlockId, - to: BasicBlockId, + from: BlockNodeId, + to: BlockNodeId, filter: F, ) -> bool { if from == to { @@ -127,13 +154,13 @@ impl ControlFlowGraph { /// Otherwise returns `Some(loop_start, loop_end)`. pub fn is_infinite_loop_start( &self, - node: BasicBlockId, + node: BlockNodeId, try_eval_const_condition: F, - ) -> Option<(BasicBlockId, BasicBlockId)> + ) -> Option<(BlockNodeId, BlockNodeId)> where F: Fn(&Instruction) -> EvalConstConditionResult, { - fn get_jump_target(graph: &Graph, node: BasicBlockId) -> Option { + fn get_jump_target(graph: &Graph, node: BlockNodeId) -> Option { graph .edges_directed(node, Direction::Outgoing) .find_or_first(|e| matches!(e.weight(), EdgeType::Jump)) @@ -186,7 +213,7 @@ impl ControlFlowGraph { } } - pub fn is_cyclic(&self, node: BasicBlockId) -> bool { + pub fn is_cyclic(&self, node: BlockNodeId) -> bool { set_depth_first_search(&self.graph, Some(node), |event| match event { DfsEvent::BackEdge(_, id) if id == node => Err(()), _ => Ok(()), diff --git a/crates/oxc_cfg/src/visit.rs b/crates/oxc_cfg/src/visit.rs index 72f3d651ab0014..2e65e0f03f0335 100644 --- a/crates/oxc_cfg/src/visit.rs +++ b/crates/oxc_cfg/src/visit.rs @@ -6,18 +6,18 @@ use petgraph::{ }; use rustc_hash::FxHashSet; -use crate::BasicBlockId; +use crate::BlockNodeId; /// # Panics pub fn neighbors_filtered_by_edge_weight( graph: &Graph, - node: BasicBlockId, + node: BlockNodeId, edge_filter: &F, visitor: &mut G, ) -> Vec where F: Fn(&EdgeWeight) -> Option, - G: FnMut(&BasicBlockId, State) -> (State, bool), + G: FnMut(&BlockNodeId, State) -> (State, bool), { let mut q = vec![]; let mut final_states = vec![]; diff --git a/crates/oxc_linter/src/rules/eslint/no_fallthrough.rs b/crates/oxc_linter/src/rules/eslint/no_fallthrough.rs index 028980351280da..8fce6e0fdd48a5 100644 --- a/crates/oxc_linter/src/rules/eslint/no_fallthrough.rs +++ b/crates/oxc_linter/src/rules/eslint/no_fallthrough.rs @@ -11,7 +11,7 @@ use oxc_cfg::{ visit::{neighbors_filtered_by_edge_weight, EdgeRef}, Direction, }, - BasicBlockId, EdgeType, ErrorEdgeKind, InstructionKind, + BlockNodeId, EdgeType, ErrorEdgeKind, InstructionKind, }; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; @@ -274,7 +274,7 @@ impl Rule for NoFallthrough { return; }; - let fallthroughs: FxHashSet = neighbors_filtered_by_edge_weight( + let fallthroughs: FxHashSet = neighbors_filtered_by_edge_weight( graph, switch_id, &|e| match e { @@ -283,7 +283,7 @@ impl Rule for NoFallthrough { } _ => Some(None), }, - &mut |node, last_cond: Option| { + &mut |node, last_cond: Option| { let node = *node; if node == switch_id { @@ -448,10 +448,10 @@ fn get_switch_semantic_cases( node: &AstNode, switch: &SwitchStatement, ) -> ( - Vec, - FxHashMap, - /* default */ Option, - /* exit */ Option, + Vec, + FxHashMap, + /* default */ Option, + /* exit */ Option, ) { let cfg = ctx.cfg(); let graph = cfg.graph(); diff --git a/crates/oxc_linter/src/rules/eslint/no_this_before_super.rs b/crates/oxc_linter/src/rules/eslint/no_this_before_super.rs index db4fb50439d5ec..eb1b9e28059a2c 100644 --- a/crates/oxc_linter/src/rules/eslint/no_this_before_super.rs +++ b/crates/oxc_linter/src/rules/eslint/no_this_before_super.rs @@ -4,7 +4,7 @@ use oxc_ast::{ }; use oxc_cfg::{ graph::visit::{neighbors_filtered_by_edge_weight, EdgeRef}, - BasicBlockId, ControlFlowGraph, EdgeType, ErrorEdgeKind, + BlockNodeId, ControlFlowGraph, EdgeType, ErrorEdgeKind, }; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; @@ -50,7 +50,7 @@ enum DefinitelyCallsThisBeforeSuper { #[default] No, Yes, - Maybe(BasicBlockId), + Maybe(BlockNodeId), } impl Rule for NoThisBeforeSuper { @@ -60,9 +60,9 @@ impl Rule for NoThisBeforeSuper { // first pass -> find super calls and local violations let mut wanted_nodes = Vec::new(); - let mut basic_blocks_with_super_called = FxHashSet::::default(); + let mut basic_blocks_with_super_called = FxHashSet::::default(); let mut basic_blocks_with_local_violations = - FxHashMap::>::default(); + FxHashMap::>::default(); for node in semantic.nodes() { match node.kind() { AstKind::Function(_) | AstKind::ArrowFunctionExpression(_) => { @@ -151,9 +151,9 @@ impl NoThisBeforeSuper { fn analyze( cfg: &ControlFlowGraph, - id: BasicBlockId, - basic_blocks_with_super_called: &FxHashSet, - basic_blocks_with_local_violations: &FxHashMap>, + id: BlockNodeId, + basic_blocks_with_super_called: &FxHashSet, + basic_blocks_with_local_violations: &FxHashMap>, follow_join: bool, ) -> Vec { neighbors_filtered_by_edge_weight( @@ -211,8 +211,8 @@ impl NoThisBeforeSuper { fn check_for_violation( cfg: &ControlFlowGraph, output: Vec, - basic_blocks_with_super_called: &FxHashSet, - basic_blocks_with_local_violations: &FxHashMap>, + basic_blocks_with_super_called: &FxHashSet, + basic_blocks_with_local_violations: &FxHashMap>, ) -> bool { // Deciding whether we definitely call this before super in all // codepaths is as simple as seeing if any individual codepath diff --git a/crates/oxc_semantic/examples/cfg.rs b/crates/oxc_semantic/examples/cfg.rs index b2e16bda35dc5f..02e4a3abb7a6cb 100644 --- a/crates/oxc_semantic/examples/cfg.rs +++ b/crates/oxc_semantic/examples/cfg.rs @@ -86,10 +86,9 @@ fn main() -> std::io::Result<()> { let basic_blocks_printed = cfg .basic_blocks - .iter() - .map(DisplayDot::display_dot) - .enumerate() + .iter_enumerated() .map(|(i, it)| { + let it = it.display_dot(); format!( "bb{i}: {{\n{}\n---\n{}\n}}", it.lines().map(|x| format!("\t{}", x.trim())).join("\n"), diff --git a/crates/oxc_semantic/src/node.rs b/crates/oxc_semantic/src/node.rs index 50bda824851b37..3fd50c69a00b4a 100644 --- a/crates/oxc_semantic/src/node.rs +++ b/crates/oxc_semantic/src/node.rs @@ -1,5 +1,5 @@ use oxc_ast::AstKind; -use oxc_cfg::BasicBlockId; +use oxc_cfg::BlockNodeId; use oxc_index::IndexVec; use oxc_span::GetSpan; pub use oxc_syntax::node::{NodeFlags, NodeId}; @@ -17,7 +17,7 @@ pub struct AstNode<'a> { scope_id: ScopeId, /// Associated `BasicBlockId` in CFG (initialized by control_flow) - cfg_id: BasicBlockId, + cfg_id: BlockNodeId, flags: NodeFlags, } @@ -27,7 +27,7 @@ impl<'a> AstNode<'a> { pub(crate) fn new( kind: AstKind<'a>, scope_id: ScopeId, - cfg_id: BasicBlockId, + cfg_id: BlockNodeId, flags: NodeFlags, id: NodeId, ) -> Self { @@ -44,7 +44,7 @@ impl<'a> AstNode<'a> { /// /// See [oxc_cfg::ControlFlowGraph] for more information. #[inline] - pub fn cfg_id(&self) -> BasicBlockId { + pub fn cfg_id(&self) -> BlockNodeId { self.cfg_id } @@ -236,7 +236,7 @@ impl<'a> AstNodes<'a> { kind: AstKind<'a>, scope_id: ScopeId, parent_node_id: NodeId, - cfg_id: BasicBlockId, + cfg_id: BlockNodeId, flags: NodeFlags, ) -> NodeId { let node_id = self.parent_ids.push(Some(parent_node_id)); @@ -250,7 +250,7 @@ impl<'a> AstNodes<'a> { &mut self, kind: AstKind<'a>, scope_id: ScopeId, - cfg_id: BasicBlockId, + cfg_id: BlockNodeId, flags: NodeFlags, ) -> NodeId { let node_id = self.parent_ids.push(None);