use std::fmt;
use std::ops::Deref;
use crate::analysis::core::{DataflowAnalyzer, Direction, StatementLocation};
use crate::analysis::forward::ForwardDataflowAnalysis;
use crate::{Block, BlockEnd, BlockId, Lowered};
pub struct TopologicalOrder {
blocks: Vec<BlockId>,
}
impl TopologicalOrder {
pub fn analyze(lowered: &Lowered<'_>) -> Self {
let mut fwd = ForwardDataflowAnalysis::new(lowered, TopologicalOrderAnalyzer::default());
fwd.run();
Self { blocks: fwd.analyzer.blocks }
}
}
impl Deref for TopologicalOrder {
type Target = Vec<BlockId>;
fn deref(&self) -> &Self::Target {
&self.blocks
}
}
impl fmt::Debug for TopologicalOrder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.blocks.iter()).finish()
}
}
#[derive(Default, Clone)]
struct TopologicalOrderAnalyzer {
blocks: Vec<BlockId>,
}
impl<'db, 'a> DataflowAnalyzer<'db, 'a> for TopologicalOrderAnalyzer {
type Info = ();
const DIRECTION: Direction = Direction::Forward;
fn initial_info(&mut self, _block_id: BlockId, _block_end: &'a BlockEnd<'db>) -> Self::Info {}
fn merge(
&mut self,
_lowered: &Lowered<'db>,
_statement_location: StatementLocation,
_info1: Self::Info,
_info2: Self::Info,
) -> Self::Info {
}
fn transfer_block(
&mut self,
_info: &mut Self::Info,
block_id: BlockId,
_block: &'a Block<'db>,
) {
self.blocks.push(block_id);
}
}