use std::borrow::Borrow; use std::cell::{Ref, RefMut}; use std::fmt; use std::hash::Hash; use erg_common::dict::Dict; use erg_common::set::Set; use erg_common::shared::Shared; use erg_common::Str; use crate::context::TraitImpl; /// Caches checked modules. /// In addition to being queried here when re-imported, it is also used when linking /// (Erg links all scripts defined in erg and outputs them to a single pyc file). #[derive(Debug, Default)] pub struct TraitImpls { cache: Dict>, } impl fmt::Display for TraitImpls { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "TraitImpls {{")?; for (name, impls) in self.cache.iter() { writeln!(f, "{name}: {impls}, ")?; } write!(f, "}}") } } impl TraitImpls { pub fn new() -> Self { Self { cache: Dict::new() } } pub fn get(&self, path: &P) -> Option<&Set> where Str: Borrow

, { self.cache.get(path) } pub fn get_mut(&mut self, path: &Q) -> Option<&mut Set> where Str: Borrow, { self.cache.get_mut(path) } pub fn register(&mut self, name: Str, impls: Set) { self.cache.insert(name, impls); } pub fn remove(&mut self, path: &Q) -> Option> where Str: Borrow, { self.cache.remove(path) } pub fn initialize(&mut self) { self.cache.clear(); } } #[derive(Debug, Clone, Default)] pub struct SharedTraitImpls(Shared); impl fmt::Display for SharedTraitImpls { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Shared{}", self.0) } } impl SharedTraitImpls { pub fn new() -> Self { Self(Shared::new(TraitImpls::new())) } pub fn get(&self, path: &Q) -> Option>> where Str: Borrow, { if self.0.borrow().get(path).is_some() { Some(Ref::map(self.0.borrow(), |tis| tis.get(path).unwrap())) } else { None } } pub fn get_mut(&self, path: &Q) -> Option>> where Str: Borrow, { if self.0.borrow().get(path).is_some() { Some(RefMut::map(self.0.borrow_mut(), |tis| { tis.get_mut(path).unwrap() })) } else { None } } pub fn register(&self, name: Str, impls: Set) { self.0.borrow_mut().register(name, impls); } pub fn remove(&self, path: &Q) -> Option> where Str: Borrow, { self.0.borrow_mut().remove(path) } pub fn ref_inner(&self) -> Ref>> { Ref::map(self.0.borrow(), |tis| &tis.cache) } pub fn initialize(&self) { self.0.borrow_mut().initialize(); } }