diff --git a/codegen/src/attrs.rs b/codegen/src/attrs.rs index 0997430b..2258ede3 100644 --- a/codegen/src/attrs.rs +++ b/codegen/src/attrs.rs @@ -142,33 +142,34 @@ pub fn inner_item_attributes( } #[cfg(feature = "metadata")] -pub fn doc_attributes(attrs: &mut Vec) -> syn::Result> { +pub fn doc_attributes(attrs: &[syn::Attribute]) -> syn::Result> { // Find the #[doc] attribute which will turn be read for function documentation. let mut comments = Vec::new(); - while let Some(index) = attrs - .iter() - .position(|attr| attr.path.get_ident().map(|i| *i == "doc").unwrap_or(false)) - { - match attrs.remove(index).parse_meta()? { - syn::Meta::NameValue(syn::MetaNameValue { - lit: syn::Lit::Str(s), - .. - }) => { - let mut line = s.value(); + for attr in attrs { + if let Some(i) = attr.path.get_ident() { + if *i == "doc" { + match attr.parse_meta()? { + syn::Meta::NameValue(syn::MetaNameValue { + lit: syn::Lit::Str(s), + .. + }) => { + let mut line = s.value(); - if line.contains('\n') { - // Must be a block comment `/** ... */` - line.insert_str(0, "/**"); - line.push_str("*/"); - } else { - // Single line - assume it is `///` - line.insert_str(0, "///"); + if line.contains('\n') { + // Must be a block comment `/** ... */` + line.insert_str(0, "/**"); + line.push_str("*/"); + } else { + // Single line - assume it is `///` + line.insert_str(0, "///"); + } + + comments.push(line); + } + _ => (), } - - comments.push(line); } - _ => continue, } } diff --git a/codegen/src/function.rs b/codegen/src/function.rs index 29e2a2cf..59f4f5ce 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -407,7 +407,7 @@ impl Parse for ExportedFn { params: Default::default(), cfg_attrs, #[cfg(feature = "metadata")] - comments: Default::default(), + comments: Vec::new(), }) } } diff --git a/codegen/src/module.rs b/codegen/src/module.rs index 14290c59..2a071ffc 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -127,7 +127,7 @@ impl Parse for Module { f.set_cfg_attrs(crate::attrs::collect_cfg_attr(&item_fn.attrs)); #[cfg(feature = "metadata")] - f.set_comments(crate::attrs::doc_attributes(&mut item_fn.attrs)?); + f.set_comments(crate::attrs::doc_attributes(&item_fn.attrs)?); Ok(f) })?; @@ -144,12 +144,12 @@ impl Parse for Module { attrs, ty, .. - }) if matches!(vis, syn::Visibility::Public(_)) => consts.push(( - ident.to_string(), - ty.clone(), - expr.as_ref().clone(), - crate::attrs::collect_cfg_attr(&attrs), - )), + }) if matches!(vis, syn::Visibility::Public(_)) => consts.push(ExportedConst { + name: ident.to_string(), + typ: ty.clone(), + expr: expr.as_ref().clone(), + cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), + }), _ => {} } } diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index 01bacf62..b922c231 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -10,7 +10,13 @@ use crate::function::{ }; use crate::module::Module; -pub type ExportedConst = (String, Box, syn::Expr, Vec); +#[derive(Debug)] +pub struct ExportedConst { + pub name: String, + pub typ: Box, + pub expr: syn::Expr, + pub cfg_attrs: Vec, +} pub fn generate_body( fns: &mut [ExportedFn], @@ -25,7 +31,12 @@ pub fn generate_body( let str_type_path = syn::parse2::(quote! { str }).unwrap(); let string_type_path = syn::parse2::(quote! { String }).unwrap(); - for (const_name, _, _, cfg_attrs) in consts { + for ExportedConst { + name: const_name, + cfg_attrs, + .. + } in consts + { let const_literal = syn::LitStr::new(&const_name, Span::call_site()); let const_ref = syn::Ident::new(&const_name, Span::call_site()); diff --git a/codegen/src/test/module.rs b/codegen/src/test/module.rs index 4ba006f7..f4700e83 100644 --- a/codegen/src/test/module.rs +++ b/codegen/src/test/module.rs @@ -38,6 +38,7 @@ mod module_tests { } #[test] + #[cfg(feature = "metadata")] fn one_factory_fn_with_comments_module() { let input_tokens: TokenStream = quote! { pub mod one_fn { @@ -150,9 +151,9 @@ mod module_tests { assert!(item_mod.fns().is_empty()); assert!(item_mod.consts().is_empty()); assert_eq!(item_mod.sub_modules().len(), 1); - assert_eq!(&item_mod.sub_modules()[0].consts()[0].0, "MYSTIC_NUMBER"); + assert_eq!(&item_mod.sub_modules()[0].consts()[0].name, "MYSTIC_NUMBER"); assert_eq!( - item_mod.sub_modules()[0].consts()[0].2, + item_mod.sub_modules()[0].consts()[0].expr, syn::parse2::(quote! { 42 }).unwrap() ); } @@ -211,9 +212,9 @@ mod module_tests { let item_mod = syn::parse2::(input_tokens).unwrap(); assert!(item_mod.fns().is_empty()); assert_eq!(item_mod.consts().len(), 1); - assert_eq!(&item_mod.consts()[0].0, "MYSTIC_NUMBER"); + assert_eq!(&item_mod.consts()[0].name, "MYSTIC_NUMBER"); assert_eq!( - item_mod.consts()[0].2, + item_mod.consts()[0].expr, syn::parse2::(quote! { 42 }).unwrap() ); } @@ -386,6 +387,14 @@ mod generate_tests { let expected_tokens = 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 } @@ -401,8 +410,13 @@ mod generate_tests { #[allow(unused_mut)] pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) { m.set_fn_with_comments("get_mystic_number", FnNamespace::Internal, FnAccess::Public, - Some(get_mystic_number_token::PARAM_NAMES), &[], &["/// This is a doc-comment.","/// Another line.","/// block doc-comment ","/// Final line.","/** doc-comment\n in multiple lines\n */"], - get_mystic_number_token().into()); + Some(get_mystic_number_token::PARAM_NAMES), &[], &[ + "/// This is a doc-comment.", + "/// Another line.", + "/// block doc-comment ", + "/// Final line.", + "/** doc-comment\n in multiple lines\n */" + ], get_mystic_number_token().into()); if flatten {} else {} } #[allow(non_camel_case_types)]