use indexmap::IndexMap;
use leo_ast::{Composite, Function, Library, Location, Program, Stub};
use leo_span::Symbol;
pub fn items_at_path<'a, V: Clone + 'a>(
map: &'a IndexMap<Location, V>,
program: Symbol,
path_prefix: &'a [Symbol],
) -> impl Iterator<Item = (Symbol, V)> + 'a {
map.iter().filter_map(move |(loc, v)| {
loc.path
.split_last()
.filter(|(_, rest)| *rest == path_prefix && loc.program == program)
.map(|(last, _)| (*last, v.clone()))
})
}
pub fn program_functions(program: &Program) -> impl Iterator<Item = (Location, &Function)> {
let scopes = program.program_scopes.iter().flat_map(|(_, scope)| {
let prog = scope.program_id.as_symbol();
scope.functions.iter().map(move |(name, f)| (Location::new(prog, vec![*name]), f))
});
let modules = program.modules.iter().flat_map(module_functions);
scopes.chain(modules)
}
pub fn program_composites(program: &Program) -> impl Iterator<Item = (Location, &Composite)> {
let scopes = program.program_scopes.iter().flat_map(|(_, scope)| {
let prog = scope.program_id.as_symbol();
scope.composites.iter().map(move |(name, c)| (Location::new(prog, vec![*name]), c))
});
let modules = program.modules.iter().flat_map(module_composites);
scopes.chain(modules)
}
pub fn library_functions(library: &Library) -> impl Iterator<Item = (Location, &Function)> {
let name = library.name;
let top = library.functions.iter().map(move |(sym, f)| (Location::new(name, vec![*sym]), f));
let modules = library.modules.iter().flat_map(module_functions);
top.chain(modules)
}
pub fn library_composites(library: &Library) -> impl Iterator<Item = (Location, &Composite)> {
let name = library.name;
let top = library.structs.iter().map(move |(sym, c)| (Location::new(name, vec![*sym]), c));
let modules = library.modules.iter().flat_map(module_composites);
top.chain(modules)
}
pub fn stub_functions(stub: &Stub) -> Box<dyn Iterator<Item = (Location, &Function)> + '_> {
match stub {
Stub::FromLeo { program, .. } => Box::new(program_functions(program)),
Stub::FromLibrary { library, .. } => Box::new(library_functions(library)),
Stub::FromAleo { .. } => Box::new(std::iter::empty()),
}
}
pub fn stub_composites(stub: &Stub) -> Box<dyn Iterator<Item = (Location, &Composite)> + '_> {
match stub {
Stub::FromLeo { program, .. } => Box::new(program_composites(program)),
Stub::FromLibrary { library, .. } => Box::new(library_composites(library)),
Stub::FromAleo { .. } => Box::new(std::iter::empty()),
}
}
fn module_functions<'a>(
(path, m): (&'a Vec<Symbol>, &'a leo_ast::Module),
) -> impl Iterator<Item = (Location, &'a Function)> {
m.functions.iter().map(move |(name, f)| {
let full: Vec<Symbol> = path.iter().copied().chain(std::iter::once(*name)).collect();
(Location::new(m.unit_name, full), f)
})
}
fn module_composites<'a>(
(path, m): (&'a Vec<Symbol>, &'a leo_ast::Module),
) -> impl Iterator<Item = (Location, &'a Composite)> {
m.composites.iter().map(move |(name, c)| {
let full: Vec<Symbol> = path.iter().copied().chain(std::iter::once(*name)).collect();
(Location::new(m.unit_name, full), c)
})
}