use crate::StaticSingleAssigner;
use leo_ast::{
Block,
Finalize,
Function,
FunctionConsumer,
Member,
Program,
ProgramConsumer,
ProgramScope,
ProgramScopeConsumer,
StatementConsumer,
Struct,
StructConsumer,
};
use leo_span::{sym, Symbol};
use indexmap::IndexMap;
impl StructConsumer for StaticSingleAssigner<'_> {
type Output = Struct;
fn consume_struct(&mut self, struct_: Struct) -> Self::Output {
match struct_.is_record {
false => struct_,
true => {
let mut members = Vec::with_capacity(struct_.members.len());
let mut member_map: IndexMap<Symbol, Member> =
struct_.members.into_iter().map(|member| (member.identifier.name, member)).collect();
members.push(member_map.shift_remove(&sym::owner).unwrap());
members.extend(member_map.into_iter().map(|(_, member)| member));
Struct { members, ..struct_ }
}
}
}
}
impl FunctionConsumer for StaticSingleAssigner<'_> {
type Output = Function;
fn consume_function(&mut self, function: Function) -> Self::Output {
self.push();
for input_variable in function.input.iter() {
self.rename_table.update(input_variable.identifier().name, input_variable.identifier().name);
}
let block =
Block { span: function.block.span, id: function.block.id, statements: self.consume_block(function.block) };
self.pop();
let finalize = function.finalize.map(|finalize| {
self.push();
for input_variable in finalize.input.iter() {
self.rename_table.update(input_variable.identifier().name, input_variable.identifier().name);
}
let block = Block {
span: finalize.block.span,
id: finalize.block.id,
statements: self.consume_block(finalize.block),
};
self.pop();
Finalize {
identifier: finalize.identifier,
input: finalize.input,
output: finalize.output,
output_type: finalize.output_type,
block,
span: finalize.span,
id: finalize.id,
}
});
Function {
annotations: function.annotations,
variant: function.variant,
identifier: function.identifier,
input: function.input,
output: function.output,
output_type: function.output_type,
block,
finalize,
span: function.span,
id: function.id,
}
}
}
impl ProgramScopeConsumer for StaticSingleAssigner<'_> {
type Output = ProgramScope;
fn consume_program_scope(&mut self, input: ProgramScope) -> Self::Output {
ProgramScope {
program_id: input.program_id,
structs: input.structs.into_iter().map(|(i, s)| (i, self.consume_struct(s))).collect(),
mappings: input.mappings,
functions: input.functions.into_iter().map(|(i, f)| (i, self.consume_function(f))).collect(),
consts: input.consts,
span: input.span,
}
}
}
impl ProgramConsumer for StaticSingleAssigner<'_> {
type Output = Program;
fn consume_program(&mut self, input: Program) -> Self::Output {
Program {
imports: input
.imports
.into_iter()
.map(|(name, (import, span))| (name, (self.consume_program(import), span)))
.collect(),
program_scopes: input
.program_scopes
.into_iter()
.map(|(name, scope)| (name, self.consume_program_scope(scope)))
.collect(),
}
}
}