Move all functions metadata into metadata feature.
This commit is contained in:
parent
c4fe1782df
commit
ac7f35cacb
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
|||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
flags:
|
flags:
|
||||||
- ""
|
- ""
|
||||||
- "--features metadata,internals"
|
- "--features metadata,serde,internals"
|
||||||
- "--features unchecked"
|
- "--features unchecked"
|
||||||
- "--features sync"
|
- "--features sync"
|
||||||
- "--features no_optimize"
|
- "--features no_optimize"
|
||||||
@ -34,7 +34,7 @@ jobs:
|
|||||||
- "--features no_module"
|
- "--features no_module"
|
||||||
- "--features no_closure"
|
- "--features no_closure"
|
||||||
- "--features unicode-xid-ident"
|
- "--features unicode-xid-ident"
|
||||||
- "--features sync,no_function,no_float,no_optimize,no_module,no_closure,metadata,unchecked"
|
- "--features sync,no_function,no_float,no_optimize,no_module,no_closure,metadata,serde,unchecked"
|
||||||
toolchain: [stable]
|
toolchain: [stable]
|
||||||
experimental: [false]
|
experimental: [false]
|
||||||
include:
|
include:
|
||||||
|
@ -27,6 +27,7 @@ Breaking changes
|
|||||||
* `Array::reduce` and `Array::reduce_rev` now take a `Dynamic` as initial value instead of a function pointer.
|
* `Array::reduce` and `Array::reduce_rev` now take a `Dynamic` as initial value instead of a function pointer.
|
||||||
* `protected`, `super` are now reserved keywords.
|
* `protected`, `super` are now reserved keywords.
|
||||||
* The `Module::set_fn_XXX` API now take `&str` as the function name instead of `Into<String>`.
|
* The `Module::set_fn_XXX` API now take `&str` as the function name instead of `Into<String>`.
|
||||||
|
* The _reflections_ API such as `Engine::gen_fn_signatures`, `Module::update_fn_metadata` etc. are put under the `metadata` feature gate.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
@ -38,7 +38,7 @@ no_closure = [] # no automatic sharing and capture of anonymous
|
|||||||
no_module = [] # no modules
|
no_module = [] # no modules
|
||||||
internals = [] # expose internal data structures
|
internals = [] # expose internal data structures
|
||||||
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
||||||
metadata = ["serde", "serde_json"] # enables exporting functions metadata to JSON
|
metadata = ["serde_json"] # enable exporting functions metadata
|
||||||
|
|
||||||
no_std = ["smallvec/union", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"]
|
no_std = ["smallvec/union", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"]
|
||||||
|
|
||||||
@ -92,4 +92,4 @@ instant = { version = "0.1" } # WASM implementation of std::time::Instant
|
|||||||
instant = { version = "0.1" } # WASM implementation of std::time::Instant
|
instant = { version = "0.1" } # WASM implementation of std::time::Instant
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["metadata", "internals", "decimal"] # compiling for no-std
|
features = ["metadata", "serde", "internals", "decimal"] # compiling for no-std
|
||||||
|
13
src/ast.rs
13
src/ast.rs
@ -84,6 +84,7 @@ impl fmt::Display for ScriptFnDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A type containing the metadata of a script-defined function.
|
/// A type containing the metadata of a script-defined function.
|
||||||
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// Created by [`AST::iter_functions`].
|
/// Created by [`AST::iter_functions`].
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -260,6 +261,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions.
|
/// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
/// Not available under `no_function`.
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated = "this method is volatile and may change"]
|
#[deprecated = "this method is volatile and may change"]
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -276,6 +278,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
|
/// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
/// Not available under `no_function`.
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated = "this method is volatile and may change"]
|
#[deprecated = "this method is volatile and may change"]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -311,10 +314,9 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// Clone the [`AST`]'s functions into a new [`AST`].
|
/// Clone the [`AST`]'s functions into a new [`AST`].
|
||||||
/// No statements are cloned.
|
/// No statements are cloned.
|
||||||
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// This operation is cheap because functions are shared.
|
/// This operation is cheap because functions are shared.
|
||||||
///
|
|
||||||
/// Not available under `no_function`.
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn clone_functions_only(&self) -> Self {
|
pub fn clone_functions_only(&self) -> Self {
|
||||||
@ -322,10 +324,9 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
|
/// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
|
||||||
/// No statements are cloned.
|
/// No statements are cloned.
|
||||||
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// This operation is cheap because functions are shared.
|
/// This operation is cheap because functions are shared.
|
||||||
///
|
|
||||||
/// Not available under `no_function`.
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn clone_functions_only_filtered(
|
pub fn clone_functions_only_filtered(
|
||||||
@ -354,8 +355,8 @@ impl AST {
|
|||||||
resolver: self.resolver.clone(),
|
resolver: self.resolver.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Merge two [`AST`] into one. Both [`AST`]'s are untouched and a new, merged, version
|
/// Merge two [`AST`] into one. Both [`AST`]'s are untouched and a new, merged,
|
||||||
/// is returned.
|
/// version is returned.
|
||||||
///
|
///
|
||||||
/// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
|
/// Statements in the second [`AST`] are simply appended to the end of the first _without any processing_.
|
||||||
/// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
|
/// Thus, the return value of the first [`AST`] (if using expression-statement syntax) is buried.
|
||||||
|
@ -45,6 +45,7 @@ fn print_help() {
|
|||||||
println!("help => print this help");
|
println!("help => print this help");
|
||||||
println!("quit, exit => quit");
|
println!("quit, exit => quit");
|
||||||
println!("scope => print all variables in the scope");
|
println!("scope => print all variables in the scope");
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
println!("functions => print all functions defined");
|
println!("functions => print all functions defined");
|
||||||
println!("ast => print the last AST (optimized)");
|
println!("ast => print the last AST (optimized)");
|
||||||
println!("astu => print the last raw, un-optimized AST");
|
println!("astu => print the last raw, un-optimized AST");
|
||||||
@ -202,6 +203,7 @@ fn main() {
|
|||||||
println!("{:#?}\n", ast);
|
println!("{:#?}\n", ast);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
"functions" => {
|
"functions" => {
|
||||||
// print a list of all registered functions
|
// print a list of all registered functions
|
||||||
engine
|
engine
|
||||||
|
@ -9,12 +9,11 @@ use crate::stdlib::{
|
|||||||
any::{type_name, TypeId},
|
any::{type_name, TypeId},
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
format,
|
format,
|
||||||
string::{String, ToString},
|
string::String,
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
||||||
NativeCallContext, ParseError, Position, RhaiResult, Shared, StaticVec, AST,
|
NativeCallContext, ParseError, Position, RhaiResult, Shared, AST,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -52,30 +51,36 @@ impl Engine {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn register_fn<A, F>(
|
pub fn register_fn<N, A, F>(&mut self, name: N, func: F) -> &mut Self
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str> + Into<ImmutableString>,
|
|
||||||
func: F,
|
|
||||||
) -> &mut Self
|
|
||||||
where
|
where
|
||||||
|
N: AsRef<str> + Into<ImmutableString>,
|
||||||
F: RegisterNativeFunction<A, ()>,
|
F: RegisterNativeFunction<A, ()>,
|
||||||
{
|
{
|
||||||
let param_types = F::param_types();
|
let param_types = F::param_types();
|
||||||
let mut param_type_names: StaticVec<_> = F::param_names()
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
let mut param_type_names: crate::StaticVec<_> = F::param_names()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| format!("_: {}", self.map_type_name(ty)))
|
.map(|ty| format!("_: {}", self.map_type_name(ty)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
if F::return_type() != TypeId::of::<()>() {
|
if F::return_type() != TypeId::of::<()>() {
|
||||||
param_type_names.push(self.map_type_name(F::return_type_name()).to_string());
|
param_type_names.push(self.map_type_name(F::return_type_name()).into());
|
||||||
}
|
}
|
||||||
let param_type_names: StaticVec<_> =
|
|
||||||
param_type_names.iter().map(|ty| ty.as_str()).collect();
|
#[cfg(feature = "metadata")]
|
||||||
|
let param_type_names: Option<crate::StaticVec<_>> =
|
||||||
|
Some(param_type_names.iter().map(|ty| ty.as_str()).collect());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "metadata"))]
|
||||||
|
let param_type_names: Option<[&str; 0]> = None;
|
||||||
|
|
||||||
self.global_namespace.set_fn(
|
self.global_namespace.set_fn(
|
||||||
name,
|
name,
|
||||||
FnNamespace::Global,
|
FnNamespace::Global,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
Some(¶m_type_names),
|
param_type_names.as_ref().map(|v| v.as_ref()),
|
||||||
¶m_types,
|
¶m_types,
|
||||||
func.into_callable_function(),
|
func.into_callable_function(),
|
||||||
);
|
);
|
||||||
@ -106,28 +111,34 @@ impl Engine {
|
|||||||
/// .expect_err("expecting division by zero error!");
|
/// .expect_err("expecting division by zero error!");
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn register_result_fn<A, F, R>(
|
pub fn register_result_fn<N, A, F, R>(&mut self, name: N, func: F) -> &mut Self
|
||||||
&mut self,
|
|
||||||
name: impl AsRef<str> + Into<ImmutableString>,
|
|
||||||
func: F,
|
|
||||||
) -> &mut Self
|
|
||||||
where
|
where
|
||||||
|
N: AsRef<str> + Into<ImmutableString>,
|
||||||
F: RegisterNativeFunction<A, Result<R, Box<EvalAltResult>>>,
|
F: RegisterNativeFunction<A, Result<R, Box<EvalAltResult>>>,
|
||||||
{
|
{
|
||||||
let param_types = F::param_types();
|
let param_types = F::param_types();
|
||||||
let mut param_type_names: StaticVec<_> = F::param_names()
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
let param_type_names: crate::StaticVec<_> = F::param_names()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| format!("_: {}", self.map_type_name(ty)))
|
.map(|ty| format!("_: {}", self.map_type_name(ty)))
|
||||||
|
.chain(crate::stdlib::iter::once(
|
||||||
|
self.map_type_name(F::return_type_name()).into(),
|
||||||
|
))
|
||||||
.collect();
|
.collect();
|
||||||
param_type_names.push(self.map_type_name(F::return_type_name()).to_string());
|
|
||||||
let param_type_names: StaticVec<&str> =
|
#[cfg(feature = "metadata")]
|
||||||
param_type_names.iter().map(|ty| ty.as_str()).collect();
|
let param_type_names: Option<crate::StaticVec<_>> =
|
||||||
|
Some(param_type_names.iter().map(|ty| ty.as_str()).collect());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "metadata"))]
|
||||||
|
let param_type_names: Option<[&str; 0]> = None;
|
||||||
|
|
||||||
self.global_namespace.set_fn(
|
self.global_namespace.set_fn(
|
||||||
name,
|
name,
|
||||||
FnNamespace::Global,
|
FnNamespace::Global,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
Some(¶m_type_names),
|
param_type_names.as_ref().map(|v| v.as_ref()),
|
||||||
¶m_types,
|
¶m_types,
|
||||||
func.into_callable_function(),
|
func.into_callable_function(),
|
||||||
);
|
);
|
||||||
@ -150,14 +161,18 @@ impl Engine {
|
|||||||
/// To access the first mutable parameter, use `args.get_mut(0).unwrap()`
|
/// To access the first mutable parameter, use `args.get_mut(0).unwrap()`
|
||||||
#[deprecated = "this function is volatile and may change"]
|
#[deprecated = "this function is volatile and may change"]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn register_raw_fn<T: Variant + Clone>(
|
pub fn register_raw_fn<N, T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl AsRef<str> + Into<ImmutableString>,
|
name: N,
|
||||||
arg_types: &[TypeId],
|
arg_types: &[TypeId],
|
||||||
func: impl Fn(NativeCallContext, &mut FnCallArgs) -> Result<T, Box<EvalAltResult>>
|
func: impl Fn(NativeCallContext, &mut FnCallArgs) -> Result<T, Box<EvalAltResult>>
|
||||||
+ SendSync
|
+ SendSync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self
|
||||||
|
where
|
||||||
|
N: AsRef<str> + Into<ImmutableString>,
|
||||||
|
T: Variant + Clone,
|
||||||
|
{
|
||||||
self.global_namespace.set_raw_fn(
|
self.global_namespace.set_raw_fn(
|
||||||
name,
|
name,
|
||||||
FnNamespace::Global,
|
FnNamespace::Global,
|
||||||
@ -1958,13 +1973,15 @@ impl Engine {
|
|||||||
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
|
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
|
||||||
}
|
}
|
||||||
/// Generate a list of all registered functions.
|
/// Generate a list of all registered functions.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
///
|
///
|
||||||
/// Functions from the following sources are included, in order:
|
/// Functions from the following sources are included, in order:
|
||||||
/// 1) Functions registered into the global namespace
|
/// 1) Functions registered into the global namespace
|
||||||
/// 2) Functions in registered sub-modules
|
/// 2) Functions in registered sub-modules
|
||||||
/// 3) Functions in packages (optional)
|
/// 3) Functions in packages (optional)
|
||||||
pub fn gen_fn_signatures(&self, include_packages: bool) -> Vec<String> {
|
#[cfg(feature = "metadata")]
|
||||||
let mut signatures: Vec<_> = Default::default();
|
pub fn gen_fn_signatures(&self, include_packages: bool) -> crate::stdlib::vec::Vec<String> {
|
||||||
|
let mut signatures: crate::stdlib::vec::Vec<_> = Default::default();
|
||||||
|
|
||||||
signatures.extend(self.global_namespace.gen_fn_signatures());
|
signatures.extend(self.global_namespace.gen_fn_signatures());
|
||||||
|
|
||||||
|
@ -5,13 +5,7 @@
|
|||||||
use crate::dynamic::{DynamicWriteLock, Variant};
|
use crate::dynamic::{DynamicWriteLock, Variant};
|
||||||
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
||||||
use crate::r#unsafe::unsafe_try_cast;
|
use crate::r#unsafe::unsafe_try_cast;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String, vec};
|
||||||
any::{type_name, TypeId},
|
|
||||||
boxed::Box,
|
|
||||||
mem,
|
|
||||||
string::String,
|
|
||||||
vec,
|
|
||||||
};
|
|
||||||
use crate::{Dynamic, EvalAltResult, NativeCallContext};
|
use crate::{Dynamic, EvalAltResult, NativeCallContext};
|
||||||
|
|
||||||
// These types are used to build a unique _marker_ tuple type for each combination
|
// These types are used to build a unique _marker_ tuple type for each combination
|
||||||
@ -66,10 +60,16 @@ pub trait RegisterNativeFunction<Args, Result> {
|
|||||||
/// Get the type ID's of this function's parameters.
|
/// Get the type ID's of this function's parameters.
|
||||||
fn param_types() -> Box<[TypeId]>;
|
fn param_types() -> Box<[TypeId]>;
|
||||||
/// Get the type names of this function's parameters.
|
/// Get the type names of this function's parameters.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
fn param_names() -> Box<[&'static str]>;
|
fn param_names() -> Box<[&'static str]>;
|
||||||
/// Get the type ID of this function's return value.
|
/// Get the type ID of this function's return value.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
fn return_type() -> TypeId;
|
fn return_type() -> TypeId;
|
||||||
/// Get the type name of this function's return value.
|
/// Get the type name of this function's return value.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
fn return_type_name() -> &'static str;
|
fn return_type_name() -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,9 +91,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<($($mark,)*), ()> for FN {
|
> RegisterNativeFunction<($($mark,)*), ()> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
||||||
#[inline(always)] fn return_type_name() -> &'static str { type_name::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -115,9 +115,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
|
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
||||||
#[inline(always)] fn return_type_name() -> &'static str { type_name::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -139,9 +139,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn return_type_name() -> &'static str { type_name::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -160,9 +160,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn return_type_name() -> &'static str { type_name::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
|
@ -12,7 +12,7 @@ use crate::stdlib::{
|
|||||||
iter::empty,
|
iter::empty,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
ops::{Add, AddAssign, Deref, DerefMut},
|
ops::{Add, AddAssign, Deref, DerefMut},
|
||||||
string::{String, ToString},
|
string::String,
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
@ -61,21 +61,21 @@ pub struct FuncInfo {
|
|||||||
/// Parameter types (if applicable).
|
/// Parameter types (if applicable).
|
||||||
pub param_types: StaticVec<TypeId>,
|
pub param_types: StaticVec<TypeId>,
|
||||||
/// Parameter names (if available).
|
/// Parameter names (if available).
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
pub param_names: StaticVec<ImmutableString>,
|
pub param_names: StaticVec<ImmutableString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FuncInfo {
|
impl FuncInfo {
|
||||||
/// Generate a signature of the function.
|
/// Generate a signature of the function.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
pub fn gen_signature(&self) -> String {
|
pub fn gen_signature(&self) -> String {
|
||||||
let mut sig = format!("{}(", self.name);
|
let mut sig = format!("{}(", self.name);
|
||||||
|
|
||||||
if !self.param_names.is_empty() {
|
if !self.param_names.is_empty() {
|
||||||
let mut params: Vec<_> = self
|
let mut params: crate::stdlib::vec::Vec<String> =
|
||||||
.param_names
|
self.param_names.iter().map(|s| s.as_str().into()).collect();
|
||||||
.iter()
|
let return_type = params.pop().unwrap_or_else(|| "()".into());
|
||||||
.map(ImmutableString::to_string)
|
|
||||||
.collect();
|
|
||||||
let return_type = params.pop().unwrap_or_else(|| "()".to_string());
|
|
||||||
sig.push_str(¶ms.join(", "));
|
sig.push_str(¶ms.join(", "));
|
||||||
if return_type != "()" {
|
if return_type != "()" {
|
||||||
sig.push_str(") -> ");
|
sig.push_str(") -> ");
|
||||||
@ -190,7 +190,7 @@ impl fmt::Debug for Module {
|
|||||||
.join(", ")
|
.join(", ")
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
Default::default()
|
||||||
},
|
},
|
||||||
if !self.variables.is_empty() {
|
if !self.variables.is_empty() {
|
||||||
format!(
|
format!(
|
||||||
@ -202,19 +202,19 @@ impl fmt::Debug for Module {
|
|||||||
.join(", ")
|
.join(", ")
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
Default::default()
|
||||||
},
|
},
|
||||||
if !self.functions.is_empty() {
|
if !self.functions.is_empty() {
|
||||||
format!(
|
format!(
|
||||||
" functions: {}\n",
|
" functions: {}\n",
|
||||||
self.functions
|
self.functions
|
||||||
.values()
|
.values()
|
||||||
.map(|f| f.func.to_string())
|
.map(|f| crate::stdlib::string::ToString::to_string(&f.func))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
Default::default()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -363,6 +363,8 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate signatures for all the non-private functions in the [`Module`].
|
/// Generate signatures for all the non-private functions in the [`Module`].
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn gen_fn_signatures(&self) -> impl Iterator<Item = String> + '_ {
|
pub fn gen_fn_signatures(&self) -> impl Iterator<Item = String> + '_ {
|
||||||
self.functions
|
self.functions
|
||||||
@ -479,6 +481,7 @@ impl Module {
|
|||||||
access: fn_def.access,
|
access: fn_def.access,
|
||||||
params: num_params,
|
params: num_params,
|
||||||
param_types: Default::default(),
|
param_types: Default::default(),
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
param_names,
|
param_names,
|
||||||
func: fn_def.into(),
|
func: fn_def.into(),
|
||||||
}),
|
}),
|
||||||
@ -602,6 +605,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update the metadata (parameter names/types and return type) of a registered function.
|
/// Update the metadata (parameter names/types and return type) of a registered function.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
///
|
///
|
||||||
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
||||||
///
|
///
|
||||||
@ -613,6 +617,7 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// The _last entry_ in the list should be the _return type_ of the function.
|
/// The _last entry_ in the list should be the _return type_ of the function.
|
||||||
/// In other words, the number of entries should be one larger than the number of parameters.
|
/// In other words, the number of entries should be one larger than the number of parameters.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
||||||
let param_names = arg_names
|
let param_names = arg_names
|
||||||
@ -652,7 +657,7 @@ impl Module {
|
|||||||
name: impl AsRef<str> + Into<ImmutableString>,
|
name: impl AsRef<str> + Into<ImmutableString>,
|
||||||
namespace: FnNamespace,
|
namespace: FnNamespace,
|
||||||
access: FnAccess,
|
access: FnAccess,
|
||||||
arg_names: Option<&[&str]>,
|
_arg_names: Option<&[&str]>,
|
||||||
arg_types: &[TypeId],
|
arg_types: &[TypeId],
|
||||||
func: CallableFunction,
|
func: CallableFunction,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
@ -683,7 +688,9 @@ impl Module {
|
|||||||
let hash_fn = calc_native_fn_hash(empty(), &name, ¶m_types);
|
let hash_fn = calc_native_fn_hash(empty(), &name, ¶m_types);
|
||||||
|
|
||||||
let name = self.interned_strings.get(name);
|
let name = self.interned_strings.get(name);
|
||||||
let param_names = arg_names
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
let param_names = _arg_names
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|p| p.iter())
|
.flat_map(|p| p.iter())
|
||||||
.map(|&arg| self.interned_strings.get(arg))
|
.map(|&arg| self.interned_strings.get(arg))
|
||||||
@ -697,6 +704,7 @@ impl Module {
|
|||||||
access,
|
access,
|
||||||
params: param_types.len(),
|
params: param_types.len(),
|
||||||
param_types,
|
param_types,
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
param_names,
|
param_names,
|
||||||
func: func.into(),
|
func: func.into(),
|
||||||
}),
|
}),
|
||||||
|
@ -142,8 +142,10 @@ macro_rules! reg_range {
|
|||||||
($lib:ident | $x:expr => $( $y:ty ),*) => {
|
($lib:ident | $x:expr => $( $y:ty ),*) => {
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<Range<$y>>();
|
$lib.set_iterator::<Range<$y>>();
|
||||||
let hash = $lib.set_native_fn($x, get_range::<$y>);
|
let _hash = $lib.set_native_fn($x, get_range::<$y>);
|
||||||
$lib.update_fn_metadata(hash, &[
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
$lib.update_fn_metadata(_hash, &[
|
||||||
concat!("from: ", stringify!($y)),
|
concat!("from: ", stringify!($y)),
|
||||||
concat!("to: ", stringify!($y)),
|
concat!("to: ", stringify!($y)),
|
||||||
concat!("Iterator<Item=", stringify!($y), ">")
|
concat!("Iterator<Item=", stringify!($y), ">")
|
||||||
@ -153,8 +155,10 @@ macro_rules! reg_range {
|
|||||||
($lib:ident | step $x:expr => $( $y:ty ),*) => {
|
($lib:ident | step $x:expr => $( $y:ty ),*) => {
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<StepRange<$y>>();
|
$lib.set_iterator::<StepRange<$y>>();
|
||||||
let hash = $lib.set_native_fn($x, get_step_range::<$y>);
|
let _hash = $lib.set_native_fn($x, get_step_range::<$y>);
|
||||||
$lib.update_fn_metadata(hash, &[
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
$lib.update_fn_metadata(_hash, &[
|
||||||
concat!("from: ", stringify!($y)),
|
concat!("from: ", stringify!($y)),
|
||||||
concat!("to: ", stringify!($y)),
|
concat!("to: ", stringify!($y)),
|
||||||
concat!("step: ", stringify!($y)),
|
concat!("step: ", stringify!($y)),
|
||||||
|
@ -211,7 +211,8 @@ impl From<&crate::Module> for ModuleMetadata {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// _(METADATA)_ Generate a list of all functions (including those defined in an
|
/// _(METADATA)_ Generate a list of all functions (including those defined in an
|
||||||
/// [`AST`][crate::AST]) in JSON format. Available only under the `metadata` feature.
|
/// [`AST`][crate::AST]) in JSON format.
|
||||||
|
/// Available under the `metadata` feature only.
|
||||||
///
|
///
|
||||||
/// Functions from the following sources are included:
|
/// Functions from the following sources are included:
|
||||||
/// 1) Functions defined in an [`AST`][crate::AST]
|
/// 1) Functions defined in an [`AST`][crate::AST]
|
||||||
|
@ -8,6 +8,7 @@ mod serialize;
|
|||||||
mod str;
|
mod str;
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
mod metadata;
|
mod metadata;
|
||||||
|
|
||||||
pub use de::from_dynamic;
|
pub use de::from_dynamic;
|
||||||
|
Loading…
Reference in New Issue
Block a user