1 use crate::ast::*; 2 use std::collections::BTreeMap; 3 use std::ops::Index; 4 5 /// The type resolution environment 6 /// 7 /// Also contains the entire module structure 8 #[derive(Default, Clone)] 9 pub struct Env { 10 pub(crate) env: BTreeMap<Path, ModuleEnv>, 11 } 12 13 /// The type resolution environment within a specific module 14 #[derive(Clone)] 15 pub struct ModuleEnv { 16 pub(crate) module: BTreeMap<Ident, ModSymbol>, 17 #[cfg_attr(not(feature = "hir"), allow(unused))] 18 pub(crate) attrs: Attrs, 19 } 20 21 impl Env { insert(&mut self, path: Path, module: ModuleEnv)22 pub(crate) fn insert(&mut self, path: Path, module: ModuleEnv) { 23 self.env.insert(path, module); 24 } 25 26 /// Given a path to a module and a name, get the item, if any get(&self, path: &Path, name: &str) -> Option<&ModSymbol>27 pub fn get(&self, path: &Path, name: &str) -> Option<&ModSymbol> { 28 self.env.get(path).and_then(|m| m.module.get(name)) 29 } 30 31 /// Iterate over all items in the environment 32 /// 33 /// This will occur in a stable lexically sorted order by path and then name iter_items(&self) -> impl Iterator<Item = (&Path, &Ident, &ModSymbol)> + '_34 pub fn iter_items(&self) -> impl Iterator<Item = (&Path, &Ident, &ModSymbol)> + '_ { 35 self.env 36 .iter() 37 .flat_map(|(k, v)| v.module.iter().map(move |v2| (k, v2.0, v2.1))) 38 } 39 40 /// Iterate over all modules 41 /// 42 /// This will occur in a stable lexically sorted order by path iter_modules(&self) -> impl Iterator<Item = (&Path, &ModuleEnv)> + '_43 pub fn iter_modules(&self) -> impl Iterator<Item = (&Path, &ModuleEnv)> + '_ { 44 self.env.iter() 45 } 46 } 47 48 impl ModuleEnv { new(attrs: Attrs) -> Self49 pub(crate) fn new(attrs: Attrs) -> Self { 50 Self { 51 module: Default::default(), 52 attrs, 53 } 54 } insert(&mut self, name: Ident, symbol: ModSymbol) -> Option<ModSymbol>55 pub(crate) fn insert(&mut self, name: Ident, symbol: ModSymbol) -> Option<ModSymbol> { 56 self.module.insert(name, symbol) 57 } 58 59 /// Given an item name, fetch it get(&self, name: &str) -> Option<&ModSymbol>60 pub fn get(&self, name: &str) -> Option<&ModSymbol> { 61 self.module.get(name) 62 } 63 64 /// Iterate over all name-item pairs in this module iter(&self) -> impl Iterator<Item = (&Ident, &ModSymbol)> + '_65 pub fn iter(&self) -> impl Iterator<Item = (&Ident, &ModSymbol)> + '_ { 66 self.module.iter() 67 } 68 69 /// Iterate over all names in this module 70 /// 71 /// This will occur in a stable lexically sorted order by name names(&self) -> impl Iterator<Item = &Ident> + '_72 pub fn names(&self) -> impl Iterator<Item = &Ident> + '_ { 73 self.module.keys() 74 } 75 76 /// Iterate over all items in this module 77 /// 78 /// This will occur in a stable lexically sorted order by name items(&self) -> impl Iterator<Item = &ModSymbol> + '_79 pub fn items(&self) -> impl Iterator<Item = &ModSymbol> + '_ { 80 self.module.values() 81 } 82 } 83 84 impl Index<&Path> for Env { 85 type Output = ModuleEnv; index(&self, i: &Path) -> &ModuleEnv86 fn index(&self, i: &Path) -> &ModuleEnv { 87 &self.env[i] 88 } 89 } 90 91 impl Index<&str> for ModuleEnv { 92 type Output = ModSymbol; index(&self, i: &str) -> &ModSymbol93 fn index(&self, i: &str) -> &ModSymbol { 94 &self.module[i] 95 } 96 } 97