use crate::{AliasId, BlockId, DeclId, Span}; use indexmap::IndexMap; /// Collection of definitions that can be exported from a module #[derive(Debug, Clone)] pub struct Module { pub name: Vec, pub decls: IndexMap, DeclId>, pub aliases: IndexMap, AliasId>, pub env_block: Option, // `export-env { ... }` block pub main: Option, // `export def main` pub span: Option, } impl Module { pub fn new(name: Vec) -> Self { Module { name, decls: IndexMap::new(), aliases: IndexMap::new(), env_block: None, main: None, span: None, } } pub fn from_span(name: Vec, span: Span) -> Self { Module { name, decls: IndexMap::new(), aliases: IndexMap::new(), env_block: None, main: None, span: Some(span), } } pub fn add_decl(&mut self, name: Vec, decl_id: DeclId) -> Option { self.decls.insert(name, decl_id) } pub fn add_alias(&mut self, name: Vec, alias_id: AliasId) -> Option { self.aliases.insert(name, alias_id) } pub fn add_env_block(&mut self, block_id: BlockId) { self.env_block = Some(block_id); } pub fn extend(&mut self, other: &Module) { self.decls.extend(other.decls.clone()); self.aliases.extend(other.aliases.clone()); } pub fn is_empty(&self) -> bool { self.decls.is_empty() && self.aliases.is_empty() } pub fn get_decl_id(&self, name: &[u8]) -> Option { self.decls.get(name).copied() } pub fn get_alias_id(&self, name: &[u8]) -> Option { self.aliases.get(name).copied() } pub fn has_decl(&self, name: &[u8]) -> bool { if name == self.name && self.main.is_some() { return true; } self.decls.contains_key(name) } pub fn has_alias(&self, name: &[u8]) -> bool { self.aliases.contains_key(name) } pub fn decl_name_with_head(&self, name: &[u8], head: &[u8]) -> Option> { if self.has_decl(name) { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); Some(new_name) } else { None } } pub fn alias_name_with_head(&self, name: &[u8], head: &[u8]) -> Option> { if self.has_alias(name) { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); Some(new_name) } else { None } } pub fn decls_with_head(&self, head: &[u8]) -> Vec<(Vec, DeclId)> { let mut result: Vec<(Vec, DeclId)> = self .decls .iter() .map(|(name, id)| { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); (new_name, *id) }) .collect(); if let Some(decl_id) = self.main { result.push((self.name.clone(), decl_id)); } result } pub fn decl_names_with_head(&self, head: &[u8]) -> Vec> { let mut result: Vec> = self .decls .keys() .map(|name| { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); new_name }) .collect(); if self.main.is_some() { result.push(self.name.clone()); } result } pub fn aliases_with_head(&self, head: &[u8]) -> Vec<(Vec, AliasId)> { self.aliases .iter() .map(|(name, id)| { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); (new_name, *id) }) .collect() } pub fn alias_names_with_head(&self, head: &[u8]) -> Vec> { self.aliases .keys() .map(|name| { let mut new_name = head.to_vec(); new_name.push(b' '); new_name.extend(name); new_name }) .collect() } pub fn decls(&self) -> Vec<(Vec, DeclId)> { let mut result: Vec<(Vec, DeclId)> = self .decls .iter() .map(|(name, id)| (name.clone(), *id)) .collect(); if let Some(decl_id) = self.main { result.push((self.name.clone(), decl_id)); } result } pub fn decl_names(&self) -> Vec> { let mut result: Vec> = self.decls.keys().cloned().collect(); if self.main.is_some() { result.push(self.name.clone()); } result } pub fn alias_names(&self) -> Vec> { self.aliases.keys().cloned().collect() } pub fn aliases(&self) -> Vec<(Vec, AliasId)> { self.aliases .iter() .map(|(name, id)| (name.clone(), *id)) .collect() } }