diff --git a/src/engine_api.rs b/src/engine_api.rs index 9f72a5df..78b96e6c 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -1681,7 +1681,7 @@ impl Engine { }); if include_packages { - signatures.extend(self.packages.gen_fn_signatures()); + signatures.extend(self.packages.iter().flat_map(|m| m.gen_fn_signatures())); } signatures diff --git a/src/engine_settings.rs b/src/engine_settings.rs index ca220cb1..e61dc08f 100644 --- a/src/engine_settings.rs +++ b/src/engine_settings.rs @@ -1,9 +1,8 @@ //! Configuration settings for [`Engine`]. -use crate::packages::PackageLibrary; use crate::stdlib::{format, string::String}; use crate::token::{is_valid_identifier, Token}; -use crate::Engine; +use crate::{Engine, Module, Shared}; #[cfg(not(feature = "no_module"))] use crate::stdlib::boxed::Box; @@ -15,8 +14,8 @@ impl Engine { /// When searching for functions, packages loaded later are preferred. /// In other words, loaded packages are searched in reverse order. #[inline(always)] - pub fn load_package(&mut self, package: impl Into) -> &mut Self { - self.packages.add(package.into()); + pub fn load_package(&mut self, package: impl Into>) -> &mut Self { + self.packages.insert(0, package.into()); self } /// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation. diff --git a/src/fn_call.rs b/src/fn_call.rs index d0b320d2..68701342 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -184,7 +184,7 @@ impl Engine { let f = self .global_namespace .get_fn(hash_fn, pub_only) - .or_else(|| self.packages.get_fn(hash_fn)) + .or_else(|| self.packages.iter().find_map(|m| m.get_fn(hash_fn, false))) .or_else(|| mods.get_fn(hash_fn)); state.functions_cache.insert(hash_fn, f.cloned()); @@ -460,8 +460,8 @@ impl Engine { //|| (hash_script != 0 && self.global_namespace.contains_fn(hash_script, pub_only)) || self.global_namespace.contains_fn(hash_fn, false) // Then check packages - || (hash_script != 0 && self.packages.contains_fn(hash_script)) - || self.packages.contains_fn(hash_fn) + || (hash_script != 0 && self.packages.iter().any(|m| m.contains_fn(hash_script, false))) + || self.packages.iter().any(|m| m.contains_fn(hash_fn, false)) // Then check imported modules || (hash_script != 0 && mods.map(|m| m.contains_fn(hash_script)).unwrap_or(false)) || mods.map(|m| m.contains_fn(hash_fn)).unwrap_or(false) @@ -541,7 +541,12 @@ impl Engine { .map(|f| (f, m.id_raw().clone())) }) //.or_else(|| self.global_namespace.get_fn(hash_script, pub_only)) - .or_else(|| self.packages.get_fn(hash_script).map(|f| (f, None))) + .or_else(|| { + self.packages + .iter() + .find_map(|m| m.get_fn(hash_script, false)) + .map(|f| (f, None)) + }) //.or_else(|| mods.iter().find_map(|(_, m)| m.get_qualified_fn(hash_script).map(|f| (f, m.id_raw().clone())))) .unwrap(); diff --git a/src/packages/mod.rs b/src/packages/mod.rs index ca42cced..e5bffc58 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -39,71 +39,7 @@ pub trait Package { fn init(lib: &mut Module); /// Retrieve the generic package library from this package. - fn get(&self) -> PackageLibrary; -} - -/// A sharable [`Module`][crate::Module] to facilitate sharing library instances. -pub type PackageLibrary = Shared; - -/// Type containing a collection of [`PackageLibrary`] instances. -/// All function and type iterator keys in the loaded packages are indexed for fast access. -#[derive(Debug, Clone, Default)] -pub(crate) struct PackagesCollection(Option>); - -impl PackagesCollection { - /// Add a [`PackageLibrary`] into the [`PackagesCollection`]. - /// - /// Packages are searched in reverse order. - pub fn add(&mut self, package: PackageLibrary) { - if self.0.is_none() { - self.0 = Some(Default::default()); - } - // Later packages override previous ones. - self.0.as_mut().unwrap().insert(0, package); - } - /// Does the specified function hash key exist in the [`PackagesCollection`]? - #[allow(dead_code)] - pub fn contains_fn(&self, hash: u64) -> bool { - if hash == 0 { - false - } else { - self.0 - .as_ref() - .map_or(false, |x| x.iter().any(|p| p.contains_fn(hash, false))) - } - } - /// Get specified function via its hash key. - pub fn get_fn(&self, hash: u64) -> Option<&CallableFunction> { - if hash == 0 { - None - } else { - self.0 - .as_ref() - .and_then(|x| x.iter().find_map(|p| p.get_fn(hash, false))) - } - } - /// Does the specified [`TypeId`] iterator exist in the [`PackagesCollection`]? - #[allow(dead_code)] - pub fn contains_iter(&self, id: TypeId) -> bool { - self.0 - .as_ref() - .map_or(false, |x| x.iter().any(|p| p.contains_iter(id))) - } - /// Get the specified [`TypeId`] iterator. - pub fn get_iter(&self, id: TypeId) -> Option { - self.0 - .as_ref() - .and_then(|x| x.iter().find_map(|p| p.get_iter(id))) - } - /// Get an iterator over all the packages in the [`PackagesCollection`]. - pub(crate) fn iter(&self) -> impl Iterator { - self.0.iter().flat_map(|p| p.iter()) - } - - /// Generate signatures for all the functions in the [`PackagesCollection`]. - pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator + 'a { - self.iter().flat_map(|m| m.gen_fn_signatures()) - } + fn get(&self) -> Shared; } /// Macro that makes it easy to define a _package_ (which is basically a shared module) @@ -132,10 +68,10 @@ impl PackagesCollection { macro_rules! def_package { ($root:ident : $package:ident : $comment:expr , $lib:ident , $block:stmt) => { #[doc=$comment] - pub struct $package($root::packages::PackageLibrary); + pub struct $package($root::Shared<$root::Module>); impl $root::packages::Package for $package { - fn get(&self) -> $root::packages::PackageLibrary { + fn get(&self) -> $root::Shared<$root::Module> { self.0.clone() }