use crate::{
GlobalItemsCollection,
GlobalVarsCollection,
Pass,
PathResolution,
SymbolTable,
TypeChecking,
TypeCheckingInput,
};
use leo_ast::{ArrayType, CompositeType, ProgramReconstructor as _, Type};
use leo_errors::Result;
use leo_span::Symbol;
use indexmap::IndexMap;
use itertools::Itertools;
mod ast;
mod program;
mod visitor;
use visitor::*;
pub struct OptionLowering;
impl Pass for OptionLowering {
type Input = TypeCheckingInput;
type Output = ();
const NAME: &str = "OptionLowering";
fn do_pass(input: TypeCheckingInput, state: &mut crate::CompilerState) -> Result<Self::Output> {
let mut ast = std::mem::take(&mut state.ast);
let mut visitor = OptionLoweringVisitor {
state,
program: Symbol::intern(""),
module: vec![],
function: None,
new_structs: IndexMap::new(),
reconstructed_composites: IndexMap::new(),
};
ast.ast = visitor.reconstruct_program(ast.ast);
visitor.state.handler.last_err()?;
visitor.state.ast = ast;
visitor.state.symbol_table = SymbolTable::default();
GlobalVarsCollection::do_pass((), state)?;
PathResolution::do_pass((), state)?;
GlobalItemsCollection::do_pass((), state)?;
TypeChecking::do_pass(input.clone(), state)?;
Ok(())
}
}
pub fn make_optional_struct_symbol(ty: &Type) -> Symbol {
fn display_type(ty: &Type) -> String {
match ty {
Type::Address
| Type::Field
| Type::Group
| Type::Scalar
| Type::Signature
| Type::Boolean
| Type::Integer(..) => format!("{ty}"),
Type::Array(ArrayType { element_type, length }) => {
format!("[{}; {length}]", display_type(element_type))
}
Type::Composite(CompositeType { path, .. }) => {
format!("::{}", path.expect_global_location().path.iter().format("::"))
}
Type::Tuple(_)
| Type::Optional(_)
| Type::Mapping(_)
| Type::Numeric
| Type::Identifier(_)
| Type::Future(_)
| Type::Vector(_)
| Type::String
| Type::Err
| Type::Unit => {
panic!("unexpected inner type in optional struct name")
}
}
}
Symbol::intern(&format!("\"{}?\"", display_type(ty)))
}