use crate::{
GlobalItemsCollection,
GlobalVarsCollection,
Pass,
PathResolution,
SymbolTable,
TypeChecking,
TypeCheckingInput,
};
use leo_ast::{ArrayType, Ast, CompositeType, TypeKind, UnitReconstructor as _};
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 ast = std::mem::take(&mut state.ast);
let mut visitor = OptionLoweringVisitor {
state,
program: Symbol::intern(""),
module: vec![],
function: None,
composites: IndexMap::new(),
};
if let Ast::Program(program) = &ast {
visitor.collect_composites_from_program(program);
}
let ast = ast.map(
|program| visitor.reconstruct_program(program),
|library| library, );
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: &TypeKind) -> Symbol {
fn display_type(ty: &TypeKind) -> String {
match ty {
TypeKind::Address
| TypeKind::Field
| TypeKind::Group
| TypeKind::Scalar
| TypeKind::Signature
| TypeKind::Boolean
| TypeKind::Integer(..) => format!("{ty}"),
TypeKind::Array(ArrayType { element_type, length }) => {
format!("[{}; {length}]", display_type(element_type))
}
TypeKind::Composite(CompositeType { path, .. }) => {
format!("::{}", path.expect_global_location().path.iter().format("::"))
}
TypeKind::Tuple(_)
| TypeKind::Optional(_)
| TypeKind::Mapping(_)
| TypeKind::Numeric
| TypeKind::Ident(_)
| TypeKind::Future(_)
| TypeKind::Vector(_)
| TypeKind::String
| TypeKind::Identifier
| TypeKind::DynRecord
| TypeKind::Err
| TypeKind::Unit => {
panic!("unexpected inner type in optional struct name")
}
}
}
Symbol::intern(&format!("{}?", display_type(ty)))
}