Add position to script error.

This commit is contained in:
Stephen Chung 2020-05-06 00:09:04 +08:00
parent 82e1af7acd
commit c9571d375a
4 changed files with 34 additions and 10 deletions

View File

@ -2120,6 +2120,13 @@ Built-in module resolvers are grouped under the `rhai::module_resolvers` module
| `StaticModuleResolver` | Loads modules that are statically added. This can be used when the [`no_std`] feature is turned on. | | `StaticModuleResolver` | Loads modules that are statically added. This can be used when the [`no_std`] feature is turned on. |
| `NullModuleResolver` | The default module resolution service under the [`no_std`] feature. Always returns an `EvalAltResult::ErrorModuleNotFound` error. | | `NullModuleResolver` | The default module resolution service under the [`no_std`] feature. Always returns an `EvalAltResult::ErrorModuleNotFound` error. |
An [`Engine`]'s module resolver is set via a call to `set_module_resolver`:
```rust
// Use the 'NullModuleResolver'
engine.set_module_resolver(rhai::module_resolvers::NullModuleResolver::new());
```
Script optimization Script optimization
=================== ===================

View File

@ -437,13 +437,23 @@ impl Engine {
/// Read the contents of a file into a string. /// Read the contents of a file into a string.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
fn read_file(path: PathBuf) -> Result<String, Box<EvalAltResult>> { fn read_file(path: PathBuf) -> Result<String, Box<EvalAltResult>> {
let mut f = File::open(path.clone()) let mut f = File::open(path.clone()).map_err(|err| {
.map_err(|err| Box::new(EvalAltResult::ErrorReadingScriptFile(path.clone(), err)))?; Box::new(EvalAltResult::ErrorReadingScriptFile(
path.clone(),
Position::none(),
err,
))
})?;
let mut contents = String::new(); let mut contents = String::new();
f.read_to_string(&mut contents) f.read_to_string(&mut contents).map_err(|err| {
.map_err(|err| Box::new(EvalAltResult::ErrorReadingScriptFile(path.clone(), err)))?; Box::new(EvalAltResult::ErrorReadingScriptFile(
path.clone(),
Position::none(),
err,
))
})?;
Ok(contents) Ok(contents)
} }

View File

@ -1530,7 +1530,10 @@ impl Engine {
.eval_expr(scope, state, fn_lib, expr, level)? .eval_expr(scope, state, fn_lib, expr, level)?
.try_cast::<String>() .try_cast::<String>()
{ {
let module = self.module_resolver.resolve(self, &path)?; let module = self
.module_resolver
.resolve(self, &path)
.map_err(|err| EvalAltResult::set_position(err, expr.position()))?;
// TODO - avoid copying module name in inner block? // TODO - avoid copying module name in inner block?
let mod_name = name.as_ref().clone(); let mod_name = name.as_ref().clone();

View File

@ -29,7 +29,7 @@ pub enum EvalAltResult {
/// ///
/// Never appears under the `no_std` feature. /// Never appears under the `no_std` feature.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
ErrorReadingScriptFile(PathBuf, std::io::Error), ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
/// Call to an unknown function. Wrapped value is the name of the function. /// Call to an unknown function. Wrapped value is the name of the function.
ErrorFunctionNotFound(String, Position), ErrorFunctionNotFound(String, Position),
@ -94,7 +94,7 @@ impl EvalAltResult {
pub(crate) fn desc(&self) -> &str { pub(crate) fn desc(&self) -> &str {
match self { match self {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => "Cannot read from script file", Self::ErrorReadingScriptFile(_, _, _) => "Cannot read from script file",
Self::ErrorParsing(p) => p.desc(), Self::ErrorParsing(p) => p.desc(),
Self::ErrorFunctionNotFound(_, _) => "Function not found", Self::ErrorFunctionNotFound(_, _) => "Function not found",
@ -150,9 +150,13 @@ impl fmt::Display for EvalAltResult {
match self { match self {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(path, err) => { Self::ErrorReadingScriptFile(path, pos, err) if pos.is_none() => {
write!(f, "{} '{}': {}", desc, path.display(), err) write!(f, "{} '{}': {}", desc, path.display(), err)
} }
#[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(path, pos, err) => {
write!(f, "{} '{}': {} ({})", desc, path.display(), err, pos)
}
Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p), Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p),
@ -261,7 +265,7 @@ impl EvalAltResult {
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => Position::none(), Self::ErrorReadingScriptFile(_, pos, _) => *pos,
Self::ErrorParsing(err) => err.position(), Self::ErrorParsing(err) => err.position(),
@ -297,7 +301,7 @@ impl EvalAltResult {
pub(crate) fn set_position(mut err: Box<Self>, new_position: Position) -> Box<Self> { pub(crate) fn set_position(mut err: Box<Self>, new_position: Position) -> Box<Self> {
match err.as_mut() { match err.as_mut() {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => (), Self::ErrorReadingScriptFile(_, pos, _) => *pos = new_position,
Self::ErrorParsing(err) => err.1 = new_position, Self::ErrorParsing(err) => err.1 = new_position,