Add Scope::set_alias.

This commit is contained in:
Stephen Chung 2022-03-09 09:25:32 +08:00
parent cbb1c5c6a0
commit 89426f8b3a
3 changed files with 29 additions and 6 deletions

View File

@ -25,6 +25,7 @@ Enhancements
* The `event_handler_map` example is enhanced to prevent shadowing of the state object map. * The `event_handler_map` example is enhanced to prevent shadowing of the state object map.
* Separation of constants in function calls is removed as its performance benefit is dubious. * Separation of constants in function calls is removed as its performance benefit is dubious.
* A function `sleep` is added to block the current thread by a specified number of seconds. * A function `sleep` is added to block the current thread by a specified number of seconds.
* `Scope::set_alias` is added to export a variable under a particular alias name.
Version 1.5.0 Version 1.5.0

View File

@ -905,7 +905,7 @@ impl Engine {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
if let Some(alias) = _alias { if let Some(alias) = _alias {
scope.add_entry_alias(scope.len() - 1, alias.name.clone()); scope.add_alias_by_index(scope.len() - 1, alias.name.clone());
} }
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)
@ -989,10 +989,8 @@ impl Engine {
let (Ident { name, pos, .. }, alias) = x.as_ref(); let (Ident { name, pos, .. }, alias) = x.as_ref();
// Mark scope variables as public // Mark scope variables as public
if let Some((index, ..)) = scope.get_index(name) { if let Some((index, ..)) = scope.get_index(name) {
scope.add_entry_alias( let alias = if alias.is_empty() { name } else { alias }.clone();
index, scope.add_alias_by_index(index, alias);
if alias.is_empty() { name } else { alias }.clone(),
);
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)
} else { } else {
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()) Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())

View File

@ -514,13 +514,37 @@ impl Scope<'_> {
/// Panics if the index is out of bounds. /// Panics if the index is out of bounds.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline] #[inline]
pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self { pub(crate) fn add_alias_by_index(&mut self, index: usize, alias: Identifier) -> &mut Self {
let aliases = self.aliases.get_mut(index).unwrap(); let aliases = self.aliases.get_mut(index).unwrap();
if aliases.is_empty() || !aliases.contains(&alias) { if aliases.is_empty() || !aliases.contains(&alias) {
aliases.push(alias); aliases.push(alias);
} }
self self
} }
/// Add an alias to a variable in the [`Scope`] so that it is exported under that name.
/// This is an advanced API.
///
/// If the alias is empty, then the variable is exported under its original name.
///
/// Multiple aliases can be added to any variable.
///
/// Only the last variable matching the name (and not other shadowed versions) is aliased by
/// this call.
#[cfg(not(feature = "no_module"))]
#[inline]
pub fn set_alias(
&mut self,
name: impl AsRef<str> + Into<Identifier>,
alias: impl Into<Identifier>,
) {
if let Some((index, ..)) = self.get_index(name.as_ref()) {
let alias = match alias.into() {
x if x.is_empty() => name.into(),
x => x,
};
self.add_alias_by_index(index, alias);
}
}
/// Clone the [`Scope`], keeping only the last instances of each variable name. /// Clone the [`Scope`], keeping only the last instances of each variable name.
/// Shadowed variables are omitted in the copy. /// Shadowed variables are omitted in the copy.
#[inline] #[inline]