From 398edf66b3f8e86c154fb8b45dcb943f11fedd39 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 13 Jul 2020 13:43:28 +0800 Subject: [PATCH 01/20] Delete benchmark.yml --- .github/workflows/benchmark.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .github/workflows/benchmark.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml deleted file mode 100644 index df310705..00000000 --- a/.github/workflows/benchmark.yml +++ /dev/null @@ -1,29 +0,0 @@ -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 96aa5ed39e88bb5a79bdc1181212f3b8ca670bdc Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Fri, 24 Jul 2020 16:20:47 +0200 Subject: [PATCH 02/20] set_indexer_set_fn to support setting generic value --- src/module.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/module.rs b/src/module.rs index 7216c248..d4cec91e 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, From 2b0aacde23780e7399fcb53a6b712074203be67a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 24 Jul 2020 23:16:54 +0800 Subject: [PATCH 03/20] 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 ea22591e365a55d40b00b0ccee24f029f4ef732d Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Fri, 24 Jul 2020 19:08:59 +0200 Subject: [PATCH 04/20] Support u128/i128 types during serialization --- src/serde/de.rs | 24 ++++++++++++++++++++++++ src/serde/ser.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/serde/de.rs b/src/serde/de.rs index 88533718..4ab9919a 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -162,10 +162,12 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { Union::Variant(value) if value.is::() => self.deserialize_i16(visitor), Union::Variant(value) if value.is::() => self.deserialize_i32(visitor), Union::Variant(value) if value.is::() => self.deserialize_i64(visitor), + Union::Variant(value) if value.is::() => self.deserialize_i128(visitor), Union::Variant(value) if value.is::() => self.deserialize_u8(visitor), Union::Variant(value) if value.is::() => self.deserialize_u16(visitor), Union::Variant(value) if value.is::() => self.deserialize_u32(visitor), Union::Variant(value) if value.is::() => self.deserialize_u64(visitor), + Union::Variant(value) if value.is::() => self.deserialize_u128(visitor), Union::Variant(_) => self.type_error(), } @@ -219,6 +221,18 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { } } + fn deserialize_i128>(self, visitor: V) -> Result> { + if let Ok(v) = self.value.as_int() { + self.deserialize_int(v, visitor) + } else if cfg!(not(feature = "only_i32")) { + self.type_error() + } else { + self.value + .downcast_ref::() + .map_or_else(|| self.type_error(), |&x| visitor.visit_i128(x)) + } + } + fn deserialize_u8>(self, visitor: V) -> Result> { if let Ok(v) = self.value.as_int() { self.deserialize_int(v, visitor) @@ -259,6 +273,16 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { } } + fn deserialize_u128>(self, visitor: V) -> Result> { + if let Ok(v) = self.value.as_int() { + self.deserialize_int(v, visitor) + } else { + self.value + .downcast_ref::() + .map_or_else(|| self.type_error(), |&x| visitor.visit_u128(x)) + } + } + fn deserialize_f32>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_float"))] return self diff --git a/src/serde/ser.rs b/src/serde/ser.rs index 181573b0..7c3f9321 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -150,6 +150,21 @@ impl Serializer for &mut DynamicSerializer { } } + fn serialize_i128(self, v: i128) -> Result> { + #[cfg(not(feature = "only_i32"))] + if v > i64::MAX as i128 { + return Ok(Dynamic::from(v)); + } else { + return self.serialize_i64(v as i64); + } + #[cfg(feature = "only_i32")] + if v > i32::MAX as i128 { + return Ok(Dynamic::from(v)); + } else { + return self.serialize_i32(v as i32); + } + } + fn serialize_u8(self, v: u8) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -190,6 +205,21 @@ impl Serializer for &mut DynamicSerializer { } } + fn serialize_u128(self, v: u128) -> Result> { + #[cfg(not(feature = "only_i32"))] + if v > i64::MAX as u128 { + return Ok(Dynamic::from(v)); + } else { + return self.serialize_i64(v as i64); + } + #[cfg(feature = "only_i32")] + if v > i32::MAX as u128 { + return Ok(Dynamic::from(v)); + } else { + return self.serialize_i32(v as i32); + } + } + fn serialize_f32(self, v: f32) -> Result> { Ok(Dynamic::from(v)) } From 554ee07e01b85fda6c143fb3439cbb9b49d8a592 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 09:47:50 +0800 Subject: [PATCH 05/20] 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 06/20] 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 1bd7a9d079ea4065c17c1a72b940e54977e61a8e Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Sat, 25 Jul 2020 06:54:28 +0200 Subject: [PATCH 07/20] Rename LICENSE.txt -> LICENSE-APACHE.txt --- LICENSE.txt => LICENSE-APACHE.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE.txt => LICENSE-APACHE.txt (100%) diff --git a/LICENSE.txt b/LICENSE-APACHE.txt similarity index 100% rename from LICENSE.txt rename to LICENSE-APACHE.txt From 11cef56f89357eb2bded18d04a32a5bda0de0d87 Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Sat, 25 Jul 2020 06:54:50 +0200 Subject: [PATCH 08/20] Remove appendix from LICENSE-APACHE.txt --- LICENSE-APACHE.txt | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/LICENSE-APACHE.txt b/LICENSE-APACHE.txt index 261eeb9e..d9a10c0d 100644 --- a/LICENSE-APACHE.txt +++ b/LICENSE-APACHE.txt @@ -174,28 +174,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From ec0aa891d70714498e4ef00adb243471884d473c Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Sat, 25 Jul 2020 06:57:41 +0200 Subject: [PATCH 09/20] Add LICENSE-MIT.txt (based on Syn) --- LICENSE-MIT.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 LICENSE-MIT.txt diff --git a/LICENSE-MIT.txt b/LICENSE-MIT.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/LICENSE-MIT.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From c14f36e2d509148757be0aaf7af6c25409875a6b Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Sat, 25 Jul 2020 07:02:51 +0200 Subject: [PATCH 10/20] README.md: Add License section (based on Syn) --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 1f9f5bf8..b40d97a8 100644 --- a/README.md +++ b/README.md @@ -64,3 +64,13 @@ Playground An [Online Playground](https://alvinhochun.github.io/rhai-demo/) is available with syntax-highlighting editor. Scripts can be evaluated directly from the editor. + +License +------- + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + +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. From b4b7abdcb0cbdebf86029618bc073f997f03f3c8 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 14:06:04 +0800 Subject: [PATCH 11/20] 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 12/20] 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 d920613d57cc83e4b58107c0fe95f442fb7a8a88 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Fri, 24 Jul 2020 19:10:07 +0200 Subject: [PATCH 13/20] Avoid shadowing call errors in get_indexed_mut --- src/engine.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index cb7234d3..daa24844 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1052,17 +1052,20 @@ impl Engine { #[cfg(not(feature = "no_index"))] _ => { - let type_name = self.map_type_name(val.type_name()); + let val_type_name = val.type_name(); let args = &mut [val, &mut idx]; self.exec_fn_call( 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(|e| match *e { + EvalAltResult::ErrorFunctionNotFound(..) => { + Box::new(EvalAltResult::ErrorIndexingType( + self.map_type_name(val_type_name).into(), + Position::none(), + )) + } + _ => e, }) } From e7aaec8e3a686364a00045bd0c53661c37871050 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sat, 25 Jul 2020 09:14:29 +0200 Subject: [PATCH 14/20] Seal Variant trait to prevent downstream implementations --- src/any.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/any.rs b/src/any.rs index 7f637187..202afa24 100644 --- a/src/any.rs +++ b/src/any.rs @@ -30,12 +30,24 @@ use crate::stdlib::time::Instant; #[cfg(target_arch = "wasm32")] use instant::Instant; +mod private { + use crate::fn_native::SendSync; + use crate::stdlib::any::Any; + + /// A sealed trait that prevents other crates from implementing [Variant]. + /// + /// [Variant]: super::Variant + pub trait Sealed {} + + impl Sealed for T {} +} + /// Trait to represent any type. /// /// Currently, `Variant` is not `Send` nor `Sync`, so it can practically be any type. /// Turn on the `sync` feature to restrict it to only types that implement `Send + Sync`. #[cfg(not(feature = "sync"))] -pub trait Variant: Any { +pub trait Variant: Any + private::Sealed { /// Convert this `Variant` trait object to `&dyn Any`. fn as_any(&self) -> &dyn Any; @@ -53,10 +65,6 @@ pub trait Variant: Any { /// Clone into `Dynamic`. fn clone_into_dynamic(&self) -> Dynamic; - - /// This trait may only be implemented by `rhai`. - #[doc(hidden)] - fn _closed(&self) -> _Private; } /// Trait to represent any type. @@ -64,7 +72,7 @@ pub trait Variant: Any { /// `From<_>` is implemented for `i64` (`i32` if `only_i32`), `f64` (if not `no_float`), /// `bool`, `String`, `char`, `Vec` (into `Array`) and `HashMap` (into `Map`). #[cfg(feature = "sync")] -pub trait Variant: Any + Send + Sync { +pub trait Variant: Any + Send + Sync + private::Sealed { /// Convert this `Variant` trait object to `&dyn Any`. fn as_any(&self) -> &dyn Any; @@ -82,10 +90,6 @@ pub trait Variant: Any + Send + Sync { /// Clone into `Dynamic`. fn clone_into_dynamic(&self) -> Dynamic; - - /// This trait may only be implemented by `rhai`. - #[doc(hidden)] - fn _closed(&self) -> _Private; } impl Variant for T { @@ -107,9 +111,6 @@ impl Variant for T { fn clone_into_dynamic(&self) -> Dynamic { Dynamic::from(self.clone()) } - fn _closed(&self) -> _Private { - _Private - } } impl dyn Variant { From 261273bac3138b3ce84a478df834dc264d43d316 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sat, 25 Jul 2020 09:14:39 +0200 Subject: [PATCH 15/20] Unbreak no_std --- src/fn_native.rs | 1 + src/parser.rs | 2 +- src/syntax.rs | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fn_native.rs b/src/fn_native.rs index f4de5982..a113db4b 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -5,6 +5,7 @@ use crate::engine::Engine; use crate::module::{FuncReturn, Module}; use crate::parser::ScriptFnDef; use crate::result::EvalAltResult; +use crate::stdlib::vec::Vec; use crate::token::{is_valid_identifier, Position}; use crate::utils::{ImmutableString, StaticVec}; use crate::Scope; diff --git a/src/parser.rs b/src/parser.rs index b6a3fa08..643c7aa9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -592,7 +592,7 @@ 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); } } 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, From be86927bc5b566e07e01dab851958c75e8b21caf Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sat, 25 Jul 2020 09:19:21 +0200 Subject: [PATCH 16/20] Use bash syntax to check value of TRAVIS_RUST_VERSION --- .ci/build.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 20c75afa..fb0e7e04 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -5,9 +5,7 @@ set -ex cargo build --verbose cargo test --verbose -if [ "$TRAVIS_RUST_VERSION" = "nightly" ] -then +if [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo build --verbose --features no_std cargo test --verbose --features no_std fi - From 284e58e8a1e1ad35b5887046761b86c4808f63cf Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 15:52:27 +0800 Subject: [PATCH 17/20] 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 1aab77df1cc924a13f9e6a0c9054a04903550912 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sat, 25 Jul 2020 08:32:43 +0200 Subject: [PATCH 18/20] Avoid scanning over slices to validate numerical literals --- src/token.rs | 43 ++++++++++++++++++++++++++++------------ tests/number_literals.rs | 3 +++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/token.rs b/src/token.rs index f2719a7a..1248d742 100644 --- a/src/token.rs +++ b/src/token.rs @@ -810,6 +810,32 @@ pub fn get_next_token( result } +/// Test if the given character is a hex character. +fn is_hex_char(c: char) -> bool { + match c { + 'a'..='f' => true, + 'A'..='F' => true, + '0'..='9' => true, + _ => false, + } +} + +/// Test if the given character is an octal character. +fn is_octal_char(c: char) -> bool { + match c { + '0'..='7' => true, + _ => false, + } +} + +/// Test if the given character is a binary character. +fn is_binary_char(c: char) -> bool { + match c { + '0' | '1' => true, + _ => false, + } +} + /// Get the next token. fn get_next_token_inner( stream: &mut impl InputStream, @@ -872,18 +898,9 @@ fn get_next_token_inner( eat_next(stream, pos); let valid = match ch { - 'x' | 'X' => [ - 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', - ], - 'o' | 'O' => [ - '0', '1', '2', '3', '4', '5', '6', '7', '_', '_', '_', '_', - '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', - ], - 'b' | 'B' => [ - '0', '1', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', - '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', - ], + 'x' | 'X' => is_hex_char, + 'o' | 'O' => is_octal_char, + 'b' | 'B' => is_binary_char, _ => unreachable!(), }; @@ -895,7 +912,7 @@ fn get_next_token_inner( }); while let Some(next_char_in_escape_seq) = stream.peek_next() { - if !valid.contains(&next_char_in_escape_seq) { + if !valid(next_char_in_escape_seq) { break; } diff --git a/tests/number_literals.rs b/tests/number_literals.rs index 699de19a..ce19b52d 100644 --- a/tests/number_literals.rs +++ b/tests/number_literals.rs @@ -14,6 +14,7 @@ fn test_hex_literal() -> Result<(), Box> { let engine = Engine::new(); assert_eq!(engine.eval::("let x = 0xf; x")?, 15); + assert_eq!(engine.eval::("let x = 0Xf; x")?, 15); assert_eq!(engine.eval::("let x = 0xff; x")?, 255); Ok(()) @@ -24,6 +25,7 @@ fn test_octal_literal() -> Result<(), Box> { let engine = Engine::new(); assert_eq!(engine.eval::("let x = 0o77; x")?, 63); + assert_eq!(engine.eval::("let x = 0O77; x")?, 63); assert_eq!(engine.eval::("let x = 0o1234; x")?, 668); Ok(()) @@ -34,6 +36,7 @@ fn test_binary_literal() -> Result<(), Box> { let engine = Engine::new(); assert_eq!(engine.eval::("let x = 0b1111; x")?, 15); + assert_eq!(engine.eval::("let x = 0B1111; x")?, 15); assert_eq!( engine.eval::("let x = 0b0011_1100_1010_0101; x")?, 15525 From c825de6f7717571105fa685ffcdddf1e00f70c14 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 25 Jul 2020 16:05:08 +0800 Subject: [PATCH 19/20] 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 20/20] 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;