Merge pull request #638 from schungx/master
Include types in definitions.
This commit is contained in:
commit
250604d5e6
@ -53,6 +53,7 @@ Enhancements
|
|||||||
* `is_empty` method is added to arrays, BLOB's, object maps, strings and ranges.
|
* `is_empty` method is added to arrays, BLOB's, object maps, strings and ranges.
|
||||||
* `StaticModuleResolver` now stores the path in the module's `id` field.
|
* `StaticModuleResolver` now stores the path in the module's `id` field.
|
||||||
* `Engine::module_resolver` is added to grant access to the `Engine`'s module resolver.
|
* `Engine::module_resolver` is added to grant access to the `Engine`'s module resolver.
|
||||||
|
* Constants and variables now have types in generated definition files.
|
||||||
|
|
||||||
|
|
||||||
Version 1.9.1
|
Version 1.9.1
|
||||||
|
@ -64,7 +64,7 @@ debugging = ["internals"] # enable debugging
|
|||||||
serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] # implement serde for rhai types
|
serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] # implement serde for rhai types
|
||||||
|
|
||||||
# compiling for no-std
|
# compiling for no-std
|
||||||
no_std = ["no-std-compat", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng", "hashbrown"]
|
no_std = ["no-std-compat", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng", "hashbrown/ahash-compile-time-rng"]
|
||||||
|
|
||||||
# compiling for WASM
|
# compiling for WASM
|
||||||
wasm-bindgen = ["instant/wasm-bindgen"]
|
wasm-bindgen = ["instant/wasm-bindgen"]
|
||||||
|
@ -1211,7 +1211,7 @@ fn all(array: Array, filter: FnPtr) -> bool;
|
|||||||
/// let x = [1, 2, 3];
|
/// let x = [1, 2, 3];
|
||||||
/// let y = [true, 'x'];
|
/// let y = [true, 'x'];
|
||||||
///
|
///
|
||||||
/// x.push(y);
|
/// x.append(y);
|
||||||
///
|
///
|
||||||
/// print(x); // prints "[1, 2, 3, true, 'x']"
|
/// print(x); // prints "[1, 2, 3, true, 'x']"
|
||||||
/// ```
|
/// ```
|
||||||
@ -6480,8 +6480,12 @@ op |(u64, u64) -> u64;
|
|||||||
op |(u8, u8) -> u8;
|
op |(u8, u8) -> u8;
|
||||||
|
|
||||||
module general_kenobi {
|
module general_kenobi {
|
||||||
|
const CONSTANT: int;
|
||||||
|
|
||||||
/// Returns a string where "hello there" is repeated `n` times.
|
/// Returns a string where "hello there" is repeated `n` times.
|
||||||
fn hello_there(n: int) -> String;
|
fn hello_there(n: int) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hello_there;
|
let hello_there: string;
|
||||||
|
|
||||||
|
const HELLO: string;
|
||||||
|
@ -3,8 +3,12 @@ module static;
|
|||||||
op minus(int, int) -> int;
|
op minus(int, int) -> int;
|
||||||
|
|
||||||
module general_kenobi {
|
module general_kenobi {
|
||||||
|
const CONSTANT: int;
|
||||||
|
|
||||||
/// Returns a string where "hello there" is repeated `n` times.
|
/// Returns a string where "hello there" is repeated `n` times.
|
||||||
fn hello_there(n: int) -> String;
|
fn hello_there(n: int) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hello_there;
|
let hello_there: string;
|
||||||
|
|
||||||
|
const HELLO: string;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
module static;
|
module static;
|
||||||
|
|
||||||
let hello_there;
|
let hello_there: string;
|
||||||
|
|
||||||
|
const HELLO: string;
|
@ -693,7 +693,7 @@ fn all(array: Array, filter: FnPtr) -> bool;
|
|||||||
/// let x = [1, 2, 3];
|
/// let x = [1, 2, 3];
|
||||||
/// let y = [true, 'x'];
|
/// let y = [true, 'x'];
|
||||||
///
|
///
|
||||||
/// x.push(y);
|
/// x.append(y);
|
||||||
///
|
///
|
||||||
/// print(x); // prints "[1, 2, 3, true, 'x']"
|
/// print(x); // prints "[1, 2, 3, true, 'x']"
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
module general_kenobi;
|
module general_kenobi;
|
||||||
|
|
||||||
|
const CONSTANT: int;
|
||||||
|
|
||||||
/// Returns a string where "hello there" is repeated `n` times.
|
/// Returns a string where "hello there" is repeated `n` times.
|
||||||
fn hello_there(n: int) -> String;
|
fn hello_there(n: int) -> String;
|
@ -3,8 +3,8 @@
|
|||||||
"general_kenobi": {
|
"general_kenobi": {
|
||||||
"functions": [
|
"functions": [
|
||||||
{
|
{
|
||||||
"baseHash": 14798413363692662073,
|
"baseHash": 727795846011184342,
|
||||||
"fullHash": 2039416761244929762,
|
"fullHash": 5101524478338862216,
|
||||||
"namespace": "internal",
|
"namespace": "internal",
|
||||||
"access": "public",
|
"access": "public",
|
||||||
"name": "hello_there",
|
"name": "hello_there",
|
||||||
@ -27,8 +27,8 @@
|
|||||||
},
|
},
|
||||||
"functions": [
|
"functions": [
|
||||||
{
|
{
|
||||||
"baseHash": 17487674894006547092,
|
"baseHash": 17133166385977770750,
|
||||||
"fullHash": 13058993152904417424,
|
"fullHash": 11299449021188202345,
|
||||||
"namespace": "global",
|
"namespace": "global",
|
||||||
"access": "public",
|
"access": "public",
|
||||||
"name": "minus",
|
"name": "minus",
|
||||||
|
@ -3,6 +3,9 @@ use rhai::{Engine, EvalAltResult, Scope};
|
|||||||
|
|
||||||
#[export_module]
|
#[export_module]
|
||||||
pub mod general_kenobi {
|
pub mod general_kenobi {
|
||||||
|
/// General Kenobi's Constant.
|
||||||
|
pub const CONSTANT: i64 = 42;
|
||||||
|
|
||||||
/// Returns a string where "hello there" is repeated `n` times.
|
/// Returns a string where "hello there" is repeated `n` times.
|
||||||
pub fn hello_there(n: i64) -> String {
|
pub fn hello_there(n: i64) -> String {
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
@ -17,6 +20,9 @@ fn main() -> Result<(), Box<EvalAltResult>> {
|
|||||||
// This variable will also show up in the definitions, since it will be part of the scope.
|
// This variable will also show up in the definitions, since it will be part of the scope.
|
||||||
scope.push("hello_there", "hello there");
|
scope.push("hello_there", "hello there");
|
||||||
|
|
||||||
|
// This constant will also show up in the definitions, since it will be part of the scope.
|
||||||
|
scope.push_constant("HELLO", "hello there");
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
engine.register_static_module("general_kenobi", exported_module!(general_kenobi).into());
|
engine.register_static_module("general_kenobi", exported_module!(general_kenobi).into());
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ impl Definitions<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(scope) = self.scope {
|
if let Some(scope) = self.scope {
|
||||||
scope.write_definition(&mut s).unwrap();
|
scope.write_definition(&mut s, self).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
s
|
s
|
||||||
@ -412,13 +412,15 @@ impl Module {
|
|||||||
let mut vars = self.iter_var().collect::<Vec<_>>();
|
let mut vars = self.iter_var().collect::<Vec<_>>();
|
||||||
vars.sort_by(|(a, _), (b, _)| a.cmp(b));
|
vars.sort_by(|(a, _), (b, _)| a.cmp(b));
|
||||||
|
|
||||||
for (name, _) in vars {
|
for (name, value) in vars {
|
||||||
if !first {
|
if !first {
|
||||||
writer.write_str("\n\n")?;
|
writer.write_str("\n\n")?;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
write!(writer, "const {name}: ?;")?;
|
let ty = def_type_name(value.type_name(), def.engine);
|
||||||
|
|
||||||
|
write!(writer, "const {name}: {ty};")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut func_infos = self.iter_fn().collect::<Vec<_>>();
|
let mut func_infos = self.iter_fn().collect::<Vec<_>>();
|
||||||
@ -554,17 +556,18 @@ fn def_type_name<'a>(ty: &'a str, engine: &'a Engine) -> Cow<'a, str> {
|
|||||||
|
|
||||||
impl Scope<'_> {
|
impl Scope<'_> {
|
||||||
/// _(metadata, internals)_ Return definitions for all items inside the [`Scope`].
|
/// _(metadata, internals)_ Return definitions for all items inside the [`Scope`].
|
||||||
fn write_definition(&self, writer: &mut dyn fmt::Write) -> fmt::Result {
|
fn write_definition(&self, writer: &mut dyn fmt::Write, def: &Definitions) -> fmt::Result {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for (name, constant, _) in self.iter_raw() {
|
for (name, constant, value) in self.iter_raw() {
|
||||||
if !first {
|
if !first {
|
||||||
writer.write_str("\n\n")?;
|
writer.write_str("\n\n")?;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
let kw = if constant { Token::Const } else { Token::Let };
|
let kw = if constant { Token::Const } else { Token::Let };
|
||||||
|
let ty = def_type_name(value.type_name(), def.engine);
|
||||||
|
|
||||||
write!(writer, "{kw} {name};")?;
|
write!(writer, "{kw} {name}: {ty};")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,6 +106,71 @@ fn map_std_type_name(name: &str, shorthands: bool) -> &str {
|
|||||||
.map_or(name, |s| map_std_type_name(s, shorthands))
|
.map_or(name, |s| map_std_type_name(s, shorthands))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Format a Rust type to be display-friendly.
|
||||||
|
///
|
||||||
|
/// * `()` is cleared.
|
||||||
|
/// * `INT` and `FLOAT` are expanded.
|
||||||
|
/// * [`RhaiResult`][crate::RhaiResult] and [`RhaiResultOf<T>`][crate::RhaiResultOf] are expanded.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
pub fn format_type(typ: &str, is_return_type: bool) -> std::borrow::Cow<str> {
|
||||||
|
const RHAI_RESULT_TYPE: &str = "RhaiResult";
|
||||||
|
const RHAI_RESULT_TYPE_EXPAND: &str = "Result<Dynamic, Box<EvalAltResult>>";
|
||||||
|
const RHAI_RESULT_OF_TYPE: &str = "RhaiResultOf<";
|
||||||
|
const RHAI_RESULT_OF_TYPE_EXPAND: &str = "Result<{}, Box<EvalAltResult>>";
|
||||||
|
const RHAI_RANGE: &str = "ExclusiveRange";
|
||||||
|
const RHAI_RANGE_TYPE: &str = "Range<";
|
||||||
|
const RHAI_RANGE_EXPAND: &str = "Range<{}>";
|
||||||
|
const RHAI_INCLUSIVE_RANGE: &str = "InclusiveRange";
|
||||||
|
const RHAI_INCLUSIVE_RANGE_TYPE: &str = "RangeInclusive<";
|
||||||
|
const RHAI_INCLUSIVE_RANGE_EXPAND: &str = "RangeInclusive<{}>";
|
||||||
|
|
||||||
|
let typ = typ.trim();
|
||||||
|
|
||||||
|
if let Some(x) = typ.strip_prefix("rhai::") {
|
||||||
|
return format_type(x, is_return_type);
|
||||||
|
} else if let Some(x) = typ.strip_prefix("&mut ") {
|
||||||
|
let r = format_type(x, false);
|
||||||
|
return if r == x {
|
||||||
|
typ.into()
|
||||||
|
} else {
|
||||||
|
format!("&mut {r}").into()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
match typ {
|
||||||
|
"" | "()" if is_return_type => "".into(),
|
||||||
|
"INT" => std::any::type_name::<crate::INT>().into(),
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
"FLOAT" => std::any::type_name::<crate::FLOAT>().into(),
|
||||||
|
RHAI_RANGE => RHAI_RANGE_EXPAND
|
||||||
|
.replace("{}", std::any::type_name::<crate::INT>())
|
||||||
|
.into(),
|
||||||
|
RHAI_INCLUSIVE_RANGE => RHAI_INCLUSIVE_RANGE_EXPAND
|
||||||
|
.replace("{}", std::any::type_name::<crate::INT>())
|
||||||
|
.into(),
|
||||||
|
RHAI_RESULT_TYPE => RHAI_RESULT_TYPE_EXPAND.into(),
|
||||||
|
ty if ty.starts_with(RHAI_RANGE_TYPE) && ty.ends_with('>') => {
|
||||||
|
let inner = &ty[RHAI_RANGE_TYPE.len()..ty.len() - 1];
|
||||||
|
RHAI_RANGE_EXPAND
|
||||||
|
.replace("{}", format_type(inner, false).trim())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
ty if ty.starts_with(RHAI_INCLUSIVE_RANGE_TYPE) && ty.ends_with('>') => {
|
||||||
|
let inner = &ty[RHAI_INCLUSIVE_RANGE_TYPE.len()..ty.len() - 1];
|
||||||
|
RHAI_INCLUSIVE_RANGE_EXPAND
|
||||||
|
.replace("{}", format_type(inner, false).trim())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
ty if ty.starts_with(RHAI_RESULT_OF_TYPE) && ty.ends_with('>') => {
|
||||||
|
let inner = &ty[RHAI_RESULT_OF_TYPE.len()..ty.len() - 1];
|
||||||
|
RHAI_RESULT_OF_TYPE_EXPAND
|
||||||
|
.replace("{}", format_type(inner, false).trim())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
ty => ty.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Pretty-print a type name.
|
/// Pretty-print a type name.
|
||||||
///
|
///
|
||||||
|
@ -15,6 +15,10 @@ use crate::{
|
|||||||
Scope, ERR,
|
Scope, ERR,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
|
use hashbrown::hash_map::Entry;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
any::{type_name, TypeId},
|
any::{type_name, TypeId},
|
||||||
@ -199,10 +203,9 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = caches
|
match caches.fn_resolution_cache_mut().entry(hash) {
|
||||||
.fn_resolution_cache_mut()
|
Entry::Occupied(entry) => entry.into_mut().as_ref(),
|
||||||
.entry(hash)
|
Entry::Vacant(entry) => {
|
||||||
.or_insert_with(|| {
|
|
||||||
let num_args = args.as_ref().map_or(0, |a| a.len());
|
let num_args = args.as_ref().map_or(0, |a| a.len());
|
||||||
let mut max_bitmask = 0; // One above maximum bitmask based on number of parameters.
|
let mut max_bitmask = 0; // One above maximum bitmask based on number of parameters.
|
||||||
// Set later when a specific matching function is not found.
|
// Set later when a specific matching function is not found.
|
||||||
@ -211,45 +214,27 @@ impl Engine {
|
|||||||
loop {
|
loop {
|
||||||
let func = lib
|
let func = lib
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|&m| {
|
.find_map(|&m| m.get_fn(hash).map(|f| (f, m.id())))
|
||||||
m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
|
|
||||||
func,
|
|
||||||
source: m.id().map(|s| Box::new(s.into())),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.global_modules.iter().find_map(|m| {
|
self.global_modules
|
||||||
m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
|
.iter()
|
||||||
func,
|
.find_map(|m| m.get_fn(hash).map(|f| (f, m.id())))
|
||||||
source: m.id().map(|s| Box::new(s.into())),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
let func = func
|
let func = func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| {
|
||||||
.or_else(|| {
|
self.global_sub_modules
|
||||||
_global.get_qualified_fn(hash).map(|(func, source)| {
|
.values()
|
||||||
FnResolutionCacheEntry {
|
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id())))
|
||||||
func: func.clone(),
|
});
|
||||||
source: source.map(|s| Box::new(s.into())),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.global_sub_modules.values().find_map(|m| {
|
|
||||||
m.get_qualified_fn(hash).cloned().map(|func| {
|
|
||||||
FnResolutionCacheEntry {
|
|
||||||
func,
|
|
||||||
source: m.id().map(|s| Box::new(s.into())),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
// Specific version found
|
if let Some((f, s)) = func {
|
||||||
if let Some(f) = func {
|
// Specific version found - insert into cache and return it
|
||||||
return Some(f);
|
let new_entry = FnResolutionCacheEntry {
|
||||||
|
func: f.clone(),
|
||||||
|
source: s.map(|s| Box::new(s.into())),
|
||||||
|
};
|
||||||
|
return entry.insert(Some(new_entry)).as_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check `Dynamic` parameters for functions with parameters
|
// Check `Dynamic` parameters for functions with parameters
|
||||||
@ -282,7 +267,8 @@ impl Engine {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
return args.and_then(|args| {
|
// Try to find a built-in version
|
||||||
|
let builtin = args.and_then(|args| {
|
||||||
if is_op_assignment {
|
if is_op_assignment {
|
||||||
let (first_arg, rest_args) = args.split_first().unwrap();
|
let (first_arg, rest_args) = args.split_first().unwrap();
|
||||||
|
|
||||||
@ -301,6 +287,8 @@ impl Engine {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return entry.insert(builtin).as_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try all permutations with `Dynamic` wildcards
|
// Try all permutations with `Dynamic` wildcards
|
||||||
@ -323,9 +311,8 @@ impl Engine {
|
|||||||
|
|
||||||
bitmask += 1;
|
bitmask += 1;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
result.as_ref()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Main Entry-Point
|
/// # Main Entry-Point
|
||||||
|
@ -47,11 +47,11 @@ impl Hasher for StraightHasher {
|
|||||||
fn finish(&self) -> u64 {
|
fn finish(&self) -> u64 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
fn write(&mut self, _bytes: &[u8]) {
|
fn write(&mut self, _bytes: &[u8]) {
|
||||||
panic!("StraightHasher can only hash u64 values");
|
panic!("StraightHasher can only hash u64 values");
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
fn write_u64(&mut self, i: u64) {
|
fn write_u64(&mut self, i: u64) {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
self.0 = ALT_ZERO_HASH;
|
self.0 = ALT_ZERO_HASH;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! Module defining external-loaded modules for Rhai.
|
//! Module defining external-loaded modules for Rhai.
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
use crate::api::type_names::format_type;
|
||||||
use crate::ast::FnAccess;
|
use crate::ast::FnAccess;
|
||||||
use crate::func::{
|
use crate::func::{
|
||||||
shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction,
|
shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction,
|
||||||
@ -116,69 +118,6 @@ pub struct FuncInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FuncInfo {
|
impl FuncInfo {
|
||||||
/// Format a return type to be display-friendly.
|
|
||||||
///
|
|
||||||
/// `()` is cleared.
|
|
||||||
/// [`RhaiResult`][crate::RhaiResult] and [`RhaiResultOf<T>`] are expanded.
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
pub fn format_type(typ: &str, is_return_type: bool) -> std::borrow::Cow<str> {
|
|
||||||
const RHAI_RESULT_TYPE: &str = "RhaiResult";
|
|
||||||
const RHAI_RESULT_TYPE_EXPAND: &str = "Result<Dynamic, Box<EvalAltResult>>";
|
|
||||||
const RHAI_RESULT_OF_TYPE: &str = "RhaiResultOf<";
|
|
||||||
const RHAI_RESULT_OF_TYPE_EXPAND: &str = "Result<{}, Box<EvalAltResult>>";
|
|
||||||
const RHAI_RANGE: &str = "ExclusiveRange";
|
|
||||||
const RHAI_RANGE_TYPE: &str = "Range<";
|
|
||||||
const RHAI_RANGE_EXPAND: &str = "Range<{}>";
|
|
||||||
const RHAI_INCLUSIVE_RANGE: &str = "InclusiveRange";
|
|
||||||
const RHAI_INCLUSIVE_RANGE_TYPE: &str = "RangeInclusive<";
|
|
||||||
const RHAI_INCLUSIVE_RANGE_EXPAND: &str = "RangeInclusive<{}>";
|
|
||||||
|
|
||||||
let typ = typ.trim();
|
|
||||||
|
|
||||||
if let Some(x) = typ.strip_prefix("rhai::") {
|
|
||||||
return Self::format_type(x, is_return_type);
|
|
||||||
} else if let Some(x) = typ.strip_prefix("&mut ") {
|
|
||||||
let r = Self::format_type(x, false);
|
|
||||||
return if r == x {
|
|
||||||
typ.into()
|
|
||||||
} else {
|
|
||||||
format!("&mut {r}").into()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
match typ {
|
|
||||||
"" | "()" if is_return_type => "".into(),
|
|
||||||
"INT" => std::any::type_name::<crate::INT>().into(),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
"FLOAT" => std::any::type_name::<crate::FLOAT>().into(),
|
|
||||||
RHAI_RANGE => RHAI_RANGE_EXPAND
|
|
||||||
.replace("{}", std::any::type_name::<crate::INT>())
|
|
||||||
.into(),
|
|
||||||
RHAI_INCLUSIVE_RANGE => RHAI_INCLUSIVE_RANGE_EXPAND
|
|
||||||
.replace("{}", std::any::type_name::<crate::INT>())
|
|
||||||
.into(),
|
|
||||||
RHAI_RESULT_TYPE => RHAI_RESULT_TYPE_EXPAND.into(),
|
|
||||||
ty if ty.starts_with(RHAI_RANGE_TYPE) && ty.ends_with('>') => {
|
|
||||||
let inner = &ty[RHAI_RANGE_TYPE.len()..ty.len() - 1];
|
|
||||||
RHAI_RANGE_EXPAND
|
|
||||||
.replace("{}", Self::format_type(inner, false).trim())
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
ty if ty.starts_with(RHAI_INCLUSIVE_RANGE_TYPE) && ty.ends_with('>') => {
|
|
||||||
let inner = &ty[RHAI_INCLUSIVE_RANGE_TYPE.len()..ty.len() - 1];
|
|
||||||
RHAI_INCLUSIVE_RANGE_EXPAND
|
|
||||||
.replace("{}", Self::format_type(inner, false).trim())
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
ty if ty.starts_with(RHAI_RESULT_OF_TYPE) && ty.ends_with('>') => {
|
|
||||||
let inner = &ty[RHAI_RESULT_OF_TYPE.len()..ty.len() - 1];
|
|
||||||
RHAI_RESULT_OF_TYPE_EXPAND
|
|
||||||
.replace("{}", Self::format_type(inner, false).trim())
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
ty => ty.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// _(metadata)_ Generate a signature of the function.
|
/// _(metadata)_ Generate a signature of the function.
|
||||||
/// Exported under the `metadata` feature only.
|
/// Exported under the `metadata` feature only.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
@ -186,7 +125,7 @@ impl FuncInfo {
|
|||||||
pub fn gen_signature(&self) -> String {
|
pub fn gen_signature(&self) -> String {
|
||||||
let mut sig = format!("{}(", self.metadata.name);
|
let mut sig = format!("{}(", self.metadata.name);
|
||||||
|
|
||||||
let return_type = Self::format_type(&self.metadata.return_type, true);
|
let return_type = format_type(&self.metadata.return_type, true);
|
||||||
|
|
||||||
if self.metadata.params_info.is_empty() {
|
if self.metadata.params_info.is_empty() {
|
||||||
for x in 0..self.metadata.params {
|
for x in 0..self.metadata.params {
|
||||||
@ -207,9 +146,7 @@ impl FuncInfo {
|
|||||||
s => s,
|
s => s,
|
||||||
};
|
};
|
||||||
let result: std::borrow::Cow<str> = match seg.next() {
|
let result: std::borrow::Cow<str> = match seg.next() {
|
||||||
Some(typ) => {
|
Some(typ) => format!("{name}: {}", format_type(typ, false)).into(),
|
||||||
format!("{name}: {}", FuncInfo::format_type(typ, false)).into()
|
|
||||||
}
|
|
||||||
None => name.into(),
|
None => name.into(),
|
||||||
};
|
};
|
||||||
result
|
result
|
||||||
@ -278,9 +215,9 @@ pub struct Module {
|
|||||||
/// Native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters.
|
/// Native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters.
|
||||||
dynamic_functions: StraightHashSet<u64>,
|
dynamic_functions: StraightHashSet<u64>,
|
||||||
/// Iterator functions, keyed by the type producing the iterator.
|
/// Iterator functions, keyed by the type producing the iterator.
|
||||||
type_iterators: StraightHashMap<TypeId, Shared<IteratorFn>>,
|
type_iterators: BTreeMap<TypeId, Shared<IteratorFn>>,
|
||||||
/// Flattened collection of iterator functions, including those in sub-modules.
|
/// Flattened collection of iterator functions, including those in sub-modules.
|
||||||
all_type_iterators: StraightHashMap<TypeId, Shared<IteratorFn>>,
|
all_type_iterators: BTreeMap<TypeId, Shared<IteratorFn>>,
|
||||||
/// Is the [`Module`] indexed?
|
/// Is the [`Module`] indexed?
|
||||||
indexed: bool,
|
indexed: bool,
|
||||||
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
||||||
@ -378,8 +315,8 @@ impl Module {
|
|||||||
functions: StraightHashMap::default(),
|
functions: StraightHashMap::default(),
|
||||||
all_functions: StraightHashMap::default(),
|
all_functions: StraightHashMap::default(),
|
||||||
dynamic_functions: StraightHashSet::default(),
|
dynamic_functions: StraightHashSet::default(),
|
||||||
type_iterators: StraightHashMap::default(),
|
type_iterators: BTreeMap::new(),
|
||||||
all_type_iterators: StraightHashMap::default(),
|
all_type_iterators: BTreeMap::new(),
|
||||||
indexed: true,
|
indexed: true,
|
||||||
contains_indexed_global_functions: false,
|
contains_indexed_global_functions: false,
|
||||||
}
|
}
|
||||||
@ -2141,7 +2078,7 @@ impl Module {
|
|||||||
path: &mut Vec<&'a str>,
|
path: &mut Vec<&'a str>,
|
||||||
variables: &mut StraightHashMap<u64, Dynamic>,
|
variables: &mut StraightHashMap<u64, Dynamic>,
|
||||||
functions: &mut StraightHashMap<u64, CallableFunction>,
|
functions: &mut StraightHashMap<u64, CallableFunction>,
|
||||||
type_iterators: &mut StraightHashMap<TypeId, Shared<IteratorFn>>,
|
type_iterators: &mut BTreeMap<TypeId, Shared<IteratorFn>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut contains_indexed_global_functions = false;
|
let mut contains_indexed_global_functions = false;
|
||||||
|
|
||||||
@ -2205,7 +2142,7 @@ impl Module {
|
|||||||
let mut path = Vec::with_capacity(4);
|
let mut path = Vec::with_capacity(4);
|
||||||
let mut variables = StraightHashMap::default();
|
let mut variables = StraightHashMap::default();
|
||||||
let mut functions = StraightHashMap::default();
|
let mut functions = StraightHashMap::default();
|
||||||
let mut type_iterators = StraightHashMap::default();
|
let mut type_iterators = BTreeMap::new();
|
||||||
|
|
||||||
path.push("");
|
path.push("");
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Serialization of functions metadata.
|
//! Serialization of functions metadata.
|
||||||
#![cfg(feature = "metadata")]
|
#![cfg(feature = "metadata")]
|
||||||
|
|
||||||
|
use crate::api::type_names::format_type;
|
||||||
use crate::module::{calc_native_fn_hash, FuncInfo};
|
use crate::module::{calc_native_fn_hash, FuncInfo};
|
||||||
use crate::{calc_fn_hash, Engine, FnAccess, SmartString, StaticVec, AST};
|
use crate::{calc_fn_hash, Engine, FnAccess, SmartString, StaticVec, AST};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -94,12 +95,12 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> {
|
|||||||
"_" => None,
|
"_" => None,
|
||||||
s => Some(s),
|
s => Some(s),
|
||||||
};
|
};
|
||||||
let typ = seg.next().map(|s| FuncInfo::format_type(s, false));
|
let typ = seg.next().map(|s| format_type(s, false));
|
||||||
FnParam { name, typ }
|
FnParam { name, typ }
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
_dummy: None,
|
_dummy: None,
|
||||||
return_type: FuncInfo::format_type(&info.metadata.return_type, true),
|
return_type: format_type(&info.metadata.return_type, true),
|
||||||
signature: info.gen_signature().into(),
|
signature: info.gen_signature().into(),
|
||||||
doc_comments: if info.func.is_script() {
|
doc_comments: if info.func.is_script() {
|
||||||
#[cfg(feature = "no_function")]
|
#[cfg(feature = "no_function")]
|
||||||
|
Loading…
Reference in New Issue
Block a user