From 99118fe2c377314563eb41a3b3bf3c3cb874397d Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 20 Mar 2022 21:58:43 +0800 Subject: [PATCH] Minor refactors. --- CHANGELOG.md | 5 +++++ codegen/src/lib.rs | 8 +++---- codegen/src/module.rs | 30 ++++++++++++--------------- src/api/compile.rs | 45 ++++++++++++++++++++-------------------- src/api/events.rs | 4 ++-- src/api/mod.rs | 2 +- src/ast/ast.rs | 7 ++++--- src/ast/stmt.rs | 20 ++++++++++++++++++ src/engine.rs | 33 ++++++++++++++--------------- src/eval/eval_context.rs | 7 ++++--- src/eval/eval_state.rs | 2 +- src/eval/global_state.rs | 7 ++++--- src/eval/stmt.rs | 7 ++++--- src/func/call.rs | 35 +++++++++++++------------------ 14 files changed, 114 insertions(+), 98 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f9eac99..2fb11d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ Bug fixes * Exporting a variable that contains a local function pointer (including anonymous function or closure) now raises a runtime error. * Full optimization is now skipped for method calls. +New features +------------ + +* [Type aliases](https://doc.rust-lang.org/reference/items/type-aliases.html) in plugin modules are now used as friendly names for custom types. This makes plugin modules more self-contained when they are used to define a custom type's API. + Enhancements ------------ diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 3be27449..915b6741 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -269,7 +269,7 @@ pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::Toke pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream { match crate::register::parse_register_macro(args) { Ok((module_expr, _export_name, module_path)) => proc_macro::TokenStream::from(quote! { - #module_path::rhai_generate_into_module(#module_expr, true); + #module_path::rhai_generate_into_module(#module_expr, true) }), Err(e) => e.to_compile_error().into(), } @@ -303,7 +303,7 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS Ok((engine_expr, export_name, rust_mod_path)) => { let gen_mod_path = crate::register::generated_module_path(&rust_mod_path); proc_macro::TokenStream::from(quote! { - #engine_expr.register_result_fn(#export_name, #gen_mod_path::dynamic_result_fn); + #engine_expr.register_result_fn(#export_name, #gen_mod_path::dynamic_result_fn) }) } Err(e) => e.to_compile_error().into(), @@ -352,7 +352,7 @@ pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream #module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public, #param_names, &#gen_mod_path::Token::param_types(), - #gen_mod_path::Token().into()); + #gen_mod_path::Token().into()) }) } Err(e) => e.to_compile_error().into(), @@ -401,7 +401,7 @@ pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::Toke #module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public, #param_names, &#gen_mod_path::Token::param_types(), - #gen_mod_path::Token().into()); + #gen_mod_path::Token().into()) }) } Err(e) => e.to_compile_error().into(), diff --git a/codegen/src/module.rs b/codegen/src/module.rs index bafd1b33..52b9716c 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -140,20 +140,18 @@ impl Parse for Module { for item in content.iter() { match item { syn::Item::Const(syn::ItemConst { - vis, + vis: syn::Visibility::Public(..), ref expr, ident, attrs, ty, .. - }) if matches!(vis, syn::Visibility::Public(..)) => { - consts.push(ExportedConst { - name: ident.to_string(), - typ: ty.clone(), - expr: expr.as_ref().clone(), - cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), - }) - } + }) => consts.push(ExportedConst { + name: ident.to_string(), + typ: ty.clone(), + expr: expr.as_ref().clone(), + cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), + }), _ => {} } } @@ -161,18 +159,16 @@ impl Parse for Module { for item in content.iter() { match item { syn::Item::Type(syn::ItemType { - vis, + vis: syn::Visibility::Public(..), ident, attrs, ty, .. - }) if matches!(vis, syn::Visibility::Public(..)) => { - custom_types.push(ExportedType { - name: ident.to_string(), - typ: ty.clone(), - cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), - }) - } + }) => custom_types.push(ExportedType { + name: ident.to_string(), + typ: ty.clone(), + cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), + }), _ => {} } } diff --git a/src/api/compile.rs b/src/api/compile.rs index 39a6ed79..4a3c0490 100644 --- a/src/api/compile.rs +++ b/src/api/compile.rs @@ -115,33 +115,34 @@ impl Engine { let mut ast = self.compile_scripts_with_scope(scope, &[script])?; - if let Some(ref module_resolver) = self.module_resolver { - let mut resolver = StaticModuleResolver::new(); - let mut imports = BTreeSet::new(); + let mut resolver = StaticModuleResolver::new(); + let mut imports = BTreeSet::new(); - collect_imports(&ast, &resolver, &mut imports); + collect_imports(&ast, &resolver, &mut imports); - if !imports.is_empty() { - while let Some(path) = imports.iter().next() { - let path = path.clone(); + if !imports.is_empty() { + while let Some(path) = imports.iter().next() { + let path = path.clone(); - match module_resolver.resolve_ast(self, None, &path, crate::Position::NONE) { - Some(Ok(module_ast)) => { - collect_imports(&module_ast, &resolver, &mut imports) - } - Some(err) => return err, - None => (), - } - - let module = - module_resolver.resolve(self, None, &path, crate::Position::NONE)?; - let module = shared_take_or_clone(module); - - imports.remove(&path); - resolver.insert(path, module); + match self + .module_resolver + .resolve_ast(self, None, &path, crate::Position::NONE) + { + Some(Ok(module_ast)) => collect_imports(&module_ast, &resolver, &mut imports), + Some(err) => return err, + None => (), } - ast.set_resolver(resolver); + + let module = + self.module_resolver + .resolve(self, None, &path, crate::Position::NONE)?; + + let module = shared_take_or_clone(module); + + imports.remove(&path); + resolver.insert(path, module); } + ast.set_resolver(resolver); } Ok(ast) diff --git a/src/api/events.rs b/src/api/events.rs index 0f0061d4..782d211c 100644 --- a/src/api/events.rs +++ b/src/api/events.rs @@ -282,7 +282,7 @@ impl Engine { /// ``` #[inline(always)] pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self { - self.print = Some(Box::new(callback)); + self.print = Box::new(callback); self } /// Override default action of `debug` (print to stdout using [`println!`]) @@ -332,7 +332,7 @@ impl Engine { &mut self, callback: impl Fn(&str, Option<&str>, Position) + SendSync + 'static, ) -> &mut Self { - self.debug = Some(Box::new(callback)); + self.debug = Box::new(callback); self } /// _(debugging)_ Register a callback for debugging. diff --git a/src/api/mod.rs b/src/api/mod.rs index 2b94013a..25431175 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -71,7 +71,7 @@ impl Engine { &mut self, resolver: impl crate::ModuleResolver + 'static, ) -> &mut Self { - self.module_resolver = Some(Box::new(resolver)); + self.module_resolver = Box::new(resolver); self } diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 7c0115e5..7e6f56c7 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -150,9 +150,10 @@ impl AST { #[inline(always)] #[must_use] pub fn source(&self) -> Option<&str> { - match self.source.as_str() { - "" => None, - s => Some(s), + if self.source.is_empty() { + None + } else { + Some(self.source.as_str()) } } /// Get a reference to the source. diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 815c0f8b..33fbd75a 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -89,6 +89,26 @@ pub struct ConditionalStmtBlock { pub statements: StmtBlock, } +impl> From for ConditionalStmtBlock { + #[inline(always)] + fn from(value: B) -> Self { + Self { + condition: None, + statements: value.into(), + } + } +} + +impl> From<(Expr, B)> for ConditionalStmtBlock { + #[inline(always)] + fn from(value: (Expr, B)) -> Self { + Self { + condition: Some(value.0), + statements: value.1.into(), + } + } +} + impl> From<(Option, B)> for ConditionalStmtBlock { #[inline(always)] fn from(value: (Option, B)) -> Self { diff --git a/src/engine.rs b/src/engine.rs index f180f624..34218fda 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,6 +1,7 @@ //! Main module defining the script evaluation [`Engine`]. use crate::api::custom_syntax::CustomSyntax; +use crate::api::options::LanguageOptions; use crate::func::native::{ OnDebugCallback, OnDefVarCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback, }; @@ -102,7 +103,7 @@ pub struct Engine { /// A module resolution service. #[cfg(not(feature = "no_module"))] - pub(crate) module_resolver: Option>, + pub(crate) module_resolver: Box, /// A map mapping type names to pretty-print names. pub(crate) custom_types: CustomTypesCollection, @@ -124,9 +125,9 @@ pub struct Engine { pub(crate) token_mapper: Option>, /// Callback closure for implementing the `print` command. - pub(crate) print: Option>, + pub(crate) print: Box, /// Callback closure for implementing the `debug` command. - pub(crate) debug: Option>, + pub(crate) debug: Box, /// Callback closure for progress reporting. #[cfg(not(feature = "unchecked"))] pub(crate) progress: Option>, @@ -135,7 +136,7 @@ pub struct Engine { pub(crate) optimization_level: OptimizationLevel, /// Language options. - pub(crate) options: crate::api::options::LanguageOptions, + pub(crate) options: LanguageOptions, /// Max limits. #[cfg(not(feature = "unchecked"))] @@ -157,8 +158,7 @@ impl fmt::Debug for Engine { f.field("global_modules", &self.global_modules); #[cfg(not(feature = "no_module"))] - f.field("global_sub_modules", &self.global_sub_modules) - .field("module_resolver", &self.module_resolver.is_some()); + f.field("global_sub_modules", &self.global_sub_modules); f.field("type_names", &self.custom_types) .field("disabled_symbols", &self.disabled_symbols) @@ -166,9 +166,7 @@ impl fmt::Debug for Engine { .field("custom_syntax", &(!self.custom_syntax.is_empty())) .field("def_var_filter", &self.def_var_filter.is_some()) .field("resolve_var", &self.resolve_var.is_some()) - .field("token_mapper", &self.token_mapper.is_some()) - .field("print", &self.print.is_some()) - .field("debug", &self.debug.is_some()); + .field("token_mapper", &self.token_mapper.is_some()); #[cfg(not(feature = "unchecked"))] f.field("progress", &self.progress.is_some()); @@ -226,16 +224,15 @@ impl Engine { #[cfg(not(feature = "no_std"))] #[cfg(not(target_family = "wasm"))] { - engine.module_resolver = - Some(Box::new(crate::module::resolvers::FileModuleResolver::new())); + engine.module_resolver = Box::new(crate::module::resolvers::FileModuleResolver::new()); } // default print/debug implementations #[cfg(not(feature = "no_std"))] #[cfg(not(target_family = "wasm"))] { - engine.print = Some(Box::new(|s| println!("{}", s))); - engine.debug = Some(Box::new(|s, source, pos| { + engine.print = Box::new(|s| println!("{}", s)); + engine.debug = Box::new(|s, source, pos| { if let Some(source) = source { println!("{} @ {:?} | {}", source, pos, s); } else if pos.is_none() { @@ -243,7 +240,7 @@ impl Engine { } else { println!("{:?} | {}", pos, s); } - })); + }); } #[cfg(any(feature = "no_std", target_family = "wasm"))] { @@ -269,7 +266,7 @@ impl Engine { global_sub_modules: BTreeMap::new(), #[cfg(not(feature = "no_module"))] - module_resolver: None, + module_resolver: Box::new(crate::module::resolvers::DummyModuleResolver::new()), custom_types: CustomTypesCollection::new(), empty_string: ImmutableString::new(), @@ -281,15 +278,15 @@ impl Engine { resolve_var: None, token_mapper: None, - print: None, - debug: None, + print: Box::new(|_| {}), + debug: Box::new(|_, _, _| {}), #[cfg(not(feature = "unchecked"))] progress: None, optimization_level: OptimizationLevel::default(), - options: crate::api::options::LanguageOptions::new(), + options: LanguageOptions::new(), #[cfg(not(feature = "unchecked"))] limits: crate::api::limits::Limits::new(), diff --git a/src/eval/eval_context.rs b/src/eval/eval_context.rs index 2191bb44..f378076b 100644 --- a/src/eval/eval_context.rs +++ b/src/eval/eval_context.rs @@ -35,9 +35,10 @@ impl<'x, 'px, 'm, 'pm, 'pt> EvalContext<'_, 'x, 'px, 'm, 'pm, '_, '_, '_, '_, 'p #[inline(always)] #[must_use] pub fn source(&self) -> Option<&str> { - match self.global.source.as_str() { - "" => None, - s => Some(s), + if self.global.source.is_empty() { + None + } else { + Some(self.global.source.as_str()) } } /// The current [`Scope`]. diff --git a/src/eval/eval_state.rs b/src/eval/eval_state.rs index 943831b7..5f8a7c3a 100644 --- a/src/eval/eval_state.rs +++ b/src/eval/eval_state.rs @@ -28,7 +28,7 @@ pub struct EvalState<'a> { /// Stack of function resolution caches. fn_resolution_caches: StaticVec, /// Take care of the lifetime parameter - dummy: PhantomData>, + dummy: PhantomData<&'a ()>, } impl EvalState<'_> { diff --git a/src/eval/global_state.rs b/src/eval/global_state.rs index 1363f108..a7d6aeb6 100644 --- a/src/eval/global_state.rs +++ b/src/eval/global_state.rs @@ -244,9 +244,10 @@ impl GlobalRuntimeState<'_> { #[inline] #[must_use] pub fn source(&self) -> Option<&str> { - match self.source.as_str() { - "" => None, - s => Some(s), + if self.source.is_empty() { + None + } else { + Some(self.source.as_str()) } } /// Get the pre-calculated index getter hash. diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 1a1244fd..4e33f28a 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -952,9 +952,10 @@ impl Engine { result => Some(result), }) .or_else(|| { - self.module_resolver - .as_ref() - .map(|r| r.resolve_raw(self, global, &path, path_pos)) + Some( + self.module_resolver + .resolve_raw(self, global, &path, path_pos), + ) }) .unwrap_or_else(|| { Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into()) diff --git a/src/func/call.rs b/src/func/call.rs index 1a5e9960..3b256349 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -464,30 +464,23 @@ impl Engine { // See if the function match print/debug (which requires special processing) return Ok(match name { KEYWORD_PRINT => { - if let Some(ref print) = self.print { - let text = result.into_immutable_string().map_err(|typ| { - let t = self.map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), pos) - })?; - (print(&text).into(), false) - } else { - (Dynamic::UNIT, false) - } + let text = result.into_immutable_string().map_err(|typ| { + let t = self.map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), pos) + })?; + ((&*self.print)(&text).into(), false) } KEYWORD_DEBUG => { - if let Some(ref debug) = self.debug { - let text = result.into_immutable_string().map_err(|typ| { - let t = self.map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), pos) - })?; - let source = match global.source.as_str() { - "" => None, - s => Some(s), - }; - (debug(&text, source, pos).into(), false) + let text = result.into_immutable_string().map_err(|typ| { + let t = self.map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), pos) + })?; + let source = if global.source.is_empty() { + None } else { - (Dynamic::UNIT, false) - } + Some(global.source.as_str()) + }; + ((&*self.debug)(&text, source, pos).into(), false) } _ => (result, is_method), });