Refine namespace display.

This commit is contained in:
Stephen Chung 2021-10-27 23:30:25 +08:00
parent 00659d65d9
commit a5ae002cb7
6 changed files with 62 additions and 33 deletions

View File

@ -2003,7 +2003,7 @@ impl fmt::Debug for Expr {
Self::Variable(i, _, x) => { Self::Variable(i, _, x) => {
f.write_str("Variable(")?; f.write_str("Variable(")?;
if let Some((_, ref namespace)) = x.1 { if let Some((_, ref namespace)) = x.1 {
write!(f, "{}", namespace)? write!(f, "{}{}", namespace, Token::DoubleColon.literal_syntax())?
} }
f.write_str(&x.2)?; f.write_str(&x.2)?;
if let Some(n) = i.map_or_else(|| x.0, |n| NonZeroUsize::new(n.get() as usize)) { if let Some(n) = i.map_or_else(|| x.0, |n| NonZeroUsize::new(n.get() as usize)) {

View File

@ -1181,38 +1181,54 @@ impl Engine {
Expr::Variable(None, var_pos, v) => match v.as_ref() { Expr::Variable(None, var_pos, v) => match v.as_ref() {
// Normal variable access // Normal variable access
(_, None, _) => self.search_scope_only(scope, mods, state, lib, this_ptr, expr), (_, None, _) => self.search_scope_only(scope, mods, state, lib, this_ptr, expr),
// Qualified variable // Qualified variable access
(_, Some((namespace, hash_var)), var_name) => { (_, Some((namespace, hash_var)), var_name) => {
if let Some(module) = self.search_imports(mods, state, namespace) { if let Some(module) = self.search_imports(mods, state, namespace) {
let target = module.get_qualified_var(*hash_var).map_err(|mut err| { // foo:bar::baz::VARIABLE
match *err { match module.get_qualified_var(*hash_var) {
EvalAltResult::ErrorVariableNotFound(ref mut err_name, _) => { Ok(target) => {
*err_name = format!("{}{}", namespace, var_name); let mut target = target.clone();
} // Module variables are constant
_ => (), target.set_access_mode(AccessMode::ReadOnly);
Ok((target.into(), *var_pos))
} }
err.fill_position(*var_pos) Err(mut err) => {
})?; match *err {
EvalAltResult::ErrorVariableNotFound(ref mut err_name, _) => {
// Module variables are constant *err_name = format!(
let mut target = target.clone(); "{}{}{}",
target.set_access_mode(AccessMode::ReadOnly); namespace,
Ok((target.into(), *var_pos)) Token::DoubleColon.literal_syntax(),
var_name
);
}
_ => (),
}
Err(err.fill_position(*var_pos))
}
}
} else if namespace.len() == 1 && namespace[0].name == KEYWORD_GLOBAL { } else if namespace.len() == 1 && namespace[0].name == KEYWORD_GLOBAL {
// global::VARIABLE
if let Some(value) = state.global_constants.get_mut(var_name) { if let Some(value) = state.global_constants.get_mut(var_name) {
let mut target: Target = value.clone().into(); let mut target: Target = value.clone().into();
// Module variables are constant
target.set_access_mode(AccessMode::ReadOnly); target.set_access_mode(AccessMode::ReadOnly);
Ok((target.into(), *var_pos)) Ok((target.into(), *var_pos))
} else { } else {
Err(EvalAltResult::ErrorVariableNotFound( Err(EvalAltResult::ErrorVariableNotFound(
format!("{}{}", namespace, var_name), format!(
"{}{}{}",
namespace,
Token::DoubleColon.literal_syntax(),
var_name
),
namespace[0].pos, namespace[0].pos,
) )
.into()) .into())
} }
} else { } else {
Err(EvalAltResult::ErrorModuleNotFound( Err(EvalAltResult::ErrorModuleNotFound(
namespace[0].name.to_string(), namespace.to_string(),
namespace[0].pos, namespace[0].pos,
) )
.into()) .into())

View File

@ -122,11 +122,11 @@ impl fmt::Display for EvalAltResult {
Self::ErrorInModule(s, err, _) if s.is_empty() => { Self::ErrorInModule(s, err, _) if s.is_empty() => {
write!(f, "Error in module: {}", err)? write!(f, "Error in module: {}", err)?
} }
Self::ErrorInModule(s, err, _) => write!(f, "Error in module '{}': {}", s, err)?, Self::ErrorInModule(s, err, _) => write!(f, "Error in module {}: {}", s, err)?,
Self::ErrorFunctionNotFound(s, _) => write!(f, "Function not found: {}", s)?, Self::ErrorFunctionNotFound(s, _) => write!(f, "Function not found: {}", s)?,
Self::ErrorVariableNotFound(s, _) => write!(f, "Variable not found: {}", s)?, Self::ErrorVariableNotFound(s, _) => write!(f, "Variable not found: {}", s)?,
Self::ErrorModuleNotFound(s, _) => write!(f, "Module not found: '{}'", s)?, Self::ErrorModuleNotFound(s, _) => write!(f, "Module not found: {}", s)?,
Self::ErrorDataRace(s, _) => { Self::ErrorDataRace(s, _) => {
write!(f, "Data race detected when accessing variable: {}", s)? write!(f, "Data race detected when accessing variable: {}", s)?
} }
@ -134,7 +134,7 @@ impl fmt::Display for EvalAltResult {
"" => f.write_str("Malformed dot expression"), "" => f.write_str("Malformed dot expression"),
s => f.write_str(s), s => f.write_str(s),
}?, }?,
Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered for '{}'", s)?, Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered for {}", s)?,
Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?, Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?,
Self::ErrorFor(_) => f.write_str("For loop expects a type with an iterator defined")?, Self::ErrorFor(_) => f.write_str("For loop expects a type with an iterator defined")?,
Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?, Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?,

View File

@ -9,14 +9,13 @@ use crate::engine::{
use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn}; use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn};
use crate::fn_native::FnAny; use crate::fn_native::FnAny;
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::token::Token;
use crate::{ use crate::{
ast::{Expr, Stmt}, ast::{Expr, Stmt},
calc_fn_hash, calc_fn_params_hash, combine_hashes,
fn_native::CallableFunction, fn_native::CallableFunction,
RhaiResult, Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, ParseErrorType,
}; Position, RhaiResult, Scope, StaticVec,
use crate::{
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, EvalAltResult, FnPtr,
Identifier, ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec,
}; };
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -135,8 +134,13 @@ impl Engine {
args: &[&mut Dynamic], args: &[&mut Dynamic],
) -> String { ) -> String {
format!( format!(
"{}{} ({})", "{}{}{} ({})",
namespace.map_or(String::new(), |ns| ns.to_string()), namespace.map_or(String::new(), |ns| ns.to_string()),
if namespace.is_some() {
Token::DoubleColon.literal_syntax()
} else {
""
},
fn_name, fn_name,
args.iter() args.iter()
.map(|a| if a.is::<ImmutableString>() { .map(|a| if a.is::<ImmutableString>() {
@ -1393,7 +1397,7 @@ impl Engine {
} }
let module = self.search_imports(mods, state, namespace).ok_or_else(|| { let module = self.search_imports(mods, state, namespace).ok_or_else(|| {
EvalAltResult::ErrorModuleNotFound(namespace[0].name.to_string(), namespace[0].pos) EvalAltResult::ErrorModuleNotFound(namespace.to_string(), namespace[0].pos)
})?; })?;
// First search in script-defined functions (can override built-in) // First search in script-defined functions (can override built-in)

View File

@ -1677,17 +1677,21 @@ impl fmt::Debug for NamespaceRef {
.iter() .iter()
.map(|Ident { name, .. }| name.as_str()) .map(|Ident { name, .. }| name.as_str())
.collect::<StaticVec<_>>() .collect::<StaticVec<_>>()
.join("::"), .join(Token::DoubleColon.literal_syntax()),
) )
} }
} }
impl fmt::Display for NamespaceRef { impl fmt::Display for NamespaceRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for Ident { name, .. } in self.path.iter() { f.write_str(
write!(f, "{}{}", name, Token::DoubleColon.syntax())?; &self
} .path
Ok(()) .iter()
.map(|Ident { name, .. }| name.as_str())
.collect::<StaticVec<_>>()
.join(Token::DoubleColon.literal_syntax()),
)
} }
} }

View File

@ -107,7 +107,12 @@ fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
list.push(make_metadata(dict, Some(namespace.clone()), f).into()) list.push(make_metadata(dict, Some(namespace.clone()), f).into())
}); });
module.iter_sub_modules().for_each(|(ns, m)| { module.iter_sub_modules().for_each(|(ns, m)| {
let ns = format!("{}::{}", namespace, ns); let ns = format!(
"{}{}{}",
namespace,
crate::token::Token::DoubleColon.literal_syntax(),
ns
);
scan_module(list, dict, ns.into(), m.as_ref()) scan_module(list, dict, ns.into(), m.as_ref())
}); });
} }