From 2b0aacde23780e7399fcb53a6b712074203be67a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 24 Jul 2020 23:16:54 +0800 Subject: [PATCH 1/8] Fix Module::set_indexer_set_fn. --- RELEASES.md | 1 + src/engine.rs | 4 ++-- src/module.rs | 42 ++++++++++++++++++++++++++++++++++++++---- tests/functions.rs | 14 ++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 8ba7d09c..22aae65d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -18,6 +18,7 @@ New features * Anonymous functions in the syntax of a closure, e.g. `|x, y, z| x + y - z`. * Custom syntax now works even without the `internals` feature. * Currying of function pointers is supported via the `curry` keyword. +* `Module::set_indexer_get_set_fn` is added as a shorthand of both `Module::set_indexer_get_fn` and `Module::set_indexer_set_fn`. Breaking changes ---------------- diff --git a/src/engine.rs b/src/engine.rs index cb7234d3..f34cb7ca 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -11,7 +11,7 @@ use crate::parser::{Expr, FnAccess, ImmutableString, ReturnType, ScriptFnDef, St use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::result::EvalAltResult; use crate::scope::{EntryType as ScopeEntryType, Scope}; -use crate::syntax::{CustomSyntax, EvalContext, Expression}; +use crate::syntax::{CustomSyntax, EvalContext}; use crate::token::Position; use crate::utils::StaticVec; @@ -1020,7 +1020,7 @@ impl Engine { map.entry(index).or_insert(Default::default()).into() } else { let index = idx - .downcast_ref::() + .downcast_ref::() .ok_or_else(|| EvalAltResult::ErrorStringIndexExpr(idx_pos))?; map.get_mut(index.as_str()) diff --git a/src/module.rs b/src/module.rs index 7216c248..11787e1c 100644 --- a/src/module.rs +++ b/src/module.rs @@ -738,18 +738,18 @@ impl Module { /// }); /// assert!(module.contains_fn(hash)); /// ``` - pub fn set_indexer_set_fn( + pub fn set_indexer_set_fn( &mut self, - func: impl Fn(&mut A, B, A) -> FuncReturn<()> + SendSync + 'static, + func: impl Fn(&mut A, B, C) -> FuncReturn<()> + SendSync + 'static, ) -> u64 { let f = move |_: &Engine, _: &Module, args: &mut FnCallArgs| { let b = mem::take(args[1]).cast::(); - let c = mem::take(args[2]).cast::(); + let c = mem::take(args[2]).cast::(); let a = args[0].downcast_mut::().unwrap(); func(a, b, c).map(Dynamic::from) }; - let arg_types = [TypeId::of::(), TypeId::of::(), TypeId::of::()]; + let arg_types = [TypeId::of::(), TypeId::of::(), TypeId::of::()]; self.set_fn( FN_IDX_SET, Public, @@ -758,6 +758,40 @@ impl Module { ) } + /// Set a pair of Rust index getter and setter functions, returning both hash keys. + /// This is a shorthand for `set_indexer_get_fn` and `set_indexer_set_fn`. + /// + /// If there are similar existing Rust functions, they are replaced. + /// + /// # Examples + /// + /// ``` + /// use rhai::{Module, ImmutableString}; + /// + /// let mut module = Module::new(); + /// let (hash_get, hash_set) = module.set_indexer_get_set_fn( + /// |x: &mut i64, y: ImmutableString| { + /// Ok(*x + y.len() as i64) + /// }, + /// |x: &mut i64, y: ImmutableString, value: i64| { + /// *x = y.len() as i64 + value; + /// Ok(()) + /// } + /// ); + /// assert!(module.contains_fn(hash_get)); + /// assert!(module.contains_fn(hash_set)); + /// ``` + pub fn set_indexer_get_set_fn( + &mut self, + getter: impl Fn(&mut A, B) -> FuncReturn + SendSync + 'static, + setter: impl Fn(&mut A, B, T) -> FuncReturn<()> + SendSync + 'static, + ) -> (u64, u64) { + ( + self.set_indexer_get_fn(getter), + self.set_indexer_set_fn(setter), + ) + } + /// Set a Rust function taking four parameters into the module, returning a hash key. /// /// If there is a similar existing Rust function, it is replaced. diff --git a/tests/functions.rs b/tests/functions.rs index 3c0a080b..78d20fa3 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -104,5 +104,19 @@ fn test_function_pointers() -> Result<(), Box> { 42 ); + #[cfg(not(feature = "no_object"))] + assert_eq!( + engine.eval::( + r#" + fn foo(x) { this.data += x; } + + let x = #{ data: 40, action: Fn("foo") }; + x.action(2); + x.data + "# + )?, + 42 + ); + Ok(()) } From 554ee07e01b85fda6c143fb3439cbb9b49d8a592 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 09:47:50 +0800 Subject: [PATCH 2/8] Restore benchmark.yml. --- .github/workflows/benchmark.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/benchmark.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000..df310705 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,29 @@ +name: Benchmark +on: + push: + branches: + - master + +jobs: + benchmark: + name: Run Rust benchmark + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: rustup toolchain update nightly && rustup default nightly + - name: Run benchmark + run: cargo +nightly bench | tee output.txt + - name: Store benchmark result + uses: rhysd/github-action-benchmark@v1 + with: + name: Rust Benchmark + tool: 'cargo' + output-file-path: output.txt + # Use personal access token instead of GITHUB_TOKEN due to https://github.community/t5/GitHub-Actions/Github-action-not-triggering-gh-pages-upon-push/td-p/26869/highlight/false + github-token: ${{ secrets.RHAI }} + auto-push: true + # Show alert with commit comment on detecting possible performance regression + alert-threshold: '200%' + comment-on-alert: true + fail-on-alert: true + alert-comment-cc-users: '@schungx' From 463d669ab50fe07c2f54ad70ec610a5c9fa073b3 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 09:55:33 +0800 Subject: [PATCH 3/8] Avoid shadowing indexer errors. --- src/engine.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index f34cb7ca..dccc308f 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1050,6 +1050,7 @@ impl Engine { } } + #[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_index"))] _ => { let type_name = self.map_type_name(val.type_name()); @@ -1058,11 +1059,11 @@ impl Engine { state, lib, FN_IDX_GET, true, 0, args, is_ref, true, None, level, ) .map(|(v, _)| v.into()) - .map_err(|_| { - Box::new(EvalAltResult::ErrorIndexingType( - type_name.into(), - Position::none(), - )) + .map_err(|err| match *err { + EvalAltResult::ErrorFunctionNotFound(_, _) => Box::new( + EvalAltResult::ErrorIndexingType(type_name.into(), Position::none()), + ), + _ => err, }) } From b4b7abdcb0cbdebf86029618bc073f997f03f3c8 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 14:06:04 +0800 Subject: [PATCH 4/8] Add license to README. --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b40d97a8..88d26eae 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,13 @@ Scripts can be evaluated directly from the editor. License ------- -Licensed under either of Apache License, Version -2.0 or MIT license at your option. +Licensed under either: -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. +* [Apache License, Version 2.0](https://github.com/jonathandturner/rhai/blob/master/LICENSE-APACHE.txt), or +* [MIT license](https://github.com/jonathandturner/rhai/blob/master/LICENSE-MIT.txt) + +at your option. + +Unless explicitly stated otherwise, any contribution intentionally submitted +for inclusion in this crate, as defined in the Apache-2.0 license, shall +be dual-licensed as above, without any additional terms or conditions. From a58207aaa93bbb527f48bfa97ddc42fe4302127c Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 14:06:13 +0800 Subject: [PATCH 5/8] Change ScriptFnDef to use ImmutableString. --- src/optimize.rs | 4 ++-- src/parser.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/optimize.rs b/src/optimize.rs index eaa8aeb3..738ea300 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -456,7 +456,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { // "xxx" in "xxxxx" (Expr::StringConstant(a), Expr::StringConstant(b)) => { state.set_dirty(); - if b.0.contains(a.0.as_ref()) { Expr::True(a.1) } else { Expr::False(a.1) } + if b.0.contains(a.0.as_str()) { Expr::True(a.1) } else { Expr::False(a.1) } } // 'x' in "xxxxx" (Expr::CharConstant(a), Expr::StringConstant(b)) => { @@ -560,7 +560,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { let has_script_fn = state.lib.iter_fn().find(|(_, _, _, f)| { if !f.is_script() { return false; } let fn_def = f.get_fn_def(); - &fn_def.name == name && (args.len()..=args.len() + 1).contains(&fn_def.params.len()) + fn_def.name.as_str() == name && (args.len()..=args.len() + 1).contains(&fn_def.params.len()) }).is_some(); #[cfg(feature = "no_function")] diff --git a/src/parser.rs b/src/parser.rs index b6a3fa08..0655c903 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -346,7 +346,7 @@ impl fmt::Display for FnAccess { #[derive(Debug, Clone, Hash)] pub struct ScriptFnDef { /// Function name. - pub name: String, + pub name: ImmutableString, /// Function access mode. pub access: FnAccess, /// Names of function parameters. @@ -2852,7 +2852,7 @@ fn parse_fn( let params = params.into_iter().map(|(p, _)| p).collect(); Ok(ScriptFnDef { - name, + name: name.into(), access, params, body, @@ -2940,7 +2940,7 @@ fn parse_anon_fn( let hash = s.finish(); // Create unique function name - let fn_name = format!("{}{}", FN_ANONYMOUS, hash); + let fn_name: ImmutableString = format!("{}{:16x}", FN_ANONYMOUS, hash).into(); let script = ScriptFnDef { name: fn_name.clone(), @@ -2950,7 +2950,7 @@ fn parse_anon_fn( pos: settings.pos, }; - let expr = Expr::FnPointer(Box::new((fn_name.into(), settings.pos))); + let expr = Expr::FnPointer(Box::new((fn_name, settings.pos))); Ok((expr, script)) } From 284e58e8a1e1ad35b5887046761b86c4808f63cf Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 15:52:27 +0800 Subject: [PATCH 6/8] Improve documentation on internal types. --- Cargo.toml | 3 ++ src/engine.rs | 10 ++++ src/error.rs | 7 ++- src/fn_native.rs | 4 +- src/lib.rs | 2 +- src/module.rs | 8 +++- src/parser.rs | 41 ++++++++++++++-- src/syntax.rs | 3 +- src/token.rs | 118 +++++++++++++++++++++++++++++++++++++++++++++-- src/utils.rs | 9 +++- 10 files changed, 191 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf4e0dc2..2f2ab525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,3 +75,6 @@ optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] instant= { version = "0.1.4", features = ["wasm-bindgen"] } # WASM implementation of std::time::Instant + +[package.metadata.docs.rs] +features = [ "serde", "internals" ] diff --git a/src/engine.rs b/src/engine.rs index dccc308f..cb0a3000 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -39,6 +39,11 @@ pub type Array = Vec; pub type Map = HashMap; /// A stack of imported modules. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. pub type Imports<'a> = Vec<(Cow<'a, str>, Module)>; #[cfg(not(feature = "unchecked"))] @@ -190,11 +195,16 @@ impl> From for Target<'_> { } /// A type that holds all the current states of the Engine. +/// Exported under the `internals` feature only. /// /// # Safety /// /// This type uses some unsafe code, mainly for avoiding cloning of local variable names via /// direct lifetime casting. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Clone, Eq, PartialEq, Hash, Default)] pub struct State { /// Normally, access to variables are parsed with a relative offset into the scope to avoid a lookup. diff --git a/src/error.rs b/src/error.rs index 86c49091..736c9df8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,7 +10,12 @@ use crate::stdlib::{ string::{String, ToString}, }; -/// Error when tokenizing the script text. +/// Error encountered when tokenizing the script text. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Eq, PartialEq, Clone, Hash)] #[non_exhaustive] pub enum LexError { diff --git a/src/fn_native.rs b/src/fn_native.rs index f4de5982..2833729a 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -9,7 +9,9 @@ use crate::token::{is_valid_identifier, Position}; use crate::utils::{ImmutableString, StaticVec}; use crate::Scope; -use crate::stdlib::{boxed::Box, convert::TryFrom, fmt, mem, rc::Rc, string::String, sync::Arc}; +use crate::stdlib::{ + boxed::Box, convert::TryFrom, fmt, mem, rc::Rc, string::String, sync::Arc, vec::Vec, +}; /// Trait that maps to `Send + Sync` only under the `sync` feature. #[cfg(feature = "sync")] diff --git a/src/lib.rs b/src/lib.rs index 87f60cf3..240d87d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,7 +166,7 @@ pub use token::{get_next_token, parse_string_literal, InputStream, Token, Tokeni #[cfg(feature = "internals")] #[deprecated(note = "this type is volatile and may change")] -pub use parser::{CustomExpr, Expr, ReturnType, ScriptFnDef, Stmt}; +pub use parser::{CustomExpr, Expr, FloatWrapper, ReturnType, ScriptFnDef, Stmt}; #[cfg(feature = "internals")] #[deprecated(note = "this type is volatile and may change")] diff --git a/src/module.rs b/src/module.rs index 11787e1c..2a590cb8 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1129,10 +1129,16 @@ impl Module { } /// A chain of module names to qualify a variable or function call. -/// A `u64` hash key is kept for quick search purposes. +/// Exported under the `internals` feature only. +/// +/// A `u64` hash key is cached for quick search purposes. /// /// A `StaticVec` is used because most module-level access contains only one level, /// and it is wasteful to always allocate a `Vec` with one element. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Clone, Eq, PartialEq, Default, Hash)] pub struct ModuleRef(StaticVec<(String, Position)>, Option); diff --git a/src/parser.rs b/src/parser.rs index 0655c903..786f7d85 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -342,7 +342,12 @@ impl fmt::Display for FnAccess { } } -/// A scripted function definition. +/// A type containing information on a scripted function. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Clone, Hash)] pub struct ScriptFnDef { /// Function name. @@ -376,7 +381,12 @@ impl fmt::Display for ScriptFnDef { } } -/// `return`/`throw` statement. +/// A type encapsulating the mode of a `return`/`throw` statement. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] pub enum ReturnType { /// `return` statement. @@ -477,7 +487,8 @@ impl ParseSettings { } } -/// A statement. +/// A Rhai statement. +/// Exported under the `internals` feature only. /// /// Each variant is at most one pointer in size (for speed), /// with everything being allocated together in one single tuple. @@ -582,6 +593,12 @@ impl Stmt { } } +/// A type wrapping a custom syntax definition. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Clone)] pub struct CustomExpr(pub StaticVec, pub Shared); @@ -592,11 +609,20 @@ impl fmt::Debug for CustomExpr { } impl Hash for CustomExpr { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.0.hash(state); } } +/// A type wrapping a floating-point number. +/// Exported under the `internals` feature only. +/// +/// This type is mainly used to provide a standard `Hash` implementation +/// to floating-point numbers, allowing `Expr` to derive `Hash` automatically. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[cfg(not(feature = "no_float"))] #[derive(Debug, PartialEq, PartialOrd, Clone)] pub struct FloatWrapper(pub FLOAT, pub Position); @@ -609,10 +635,15 @@ impl Hash for FloatWrapper { } } -/// An expression. +/// An expression sub-tree. +/// Exported under the `internals` feature only. /// /// Each variant is at most one pointer in size (for speed), /// with everything being allocated together in one single tuple. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Clone, Hash)] pub enum Expr { /// Integer constant. diff --git a/src/syntax.rs b/src/syntax.rs index 485e99ea..616833c1 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -12,7 +12,8 @@ use crate::token::{is_valid_identifier, Position, Token}; use crate::utils::StaticVec; use crate::stdlib::{ - fmt, + boxed::Box, + fmt, format, rc::Rc, string::{String, ToString}, sync::Arc, diff --git a/src/token.rs b/src/token.rs index f2719a7a..82e850d5 100644 --- a/src/token.rs +++ b/src/token.rs @@ -136,89 +136,181 @@ impl fmt::Debug for Position { } } -/// Tokens. +/// A language token. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, PartialEq, Clone)] pub enum Token { + /// An `INT` constant. IntegerConstant(INT), + /// A `FLOAT` constaint. + /// + /// Never appears under the `no_float` feature. #[cfg(not(feature = "no_float"))] FloatConstant(FLOAT), + /// An identifier. Identifier(String), + /// A character constant. CharConstant(char), + /// A string constant. StringConstant(String), + /// `{` LeftBrace, + /// `}` RightBrace, + /// `(` LeftParen, + /// `)` RightParen, + /// `[` LeftBracket, + /// `]` RightBracket, + /// `+` Plus, + /// `+` (unary) UnaryPlus, + /// `-` Minus, + /// `-` (unary) UnaryMinus, + /// `*` Multiply, + /// `/` Divide, + /// `%` Modulo, + /// `~` PowerOf, + /// `<<` LeftShift, + /// `>>` RightShift, + /// `;` SemiColon, + /// `:` Colon, + /// `::` DoubleColon, + /// `,` Comma, + /// `.` Period, + /// `#{` MapStart, + /// `=` Equals, + /// `true` True, + /// `false` False, + /// `let` Let, + /// `const` Const, + /// `if` If, + /// `else` Else, + /// `while` While, + /// `loop` Loop, + /// `for` For, + /// `in` In, + /// `<` LessThan, + /// `>` GreaterThan, + /// `<=` LessThanEqualsTo, + /// `>=` GreaterThanEqualsTo, + /// `==` EqualsTo, + /// `!=` NotEqualsTo, + /// `!` Bang, + /// `|` Pipe, + /// `||` Or, + /// `^` XOr, + /// `&` Ampersand, + /// `&&` And, + /// `fn` + /// + /// Never appears under the `no_function` feature. #[cfg(not(feature = "no_function"))] Fn, + /// `continue` Continue, + /// `break` Break, + /// `return` Return, + /// `throw` Throw, + /// `+=` PlusAssign, + /// `-=` MinusAssign, + /// `*=` MultiplyAssign, + /// `/=` DivideAssign, + /// `<<=` LeftShiftAssign, + /// `>>=` RightShiftAssign, + /// `&=` AndAssign, + /// `|=` OrAssign, + /// `^=` XOrAssign, + /// `%=` ModuloAssign, + /// `~=` PowerOfAssign, + /// `private` + /// + /// Never appears under the `no_function` feature. #[cfg(not(feature = "no_function"))] Private, + /// `import` + /// + /// Never appears under the `no_module` feature. #[cfg(not(feature = "no_module"))] Import, + /// `export` + /// + /// Never appears under the `no_module` feature. #[cfg(not(feature = "no_module"))] Export, + /// `as` + /// + /// Never appears under the `no_module` feature. #[cfg(not(feature = "no_module"))] As, + /// A lexer error. LexError(Box), + /// A comment block. Comment(String), + /// A reserved symbol. Reserved(String), + /// A custom keyword. Custom(String), + /// End of the input stream. EOF, } @@ -566,7 +658,7 @@ impl Token { } } - /// Is this token a reserved keyword? + /// Is this token a reserved symbol? pub fn is_reserved(&self) -> bool { match self { Self::Reserved(_) => true, @@ -590,6 +682,11 @@ impl From for String { } /// State of the tokenizer. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. #[derive(Debug, Clone, Eq, PartialEq, Default)] pub struct TokenizeState { /// Maximum length of a string (0 = unlimited). @@ -605,6 +702,11 @@ pub struct TokenizeState { } /// Trait that encapsulates a peekable character input stream. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This trait is volatile and may change. pub trait InputStream { /// Get the next character fn get_next(&mut self) -> Option; @@ -629,6 +731,11 @@ pub fn is_valid_identifier(name: impl Iterator) -> bool { } /// Parse a string literal wrapped by `enclosing_char`. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. pub fn parse_string_literal( stream: &mut impl InputStream, state: &mut TokenizeState, @@ -794,7 +901,12 @@ fn scan_comment( } } -/// Get the next token. +/// Get the next token from the `InputStream`. +/// Exported under the `internals` feature only. +/// +/// ## WARNING +/// +/// This type is volatile and may change. pub fn get_next_token( stream: &mut impl InputStream, state: &mut TokenizeState, diff --git a/src/utils.rs b/src/utils.rs index a6eff859..603f8b81 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -92,9 +92,12 @@ pub fn calc_fn_spec<'a>( s.finish() } -/// A type to hold a number of values in static storage for no-allocation, quick access. +/// An array-like type that holds a number of values in static storage for no-allocation, quick access. +/// Exported under the `internals` feature only. +/// /// If too many items are stored, it converts into using a `Vec`. /// +/// /// This is essentially a knock-off of the [`staticvec`](https://crates.io/crates/staticvec) crate. /// This simplified implementation here is to avoid pulling in another crate. /// @@ -130,6 +133,10 @@ pub fn calc_fn_spec<'a>( /// # Safety /// /// This type uses some unsafe code (mainly for uninitialized/unused array slots) for efficiency. +/// +/// ## WARNING +/// +/// This type is volatile and may change. // // TODO - remove unsafe code pub struct StaticVec { From c825de6f7717571105fa685ffcdddf1e00f70c14 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 16:05:08 +0800 Subject: [PATCH 7/8] Mark internal data structures with [INTERNALS]. --- src/engine.rs | 4 ++-- src/error.rs | 2 +- src/module.rs | 2 +- src/parser.rs | 12 ++++++------ src/token.rs | 10 +++++----- src/utils.rs | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index cd87cc1e..a852b3fa 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -38,7 +38,7 @@ pub type Array = Vec; #[cfg(not(feature = "no_object"))] pub type Map = HashMap; -/// A stack of imported modules. +/// [INTERNALS] A stack of imported modules. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -194,7 +194,7 @@ impl> From for Target<'_> { } } -/// A type that holds all the current states of the Engine. +/// [INTERNALS] A type that holds all the current states of the Engine. /// Exported under the `internals` feature only. /// /// # Safety diff --git a/src/error.rs b/src/error.rs index 736c9df8..b6901c68 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,7 +10,7 @@ use crate::stdlib::{ string::{String, ToString}, }; -/// Error encountered when tokenizing the script text. +/// [INTERNALS] Error encountered when tokenizing the script text. /// Exported under the `internals` feature only. /// /// ## WARNING diff --git a/src/module.rs b/src/module.rs index 2a590cb8..22632c7d 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1128,7 +1128,7 @@ impl Module { } } -/// A chain of module names to qualify a variable or function call. +/// [INTERNALS] A chain of module names to qualify a variable or function call. /// Exported under the `internals` feature only. /// /// A `u64` hash key is cached for quick search purposes. diff --git a/src/parser.rs b/src/parser.rs index 786f7d85..da0409db 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -342,7 +342,7 @@ impl fmt::Display for FnAccess { } } -/// A type containing information on a scripted function. +/// [INTERNALS] A type containing information on a scripted function. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -381,7 +381,7 @@ impl fmt::Display for ScriptFnDef { } } -/// A type encapsulating the mode of a `return`/`throw` statement. +/// [INTERNALS] A type encapsulating the mode of a `return`/`throw` statement. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -487,7 +487,7 @@ impl ParseSettings { } } -/// A Rhai statement. +/// [INTERNALS] A Rhai statement. /// Exported under the `internals` feature only. /// /// Each variant is at most one pointer in size (for speed), @@ -593,7 +593,7 @@ impl Stmt { } } -/// A type wrapping a custom syntax definition. +/// [INTERNALS] A type wrapping a custom syntax definition. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -614,7 +614,7 @@ impl Hash for CustomExpr { } } -/// A type wrapping a floating-point number. +/// [INTERNALS] A type wrapping a floating-point number. /// Exported under the `internals` feature only. /// /// This type is mainly used to provide a standard `Hash` implementation @@ -635,7 +635,7 @@ impl Hash for FloatWrapper { } } -/// An expression sub-tree. +/// [INTERNALS] An expression sub-tree. /// Exported under the `internals` feature only. /// /// Each variant is at most one pointer in size (for speed), diff --git a/src/token.rs b/src/token.rs index 82e850d5..36e51903 100644 --- a/src/token.rs +++ b/src/token.rs @@ -136,7 +136,7 @@ impl fmt::Debug for Position { } } -/// A language token. +/// [INTERNALS] A Rhai language token. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -681,7 +681,7 @@ impl From for String { } } -/// State of the tokenizer. +/// [INTERNALS] State of the tokenizer. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -701,7 +701,7 @@ pub struct TokenizeState { pub include_comments: bool, } -/// Trait that encapsulates a peekable character input stream. +/// [INTERNALS] Trait that encapsulates a peekable character input stream. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -730,7 +730,7 @@ pub fn is_valid_identifier(name: impl Iterator) -> bool { first_alphabetic } -/// Parse a string literal wrapped by `enclosing_char`. +/// [INTERNALS] Parse a string literal wrapped by `enclosing_char`. /// Exported under the `internals` feature only. /// /// ## WARNING @@ -901,7 +901,7 @@ fn scan_comment( } } -/// Get the next token from the `InputStream`. +/// [INTERNALS] Get the next token from the `InputStream`. /// Exported under the `internals` feature only. /// /// ## WARNING diff --git a/src/utils.rs b/src/utils.rs index 603f8b81..760c809e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -92,7 +92,7 @@ pub fn calc_fn_spec<'a>( s.finish() } -/// An array-like type that holds a number of values in static storage for no-allocation, quick access. +/// [INTERNALS] An array-like type that holds a number of values in static storage for no-allocation, quick access. /// Exported under the `internals` feature only. /// /// If too many items are stored, it converts into using a `Vec`. From 9d900a672231d952202207d0c727af2e93b3c772 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 16:09:13 +0800 Subject: [PATCH 8/8] Remove _Private. --- src/any.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/any.rs b/src/any.rs index 202afa24..1d478e62 100644 --- a/src/any.rs +++ b/src/any.rs @@ -34,9 +34,9 @@ mod private { use crate::fn_native::SendSync; use crate::stdlib::any::Any; - /// A sealed trait that prevents other crates from implementing [Variant]. + /// A sealed trait that prevents other crates from implementing [`Variant`]. /// - /// [Variant]: super::Variant + /// [`Variant`]: super::Variant pub trait Sealed {} impl Sealed for T {} @@ -810,8 +810,3 @@ impl From> for Dynamic { Self(Union::FnPtr(value)) } } - -/// Private type which ensures that `rhai::Any` and `rhai::AnyExt` can only -/// be implemented by this crate. -#[doc(hidden)] -pub struct _Private;