use crate::DeadCodeEliminator;
use leo_ast::{
AccessExpression,
AssociatedFunction,
Expression,
ExpressionReconstructor,
Identifier,
MemberAccess,
StructExpression,
StructVariableInitializer,
TupleAccess,
Type,
};
use leo_span::sym;
impl ExpressionReconstructor for DeadCodeEliminator {
type AdditionalOutput = ();
fn reconstruct_access(&mut self, input: AccessExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Access(match input {
AccessExpression::AssociatedFunction(function) => {
match (&function.ty, function.name.name) {
(Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::get)
| (Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::get_or_init)
| (Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::set) => {
self.is_necessary = true;
}
_ => {}
};
let result = AccessExpression::AssociatedFunction(AssociatedFunction {
ty: function.ty,
name: function.name,
arguments: function
.arguments
.into_iter()
.map(|arg| self.reconstruct_expression(arg).0)
.collect(),
span: function.span,
});
self.is_necessary = false;
result
}
AccessExpression::Member(member) => AccessExpression::Member(MemberAccess {
inner: Box::new(self.reconstruct_expression(*member.inner).0),
name: member.name,
span: member.span,
}),
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
index: tuple.index,
span: tuple.span,
}),
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant),
}),
Default::default(),
)
}
fn reconstruct_struct_init(&mut self, input: StructExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Struct(StructExpression {
name: input.name,
members: input
.members
.into_iter()
.map(|member| StructVariableInitializer {
identifier: member.identifier,
expression: match member.expression {
Some(expression) => Some(self.reconstruct_expression(expression).0),
None => unreachable!("Static single assignment ensures that the expression always exists."),
},
})
.collect(),
span: input.span,
}),
Default::default(),
)
}
fn reconstruct_identifier(&mut self, input: Identifier) -> (Expression, Self::AdditionalOutput) {
if self.is_necessary {
self.used_variables.insert(input.name);
}
(Expression::Identifier(input), Default::default())
}
}