use crate::DeadCodeEliminator;
use leo_ast::{
AssignStatement,
Block,
ConsoleStatement,
DefinitionPlace,
DefinitionStatement,
ExpressionReconstructor,
ExpressionStatement,
IterationStatement,
Statement,
StatementReconstructor,
};
impl StatementReconstructor for DeadCodeEliminator<'_> {
fn reconstruct_assign(&mut self, _input: AssignStatement) -> (Statement, Self::AdditionalOutput) {
panic!("`AssignStatement`s should not exist in the AST at this phase of compilation.")
}
fn reconstruct_block(&mut self, block: Block) -> (Block, Self::AdditionalOutput) {
self.statements_before += block.statements.iter().filter(|stmt| !stmt.is_empty()).count() as u32;
let mut statements: Vec<Statement> =
block.statements.into_iter().rev().map(|statement| self.reconstruct_statement(statement).0).collect();
statements.retain(|stmt| !stmt.is_empty());
statements.reverse();
self.statements_after += statements.len() as u32;
(Block { statements, span: block.span, id: block.id }, Default::default())
}
fn reconstruct_console(&mut self, _: ConsoleStatement) -> (Statement, Self::AdditionalOutput) {
panic!("`ConsoleStatement`s should not be in the AST at this phase of compilation.")
}
fn reconstruct_definition(&mut self, mut input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
let lhs_is_used = match &input.place {
DefinitionPlace::Single(identifier) => self.used_variables.contains(&identifier.name),
DefinitionPlace::Multiple(identifiers) => {
identifiers.iter().any(|identifier| self.used_variables.contains(&identifier.name))
}
};
if !lhs_is_used && self.side_effect_free(&input.value) {
(Statement::dummy(), Default::default())
} else {
input.value = self.reconstruct_expression(input.value).0;
(Statement::Definition(input), Default::default())
}
}
fn reconstruct_iteration(&mut self, _: IterationStatement) -> (Statement, Self::AdditionalOutput) {
panic!("`IterationStatement`s should not be in the AST at this phase of compilation.");
}
fn reconstruct_expression_statement(
&mut self,
mut input: ExpressionStatement,
) -> (Statement, Self::AdditionalOutput) {
if self.side_effect_free(&input.expression) {
(Statement::dummy(), Default::default())
} else {
input.expression = self.reconstruct_expression(input.expression).0;
(Statement::Expression(input), Default::default())
}
}
}