use super::StorageLoweringVisitor;
use leo_ast::{
AstReconstructor,
Identifier,
IntegerType,
Library,
Location,
Mapping,
ProgramReconstructor,
ProgramScope,
Statement,
StorageVariable,
Type,
VectorType,
};
use leo_span::Symbol;
impl ProgramReconstructor for StorageLoweringVisitor<'_> {
fn reconstruct_library(&mut self, input: Library) -> Library {
let prev_program = self.program;
self.program = input.name;
let library = Library {
name: input.name,
modules: input.modules.into_iter().map(|(id, m)| (id, self.reconstruct_module(m))).collect(),
consts: input
.consts
.into_iter()
.map(|(i, c)| match self.reconstruct_const(c) {
(Statement::Const(declaration), _) => (i, declaration),
_ => panic!("`reconstruct_const` can only return `Statement::Const`"),
})
.collect(),
structs: input.structs.into_iter().map(|(i, s)| (i, self.reconstruct_composite(s))).collect(),
functions: input.functions.into_iter().map(|(i, f)| (i, self.reconstruct_function(f))).collect(),
interfaces: input.interfaces,
};
self.program = prev_program;
library
}
fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope {
self.program = input.program_id.as_symbol();
let storage_variables = input
.storage_variables
.into_iter()
.map(|(id, storage_variable)| (id, self.reconstruct_storage_variable(storage_variable)))
.collect::<Vec<_>>();
let mut mappings =
input.mappings.into_iter().map(|(id, mapping)| (id, self.reconstruct_mapping(mapping))).collect::<Vec<_>>();
mappings.extend(
self.new_mappings
.iter()
.filter(|(Location { program, .. }, _)| *program == self.program)
.map(|(Location { program, .. }, mapping)| (*program, mapping.clone())),
);
ProgramScope {
program_id: input.program_id,
parents: input.parents.into_iter().map(|(s, t)| (s, self.reconstruct_type(t).0)).collect(),
consts: input
.consts
.into_iter()
.map(|(i, c)| match self.reconstruct_const(c) {
(Statement::Const(declaration), _) => (i, declaration),
_ => panic!("`reconstruct_const` can only return `Statement::Const`"),
})
.collect(),
composites: input.composites.into_iter().map(|(i, c)| (i, self.reconstruct_composite(c))).collect(),
mappings,
storage_variables,
functions: input.functions.into_iter().map(|(i, f)| (i, self.reconstruct_function(f))).collect(),
interfaces: input.interfaces.into_iter().map(|(i, int)| (i, self.reconstruct_interface(int))).collect(),
constructor: input.constructor.map(|c| self.reconstruct_constructor(c)),
span: input.span,
}
}
fn reconstruct_storage_variable(&mut self, input: StorageVariable) -> StorageVariable {
let id = || self.state.node_builder.next_id();
let name = input.identifier.name.to_string();
let mapping_name = Symbol::intern(&(name.clone() + "__"));
match &input.type_ {
Type::Vector(VectorType { element_type }) => {
self.new_mappings.insert(Location::new(self.program, vec![mapping_name]), Mapping {
identifier: Identifier::new(mapping_name, id()),
key_type: Type::Integer(IntegerType::U32),
value_type: *element_type.clone(),
span: input.span,
id: id(),
});
let len_name = Symbol::intern(&(name + "__len__"));
self.new_mappings.insert(Location::new(self.program, vec![len_name]), Mapping {
identifier: Identifier::new(len_name, id()),
key_type: Type::Boolean,
value_type: Type::Integer(IntegerType::U32),
span: input.span,
id: id(),
});
}
_ => {
self.new_mappings.insert(Location::new(self.program, vec![mapping_name]), Mapping {
identifier: Identifier::new(mapping_name, id()),
key_type: Type::Boolean,
value_type: input.type_.clone(),
span: input.span,
id: id(),
});
}
}
input
}
}