leo_passes/function_inlining/
inline_statement.rsuse crate::FunctionInliner;
use leo_ast::{
AssignStatement,
Block,
ConditionalStatement,
ConsoleStatement,
DefinitionStatement,
Expression,
ExpressionReconstructor,
ExpressionStatement,
IterationStatement,
Statement,
StatementReconstructor,
};
impl StatementReconstructor for FunctionInliner<'_> {
fn reconstruct_assign(&mut self, input: AssignStatement) -> (Statement, Self::AdditionalOutput) {
let (value, mut statements) = self.reconstruct_expression(input.value.clone());
match (input.place, value) {
(Expression::Tuple(left), Expression::Tuple(right)) if left.elements.len() == right.elements.len() => {
statements.extend(left.elements.into_iter().zip(right.elements).map(|(lhs, rhs)| {
Statement::Assign(Box::new(AssignStatement {
place: lhs,
value: rhs,
span: Default::default(),
id: self.node_builder.next_id(),
}))
}));
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
}
(place, value) => (
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: input.id })),
statements,
),
}
}
fn reconstruct_block(&mut self, block: Block) -> (Block, Self::AdditionalOutput) {
let mut statements = Vec::with_capacity(block.statements.len());
for statement in block.statements {
let (reconstructed_statement, additional_statements) = self.reconstruct_statement(statement);
statements.extend(additional_statements);
statements.push(reconstructed_statement);
}
(Block { span: block.span, statements, id: block.id }, Default::default())
}
fn reconstruct_conditional(&mut self, input: ConditionalStatement) -> (Statement, Self::AdditionalOutput) {
if !self.is_async {
unreachable!("`ConditionalStatement`s should not be in the AST at this phase of compilation.")
} else {
(
Statement::Conditional(ConditionalStatement {
condition: self.reconstruct_expression(input.condition).0,
then: self.reconstruct_block(input.then).0,
otherwise: input.otherwise.map(|n| Box::new(self.reconstruct_statement(*n).0)),
span: input.span,
id: input.id,
}),
Default::default(),
)
}
}
fn reconstruct_console(&mut self, _: ConsoleStatement) -> (Statement, Self::AdditionalOutput) {
unreachable!("`ConsoleStatement`s should not be in the AST at this phase of compilation.")
}
fn reconstruct_definition(&mut self, _: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
unreachable!("`DefinitionStatement`s should not exist in the AST at this phase of compilation.")
}
fn reconstruct_expression_statement(&mut self, input: ExpressionStatement) -> (Statement, Self::AdditionalOutput) {
let (expression, additional_statements) = self.reconstruct_expression(input.expression);
let statement = match expression {
Expression::Unit(_) => Statement::dummy(Default::default(), self.node_builder.next_id()),
_ => Statement::Expression(ExpressionStatement { expression, span: input.span, id: input.id }),
};
(statement, additional_statements)
}
fn reconstruct_iteration(&mut self, _: IterationStatement) -> (Statement, Self::AdditionalOutput) {
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
}
}