Split AST::set_source into set_source/clear_source.

This commit is contained in:
Stephen Chung 2021-01-09 15:20:07 +08:00
parent 1513e6ab6a
commit 637f47d259
5 changed files with 30 additions and 15 deletions

View File

@ -10,6 +10,7 @@ Breaking changes
* The error variant `EvalAltResult::ErrorInFunctionCall` has a new parameter holding the _source_ of the function. * The error variant `EvalAltResult::ErrorInFunctionCall` has a new parameter holding the _source_ of the function.
* `ParseErrorType::WrongFnDefinition` is renamed `FnWrongDefinition`. * `ParseErrorType::WrongFnDefinition` is renamed `FnWrongDefinition`.
* Redefining an existing function within the same script now throws a new `ParseErrorType::FnDuplicatedDefinition`. This is to prevent accidental overwriting an earlier function definition. * Redefining an existing function within the same script now throws a new `ParseErrorType::FnDuplicatedDefinition`. This is to prevent accidental overwriting an earlier function definition.
* `AST::set_source` is now split into `AST::set_source` and `AST::clear_source`.
New features New features
------------ ------------

View File

@ -218,24 +218,32 @@ impl AST {
resolver: None, resolver: None,
} }
} }
/// Get the source. /// Get the source, if any.
#[inline(always)] #[inline(always)]
pub fn source(&self) -> Option<&str> { pub fn source(&self) -> Option<&str> {
self.source.as_ref().map(|s| s.as_str()) self.source.as_ref().map(|s| s.as_str())
} }
/// Clone the source. /// Clone the source, if any.
#[inline(always)] #[inline(always)]
pub(crate) fn clone_source(&self) -> Option<ImmutableString> { pub(crate) fn clone_source(&self) -> Option<ImmutableString> {
self.source.clone() self.source.clone()
} }
/// Set the source. /// Set the source.
#[inline(always)] #[inline(always)]
pub fn set_source<S: Into<ImmutableString>>(&mut self, source: Option<S>) { pub fn set_source(&mut self, source: impl Into<ImmutableString>) -> &mut Self {
self.source = source.map(|s| s.into()); self.source = Some(source.into());
if let Some(module) = Shared::get_mut(&mut self.functions) { if let Some(module) = Shared::get_mut(&mut self.functions) {
module.set_id(self.source.clone()); module.set_id(self.source.clone());
} }
self
}
/// Clear the source.
#[inline(always)]
pub fn clear_source(&mut self) -> &mut Self {
self.source = None;
self
} }
/// Get the statements. /// Get the statements.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]

View File

@ -92,7 +92,7 @@ fn main() {
.compile(&contents) .compile(&contents)
.map_err(|err| err.into()) .map_err(|err| err.into())
.and_then(|mut ast| { .and_then(|mut ast| {
ast.set_source(Some(&filename)); ast.set_source(&filename);
Module::eval_ast_as_new(Default::default(), &ast, &engine) Module::eval_ast_as_new(Default::default(), &ast, &engine)
}) { }) {
Err(err) => { Err(err) => {

View File

@ -212,7 +212,7 @@ impl ModuleResolver for FileModuleResolver {
_ => Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos)), _ => Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos)),
})?; })?;
ast.set_source(Some(path)); ast.set_source(path);
// Make a module from the AST // Make a module from the AST
let m: Shared<Module> = Module::eval_ast_as_new(scope, &ast, engine) let m: Shared<Module> = Module::eval_ast_as_new(scope, &ast, engine)

View File

@ -247,19 +247,25 @@ fn test_module_resolver() -> Result<(), Box<EvalAltResult>> {
)?; )?;
} }
let script = r#" #[cfg(not(feature = "no_function"))]
import "hello" as h; {
h::answer let script = r#"
"#; fn foo() {
let mut scope = Scope::new(); import "hello" as h;
h::answer
}
foo() + { import "hello" as h; h::answer }
"#;
let mut scope = Scope::new();
let ast = engine.compile_into_self_contained(&mut scope, script)?; let ast = engine.compile_into_self_contained(&mut scope, script)?;
engine.set_module_resolver(DummyModuleResolver::new()); engine.set_module_resolver(DummyModuleResolver::new());
assert_eq!(engine.eval_ast::<INT>(&ast)?, 42); assert_eq!(engine.eval_ast::<INT>(&ast)?, 84);
assert!(engine.eval::<INT>(script).is_err()); assert!(engine.eval::<INT>(script).is_err());
}
Ok(()) Ok(())
} }