leo_passes/option_lowering/
program.rs1use super::OptionLoweringVisitor;
18use leo_ast::{
19 AstReconstructor,
20 ConstParameter,
21 Function,
22 Input,
23 Module,
24 Output,
25 Program,
26 ProgramReconstructor,
27 ProgramScope,
28 Statement,
29};
30use leo_span::Symbol;
31
32impl ProgramReconstructor for OptionLoweringVisitor<'_> {
33 fn reconstruct_program(&mut self, input: Program) -> Program {
34 for (_, scope) in &input.program_scopes {
36 for (_, c) in &scope.structs {
37 let new_struct = self.reconstruct_struct(c.clone());
38 self.reconstructed_structs.insert(vec![new_struct.name()], new_struct);
39 }
40 }
41 for (module_path, module) in &input.modules {
42 for (_, c) in &module.structs {
43 let full_name = module_path.iter().cloned().chain(std::iter::once(c.name())).collect::<Vec<Symbol>>();
44 let new_struct = self.reconstruct_struct(c.clone());
45 self.reconstructed_structs.insert(full_name, new_struct.clone());
46 }
47 }
48
49 Program {
51 imports: input
52 .imports
53 .into_iter()
54 .map(|(id, import)| (id, (self.reconstruct_import(import.0), import.1)))
55 .collect(),
56 stubs: input.stubs.into_iter().map(|(id, stub)| (id, self.reconstruct_stub(stub))).collect(),
57 program_scopes: input
58 .program_scopes
59 .into_iter()
60 .map(|(id, scope)| (id, self.reconstruct_program_scope(scope)))
61 .collect(),
62 modules: input.modules.into_iter().map(|(id, module)| (id, self.reconstruct_module(module))).collect(),
63 }
64 }
65
66 fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope {
67 self.program = input.program_id.name.name;
68
69 let mut program = ProgramScope {
70 consts: input
71 .consts
72 .into_iter()
73 .map(|(i, c)| match self.reconstruct_const(c) {
74 (Statement::Const(decl), _) => (i, decl),
75 _ => panic!("`reconstruct_const` can only return `Statement::Const`"),
76 })
77 .collect(),
78 structs: self
79 .reconstructed_structs
80 .iter()
81 .filter_map(|(path, s)| {
82 path.split_last().filter(|(_, rest)| rest.is_empty()).map(|(last, _)| (*last, s.clone()))
83 })
84 .collect(),
85 mappings: input.mappings.into_iter().map(|(id, m)| (id, self.reconstruct_mapping(m))).collect(),
86 functions: input.functions.into_iter().map(|(i, f)| (i, self.reconstruct_function(f))).collect(),
87 constructor: input.constructor.map(|c| self.reconstruct_constructor(c)),
88 ..input
89 };
90
91 program.structs.extend(self.new_structs.drain(..));
92 program
93 }
94
95 fn reconstruct_module(&mut self, input: Module) -> Module {
96 self.program = input.program_name;
97 self.in_module_scope(&input.path.clone(), |slf| Module {
98 consts: input
99 .consts
100 .into_iter()
101 .map(|(i, c)| match slf.reconstruct_const(c) {
102 (Statement::Const(declaration), _) => (i, declaration),
103 _ => panic!("`reconstruct_const` can only return `Statement::Const`"),
104 })
105 .collect(),
106 structs: slf
107 .reconstructed_structs
108 .iter()
109 .filter_map(|(path, c)| path.split_last().map(|(last, rest)| (last, rest, c)))
110 .filter(|&(_, rest, _)| input.path == rest)
111 .map(|(last, _, c)| (*last, c.clone()))
112 .collect(),
113 functions: input.functions.into_iter().map(|(i, f)| (i, slf.reconstruct_function(f))).collect(),
114 ..input
115 })
116 }
117
118 fn reconstruct_function(&mut self, input: Function) -> Function {
119 self.function = Some(input.identifier.name);
120 Function {
121 const_parameters: input
122 .const_parameters
123 .iter()
124 .map(|param| ConstParameter { type_: self.reconstruct_type(param.type_.clone()).0, ..param.clone() })
125 .collect(),
126 input: input
127 .input
128 .iter()
129 .map(|input| Input { type_: self.reconstruct_type(input.type_.clone()).0, ..input.clone() })
130 .collect(),
131 output: input
132 .output
133 .iter()
134 .map(|output| Output { type_: self.reconstruct_type(output.type_.clone()).0, ..output.clone() })
135 .collect(),
136 output_type: self.reconstruct_type(input.output_type).0,
137 block: self.reconstruct_block(input.block).0,
138 ..input
139 }
140 }
141}