2020-08-14 12:58:34 +02:00
|
|
|
use crate::plugin::*;
|
2021-03-29 07:07:10 +02:00
|
|
|
use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
|
2021-04-17 09:15:54 +02:00
|
|
|
#[cfg(feature = "no_std")]
|
|
|
|
use std::prelude::v1::*;
|
2020-11-23 12:11:32 +01:00
|
|
|
|
2021-12-20 04:42:39 +01:00
|
|
|
def_package! {
|
2021-12-22 05:41:55 +01:00
|
|
|
/// Package of basic function pointer utilities.
|
2021-12-20 04:42:39 +01:00
|
|
|
crate::BasicFnPackage => |lib| {
|
|
|
|
lib.standard = true;
|
2021-11-05 16:22:05 +01:00
|
|
|
|
2021-12-20 04:42:39 +01:00
|
|
|
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
|
|
|
|
}
|
|
|
|
}
|
2020-08-16 17:41:59 +02:00
|
|
|
|
2020-08-20 16:11:41 +02:00
|
|
|
#[export_module]
|
|
|
|
mod fn_ptr_functions {
|
2021-02-19 16:13:53 +01:00
|
|
|
#[rhai_fn(name = "name", get = "name", pure)]
|
2021-08-13 07:42:39 +02:00
|
|
|
pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString {
|
|
|
|
fn_ptr.fn_name_raw().into()
|
2020-08-20 16:11:41 +02:00
|
|
|
}
|
2020-10-18 16:10:08 +02:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2021-10-20 10:22:12 +02:00
|
|
|
#[rhai_fn(name = "is_anonymous", get = "is_anonymous", pure)]
|
|
|
|
pub fn is_anonymous(fn_ptr: &mut FnPtr) -> bool {
|
|
|
|
fn_ptr.is_anonymous()
|
2020-10-18 11:02:17 +02:00
|
|
|
}
|
2020-11-23 12:11:32 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
#[cfg(not(feature = "no_index"))]
|
|
|
|
#[cfg(not(feature = "no_object"))]
|
2021-10-20 10:22:12 +02:00
|
|
|
pub fn get_fn_metadata_list(ctx: NativeCallContext) -> crate::Array {
|
|
|
|
collect_fn_metadata(ctx)
|
2020-11-23 12:11:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
#[cfg(not(feature = "no_index"))]
|
|
|
|
#[cfg(not(feature = "no_object"))]
|
2021-03-07 15:10:54 +01:00
|
|
|
fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
|
2021-04-17 09:15:54 +02:00
|
|
|
use crate::{ast::ScriptFnDef, Array, Identifier, Map};
|
|
|
|
use std::collections::BTreeSet;
|
2021-03-07 15:10:54 +01:00
|
|
|
|
2020-11-23 12:11:32 +01:00
|
|
|
// Create a metadata record for a function.
|
|
|
|
fn make_metadata(
|
2021-03-29 05:36:02 +02:00
|
|
|
dict: &BTreeSet<Identifier>,
|
|
|
|
namespace: Option<Identifier>,
|
2020-11-25 02:36:06 +01:00
|
|
|
f: &ScriptFnDef,
|
2020-11-23 12:11:32 +01:00
|
|
|
) -> Map {
|
2021-08-26 17:58:41 +02:00
|
|
|
const DICT: &str = "key exists";
|
2021-05-22 13:14:24 +02:00
|
|
|
|
2021-03-23 05:13:53 +01:00
|
|
|
let mut map = Map::new();
|
2020-11-23 12:11:32 +01:00
|
|
|
|
|
|
|
if let Some(ns) = namespace {
|
2021-07-24 08:11:16 +02:00
|
|
|
map.insert(dict.get("namespace").expect(DICT).clone(), ns.into());
|
2020-11-23 12:11:32 +01:00
|
|
|
}
|
2021-07-24 08:11:16 +02:00
|
|
|
map.insert(dict.get("name").expect(DICT).clone(), f.name.clone().into());
|
2020-11-23 12:11:32 +01:00
|
|
|
map.insert(
|
2021-07-24 08:11:16 +02:00
|
|
|
dict.get("access").expect(DICT).clone(),
|
2020-11-23 12:11:32 +01:00
|
|
|
match f.access {
|
2021-05-22 13:14:24 +02:00
|
|
|
FnAccess::Public => dict.get("public").expect(DICT).clone(),
|
|
|
|
FnAccess::Private => dict.get("private").expect(DICT).clone(),
|
2020-11-23 12:11:32 +01:00
|
|
|
}
|
|
|
|
.into(),
|
|
|
|
);
|
|
|
|
map.insert(
|
2021-07-24 08:11:16 +02:00
|
|
|
dict.get("is_anonymous").expect(DICT).clone(),
|
2020-11-23 12:11:32 +01:00
|
|
|
f.name.starts_with(crate::engine::FN_ANONYMOUS).into(),
|
|
|
|
);
|
|
|
|
map.insert(
|
2021-07-24 08:11:16 +02:00
|
|
|
dict.get("params").expect(DICT).clone(),
|
2020-11-23 12:11:32 +01:00
|
|
|
f.params
|
|
|
|
.iter()
|
|
|
|
.cloned()
|
|
|
|
.map(Into::<Dynamic>::into)
|
|
|
|
.collect::<Array>()
|
|
|
|
.into(),
|
|
|
|
);
|
|
|
|
|
2021-07-24 08:11:16 +02:00
|
|
|
map
|
2020-11-23 12:11:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Intern strings
|
2021-03-29 05:36:02 +02:00
|
|
|
let dict: BTreeSet<Identifier> = [
|
2020-11-23 14:12:57 +01:00
|
|
|
"namespace",
|
|
|
|
"name",
|
|
|
|
"access",
|
|
|
|
"public",
|
|
|
|
"private",
|
|
|
|
"is_anonymous",
|
|
|
|
"params",
|
|
|
|
]
|
|
|
|
.iter()
|
2021-03-23 05:13:53 +01:00
|
|
|
.map(|&s| s.into())
|
|
|
|
.collect();
|
2020-11-23 12:11:32 +01:00
|
|
|
|
2021-11-29 02:43:35 +01:00
|
|
|
let mut _list = ctx.iter_namespaces().flat_map(Module::iter_script_fn).fold(
|
2021-11-16 06:15:43 +01:00
|
|
|
Array::new(),
|
|
|
|
|mut list, (_, _, _, _, f)| {
|
|
|
|
list.push(make_metadata(&dict, None, f).into());
|
|
|
|
list
|
|
|
|
},
|
|
|
|
);
|
2020-11-23 12:11:32 +01:00
|
|
|
|
2021-03-03 15:49:57 +01:00
|
|
|
#[cfg(not(feature = "no_module"))]
|
2021-03-07 15:10:54 +01:00
|
|
|
{
|
|
|
|
// Recursively scan modules for script-defined functions.
|
|
|
|
fn scan_module(
|
|
|
|
list: &mut Array,
|
2021-03-29 05:36:02 +02:00
|
|
|
dict: &BTreeSet<Identifier>,
|
|
|
|
namespace: Identifier,
|
2021-03-07 15:10:54 +01:00
|
|
|
module: &Module,
|
|
|
|
) {
|
|
|
|
module.iter_script_fn().for_each(|(_, _, _, _, f)| {
|
|
|
|
list.push(make_metadata(dict, Some(namespace.clone()), f).into())
|
|
|
|
});
|
|
|
|
module.iter_sub_modules().for_each(|(ns, m)| {
|
2021-10-27 17:30:25 +02:00
|
|
|
let ns = format!(
|
|
|
|
"{}{}{}",
|
|
|
|
namespace,
|
2021-11-13 15:36:23 +01:00
|
|
|
crate::tokenizer::Token::DoubleColon.literal_syntax(),
|
2021-10-27 17:30:25 +02:00
|
|
|
ns
|
|
|
|
);
|
2021-03-17 06:30:47 +01:00
|
|
|
scan_module(list, dict, ns.into(), m.as_ref())
|
2021-03-07 15:10:54 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.iter_imports_raw()
|
2021-11-29 02:43:35 +01:00
|
|
|
.for_each(|(ns, m)| scan_module(&mut _list, &dict, ns.clone(), m.as_ref()));
|
2021-03-07 15:10:54 +01:00
|
|
|
}
|
2020-11-23 12:11:32 +01:00
|
|
|
|
2021-11-29 02:43:35 +01:00
|
|
|
_list
|
2020-08-16 17:41:59 +02:00
|
|
|
}
|