Extract doc-comment on plugin functions.
This commit is contained in:
parent
f74486f904
commit
b85a9b3c1c
@ -17,6 +17,7 @@ Enhancements
|
|||||||
|
|
||||||
* Added `NativeCallContext::call_fn` to easily call a function.
|
* Added `NativeCallContext::call_fn` to easily call a function.
|
||||||
* A new syntax is introduced for `def_package!` that will replace the old syntax in future versions.
|
* A new syntax is introduced for `def_package!` that will replace the old syntax in future versions.
|
||||||
|
* Doc-comments on plugin module functions are extracted into the functions' metadata.
|
||||||
|
|
||||||
Deprecated API's
|
Deprecated API's
|
||||||
----------------
|
----------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rhai_codegen"
|
name = "rhai_codegen"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["jhwgh1968", "Stephen Chung"]
|
authors = ["jhwgh1968", "Stephen Chung"]
|
||||||
description = "Procedural macros support package for Rhai, a scripting language and engine for Rust"
|
description = "Procedural macros support package for Rhai, a scripting language and engine for Rust"
|
||||||
@ -16,7 +16,7 @@ default = []
|
|||||||
metadata = []
|
metadata = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rhai = { path = "..", version = "1.1" }
|
rhai = { path = "..", version = "1.4" }
|
||||||
trybuild = "1"
|
trybuild = "1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -117,18 +117,60 @@ pub fn inner_item_attributes<T: ExportedParams>(
|
|||||||
attrs: &mut Vec<syn::Attribute>,
|
attrs: &mut Vec<syn::Attribute>,
|
||||||
attr_name: &str,
|
attr_name: &str,
|
||||||
) -> syn::Result<T> {
|
) -> syn::Result<T> {
|
||||||
// Find the #[rhai_fn] attribute which will turn be read for the function parameters.
|
// Find the #[rhai_fn] attribute which will turn be read for function parameters.
|
||||||
if let Some(rhai_fn_idx) = attrs
|
if let Some(index) = attrs
|
||||||
.iter()
|
.iter()
|
||||||
.position(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false))
|
.position(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false))
|
||||||
{
|
{
|
||||||
let rhai_fn_attr = attrs.remove(rhai_fn_idx);
|
let rhai_fn_attr = attrs.remove(index);
|
||||||
|
|
||||||
|
// Cannot have more than one #[rhai_fn]
|
||||||
|
if let Some(duplicate) = attrs
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false))
|
||||||
|
{
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
duplicate.span(),
|
||||||
|
format!("duplicated attribute '{}'", attr_name),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
rhai_fn_attr.parse_args_with(T::parse_stream)
|
rhai_fn_attr.parse_args_with(T::parse_stream)
|
||||||
} else {
|
} else {
|
||||||
Ok(T::no_attrs())
|
Ok(T::no_attrs())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
pub fn doc_attribute(attrs: &mut Vec<syn::Attribute>) -> syn::Result<String> {
|
||||||
|
// Find the #[doc] attribute which will turn be read for function documentation.
|
||||||
|
let mut comments = String::new();
|
||||||
|
|
||||||
|
while let Some(index) = attrs
|
||||||
|
.iter()
|
||||||
|
.position(|attr| attr.path.get_ident().map(|i| *i == "doc").unwrap_or(false))
|
||||||
|
{
|
||||||
|
let attr = attrs.remove(index);
|
||||||
|
let meta = attr.parse_meta()?;
|
||||||
|
|
||||||
|
match meta {
|
||||||
|
syn::Meta::NameValue(syn::MetaNameValue {
|
||||||
|
lit: syn::Lit::Str(s),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
if !comments.is_empty() {
|
||||||
|
comments += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
comments += &s.value();
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(comments)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn collect_cfg_attr(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
|
pub fn collect_cfg_attr(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
|
||||||
attrs
|
attrs
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -282,6 +282,8 @@ pub struct ExportedFn {
|
|||||||
mut_receiver: bool,
|
mut_receiver: bool,
|
||||||
params: ExportedFnParams,
|
params: ExportedFnParams,
|
||||||
cfg_attrs: Vec<syn::Attribute>,
|
cfg_attrs: Vec<syn::Attribute>,
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
comment: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for ExportedFn {
|
impl Parse for ExportedFn {
|
||||||
@ -404,6 +406,8 @@ impl Parse for ExportedFn {
|
|||||||
mut_receiver,
|
mut_receiver,
|
||||||
params: Default::default(),
|
params: Default::default(),
|
||||||
cfg_attrs,
|
cfg_attrs,
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
comment: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,6 +507,16 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
pub fn comment(&self) -> &str {
|
||||||
|
&self.comment
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
pub fn set_comment(&mut self, comment: String) {
|
||||||
|
self.comment = comment
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_cfg_attrs(&mut self, cfg_attrs: Vec<syn::Attribute>) {
|
pub fn set_cfg_attrs(&mut self, cfg_attrs: Vec<syn::Attribute>) {
|
||||||
self.cfg_attrs = cfg_attrs
|
self.cfg_attrs = cfg_attrs
|
||||||
}
|
}
|
||||||
|
@ -117,18 +117,22 @@ impl Parse for Module {
|
|||||||
syn::Item::Fn(f) => Some(f),
|
syn::Item::Fn(f) => Some(f),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.try_fold(Vec::new(), |mut vec, item_fn| {
|
.try_fold(Vec::new(), |mut vec, item_fn| -> syn::Result<_> {
|
||||||
let params =
|
let params =
|
||||||
crate::attrs::inner_item_attributes(&mut item_fn.attrs, "rhai_fn")?;
|
crate::attrs::inner_item_attributes(&mut item_fn.attrs, "rhai_fn")?;
|
||||||
|
|
||||||
syn::parse2::<ExportedFn>(item_fn.to_token_stream())
|
let f =
|
||||||
.and_then(|mut f| {
|
syn::parse2(item_fn.to_token_stream()).and_then(|mut f: ExportedFn| {
|
||||||
f.set_params(params)?;
|
f.set_params(params)?;
|
||||||
f.set_cfg_attrs(crate::attrs::collect_cfg_attr(&item_fn.attrs));
|
f.set_cfg_attrs(crate::attrs::collect_cfg_attr(&item_fn.attrs));
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
f.set_comment(crate::attrs::doc_attribute(&mut item_fn.attrs)?);
|
||||||
Ok(f)
|
Ok(f)
|
||||||
})
|
})?;
|
||||||
.map(|f| vec.push(f))
|
|
||||||
.map(|_| vec)
|
vec.push(f);
|
||||||
|
Ok(vec)
|
||||||
})?;
|
})?;
|
||||||
// Gather and parse constants definitions.
|
// Gather and parse constants definitions.
|
||||||
for item in content.iter() {
|
for item in content.iter() {
|
||||||
|
@ -166,20 +166,30 @@ pub fn generate_body(
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
let param_names = quote! {
|
let (param_names, comment) = (
|
||||||
Some(#fn_token_name::PARAM_NAMES)
|
quote! { Some(#fn_token_name::PARAM_NAMES) },
|
||||||
};
|
function.comment(),
|
||||||
|
);
|
||||||
#[cfg(not(feature = "metadata"))]
|
#[cfg(not(feature = "metadata"))]
|
||||||
let param_names = quote! { None };
|
let (param_names, comment) = (quote! { None }, "");
|
||||||
|
|
||||||
set_fn_statements.push(
|
set_fn_statements.push(if comment.is_empty() {
|
||||||
syn::parse2::<syn::Stmt>(quote! {
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
#(#cfg_attrs)*
|
#(#cfg_attrs)*
|
||||||
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
||||||
#param_names, &[#(#fn_input_types),*], #fn_token_name().into());
|
#param_names, &[#(#fn_input_types),*], #fn_token_name().into());
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
);
|
} else {
|
||||||
|
let comment_literal = syn::LitStr::new(comment, Span::call_site());
|
||||||
|
|
||||||
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
|
#(#cfg_attrs)*
|
||||||
|
m.set_fn_with_comment(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
||||||
|
#param_names, &[#(#fn_input_types),*], #comment_literal, #fn_token_name().into());
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_fn_tokens.push(quote! {
|
gen_fn_tokens.push(quote! {
|
||||||
|
@ -37,6 +37,36 @@ mod module_tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_factory_fn_with_comment_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
/// This is a doc-comment.
|
||||||
|
/// Another line.
|
||||||
|
/** block doc-comment */
|
||||||
|
// Regular comment
|
||||||
|
/// Final line.
|
||||||
|
/** doc-comment
|
||||||
|
in multiple lines
|
||||||
|
*/
|
||||||
|
pub fn get_mystic_number() -> INT {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert!(item_mod.consts().is_empty());
|
||||||
|
assert_eq!(item_mod.fns().len(), 1);
|
||||||
|
assert_eq!(item_mod.fns()[0].name().to_string(), "get_mystic_number");
|
||||||
|
assert_eq!(item_mod.fns()[0].comment(), " This is a doc-comment.\n Another line.\n block doc-comment \n Final line.\n doc-comment\n in multiple lines\n ");
|
||||||
|
assert_eq!(item_mod.fns()[0].arg_count(), 0);
|
||||||
|
assert_eq!(
|
||||||
|
item_mod.fns()[0].return_type().unwrap(),
|
||||||
|
&syn::parse2::<syn::Type>(quote! { INT }).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_single_arg_fn_module() {
|
fn one_single_arg_fn_module() {
|
||||||
let input_tokens: TokenStream = quote! {
|
let input_tokens: TokenStream = quote! {
|
||||||
@ -323,6 +353,66 @@ mod generate_tests {
|
|||||||
assert_streams_eq(item_mod.generate(), expected_tokens);
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_factory_fn_with_comment_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
/// This is a doc-comment.
|
||||||
|
/// Another line.
|
||||||
|
/** block doc-comment */
|
||||||
|
// Regular comment
|
||||||
|
/// Final line.
|
||||||
|
/** doc-comment
|
||||||
|
in multiple lines
|
||||||
|
*/
|
||||||
|
pub fn get_mystic_number() -> INT {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn get_mystic_number() -> INT {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
|
m.set_fn_with_comment("get_mystic_number", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(get_mystic_number_token::PARAM_NAMES), &[], " This is a doc-comment.\n Another line.\n block doc-comment \n Final line.\n doc-comment\n in multiple lines\n ",
|
||||||
|
get_mystic_number_token().into());
|
||||||
|
if flatten {} else {}
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct get_mystic_number_token();
|
||||||
|
impl get_mystic_number_token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["INT"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 0usize] { [] }
|
||||||
|
}
|
||||||
|
impl PluginFunction for get_mystic_number_token {
|
||||||
|
#[inline(always)]
|
||||||
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
|
Ok(Dynamic::from(get_mystic_number()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_single_arg_global_fn_module() {
|
fn one_single_arg_global_fn_module() {
|
||||||
let input_tokens: TokenStream = quote! {
|
let input_tokens: TokenStream = quote! {
|
||||||
|
18
codegen/ui_tests/rhai_fn_duplicate_attr.rs
Normal file
18
codegen/ui_tests/rhai_fn_duplicate_attr.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(name = "test")]
|
||||||
|
#[rhai_fn(pure)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
17
codegen/ui_tests/rhai_fn_duplicate_attr.stderr
Normal file
17
codegen/ui_tests/rhai_fn_duplicate_attr.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error: duplicated attribute 'rhai_fn'
|
||||||
|
--> ui_tests/rhai_fn_duplicate_attr.rs:6:5
|
||||||
|
|
|
||||||
|
6 | #[rhai_fn(pure)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> ui_tests/rhai_fn_duplicate_attr.rs:13:8
|
||||||
|
|
|
||||||
|
13 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `n` in this scope
|
||||||
|
--> ui_tests/rhai_fn_duplicate_attr.rs:13:29
|
||||||
|
|
|
||||||
|
13 | if test_module::test_fn(n) {
|
||||||
|
| ^ not found in this scope
|
@ -10,7 +10,7 @@ use crate::tokenizer::Token;
|
|||||||
use crate::types::dynamic::Variant;
|
use crate::types::dynamic::Variant;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_params_hash, calc_qualified_fn_hash, combine_hashes, Dynamic, EvalAltResult,
|
calc_fn_params_hash, calc_qualified_fn_hash, combine_hashes, Dynamic, EvalAltResult,
|
||||||
Identifier, ImmutableString, NativeCallContext, Shared, StaticVec,
|
Identifier, ImmutableString, NativeCallContext, Shared, SmartString, StaticVec,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -53,6 +53,9 @@ pub struct FuncInfo {
|
|||||||
/// Return type name.
|
/// Return type name.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
pub return_type_name: Identifier,
|
pub return_type_name: Identifier,
|
||||||
|
/// Comments.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
pub comments: SmartString,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FuncInfo {
|
impl FuncInfo {
|
||||||
@ -488,6 +491,11 @@ impl Module {
|
|||||||
param_names_and_types,
|
param_names_and_types,
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
return_type_name: self.identifiers.get("Dynamic"),
|
return_type_name: self.identifiers.get("Dynamic"),
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
comments: fn_def
|
||||||
|
.comments
|
||||||
|
.as_ref()
|
||||||
|
.map_or(SmartString::new_const(), |v| v.join("\n").into()),
|
||||||
func: Into::<CallableFunction>::into(fn_def).into(),
|
func: Into::<CallableFunction>::into(fn_def).into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
@ -750,6 +758,8 @@ impl Module {
|
|||||||
param_names_and_types: param_names,
|
param_names_and_types: param_names,
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
return_type_name,
|
return_type_name,
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
comments: SmartString::new_const(),
|
||||||
func: func.into(),
|
func: func.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
@ -761,6 +771,47 @@ impl Module {
|
|||||||
hash_fn
|
hash_fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// _(metadata)_ Set a Rust function into the [`Module`], returning a non-zero hash key.
|
||||||
|
/// Exported under the `metadata` feature only.
|
||||||
|
///
|
||||||
|
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||||
|
///
|
||||||
|
/// # WARNING - Low Level API
|
||||||
|
///
|
||||||
|
/// This function is very low level.
|
||||||
|
///
|
||||||
|
/// ## Parameter Names and Types
|
||||||
|
///
|
||||||
|
/// Each parameter name/type pair should be a single string of the format: `var_name: type`.
|
||||||
|
///
|
||||||
|
/// ## Return Type
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[inline]
|
||||||
|
pub fn set_fn_with_comment(
|
||||||
|
&mut self,
|
||||||
|
name: impl AsRef<str> + Into<Identifier>,
|
||||||
|
namespace: FnNamespace,
|
||||||
|
access: FnAccess,
|
||||||
|
arg_names: Option<&[&str]>,
|
||||||
|
arg_types: &[TypeId],
|
||||||
|
comment: impl Into<SmartString>,
|
||||||
|
func: CallableFunction,
|
||||||
|
) -> u64 {
|
||||||
|
let hash = self.set_fn(name, namespace, access, arg_names, arg_types, func);
|
||||||
|
|
||||||
|
let comment = comment.into();
|
||||||
|
|
||||||
|
if !comment.is_empty() {
|
||||||
|
let f = self.functions.get_mut(&hash).expect("exists");
|
||||||
|
f.comments = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
|
/// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
|
||||||
/// the current set of functions, plus a list of mutable [`Dynamic`] references
|
/// the current set of functions, plus a list of mutable [`Dynamic`] references
|
||||||
/// into the [`Module`], returning a non-zero hash key.
|
/// into the [`Module`], returning a non-zero hash key.
|
||||||
|
@ -60,7 +60,7 @@ impl PartialOrd for FnParam<'_> {
|
|||||||
Some(match self.name.partial_cmp(&other.name).expect("succeed") {
|
Some(match self.name.partial_cmp(&other.name).expect("succeed") {
|
||||||
Ordering::Less => Ordering::Less,
|
Ordering::Less => Ordering::Less,
|
||||||
Ordering::Greater => Ordering::Greater,
|
Ordering::Greater => Ordering::Greater,
|
||||||
Ordering::Equal => self.typ.partial_cmp(other.typ).expect("succeed"),
|
Ordering::Equal => self.typ.partial_cmp(&other.typ).expect("succeed"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +162,14 @@ impl<'a> From<&'a crate::module::FuncInfo> for FnMetadata<'a> {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or_else(|| Vec::new(), |v| v.iter().map(|s| &**s).collect())
|
.map_or_else(|| Vec::new(), |v| v.iter().map(|s| &**s).collect())
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
#[cfg(not(feature = "metadata"))]
|
||||||
|
{
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
{
|
||||||
|
info.comments.split("\n").collect()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user