Skip to content

Commit

Permalink
feat: support docstrings in metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitjes committed Nov 26, 2023
1 parent d4700d6 commit 143b0b7
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 60 deletions.
23 changes: 19 additions & 4 deletions uniffi_macros/src/enum_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use quote::quote;
use syn::{Data, DataEnum, DeriveInput, Field, Index};

use crate::util::{
create_metadata_items, derive_all_ffi_traits, ident_to_string, mod_path, tagged_impl_header,
try_metadata_value_from_usize, try_read_field,
create_metadata_items, derive_all_ffi_traits, extract_docstring, ident_to_string, mod_path,
tagged_impl_header, try_metadata_value_from_usize, try_read_field,
};

pub fn expand_enum(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStream> {
Expand All @@ -18,10 +18,12 @@ pub fn expand_enum(input: DeriveInput, udl_mode: bool) -> syn::Result<TokenStrea
}
};
let ident = &input.ident;
let docstring = extract_docstring(&input.attrs)?;
let ffi_converter_impl = enum_ffi_converter_impl(ident, &enum_, udl_mode);

let meta_static_var = (!udl_mode).then(|| {
enum_meta_static_var(ident, &enum_).unwrap_or_else(syn::Error::into_compile_error)
enum_meta_static_var(ident, docstring, &enum_)
.unwrap_or_else(syn::Error::into_compile_error)
});

Ok(quote! {
Expand Down Expand Up @@ -136,7 +138,11 @@ fn write_field(f: &Field) -> TokenStream {
}
}

pub(crate) fn enum_meta_static_var(ident: &Ident, enum_: &DataEnum) -> syn::Result<TokenStream> {
pub(crate) fn enum_meta_static_var(
ident: &Ident,
docstring: String,
enum_: &DataEnum,
) -> syn::Result<TokenStream> {
let name = ident_to_string(ident);
let module_path = mod_path()?;

Expand All @@ -146,6 +152,7 @@ pub(crate) fn enum_meta_static_var(ident: &Ident, enum_: &DataEnum) -> syn::Resu
.concat_str(#name)
};
metadata_expr.extend(variant_metadata(enum_)?);
metadata_expr.extend(quote! { .concat_str(#docstring) });
Ok(create_metadata_items("enum", &name, metadata_expr, None))
}

Expand Down Expand Up @@ -178,7 +185,13 @@ pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
.collect::<syn::Result<Vec<_>>>()?;

let name = ident_to_string(&v.ident);
let docstring = extract_docstring(&v.attrs)?;
let field_types = v.fields.iter().map(|f| &f.ty);
let field_docstrings = v.fields
.iter()
.map(|f| extract_docstring(&f.attrs))
.collect::<syn::Result<Vec<_>>>()?;

Ok(quote! {
.concat_str(#name)
.concat_value(#fields_len)
Expand All @@ -187,7 +200,9 @@ pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
.concat(<#field_types as ::uniffi::Lower<crate::UniFfiTag>>::TYPE_ID_META)
// field defaults not yet supported for enums
.concat_bool(false)
.concat_str(#field_docstrings)
)*
.concat_str(#docstring)
})
})
)
Expand Down
21 changes: 14 additions & 7 deletions uniffi_macros/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use syn::{
use crate::{
enum_::{rich_error_ffi_converter_impl, variant_metadata},
util::{
chain, create_metadata_items, derive_ffi_traits, either_attribute_arg, ident_to_string, kw,
mod_path, parse_comma_separated, tagged_impl_header, try_metadata_value_from_usize,
AttributeSliceExt, UniffiAttributeArgs,
chain, create_metadata_items, derive_ffi_traits, either_attribute_arg, extract_docstring,
ident_to_string, kw, mod_path, parse_comma_separated, tagged_impl_header,
try_metadata_value_from_usize, AttributeSliceExt, UniffiAttributeArgs,
},
};

Expand All @@ -30,13 +30,14 @@ pub fn expand_error(
}
};
let ident = &input.ident;
let docstring = extract_docstring(&input.attrs)?;
let mut attr: ErrorAttr = input.attrs.parse_uniffi_attr_args()?;
if let Some(attr_from_udl_mode) = attr_from_udl_mode {
attr = attr.merge(attr_from_udl_mode)?;
}
let ffi_converter_impl = error_ffi_converter_impl(ident, &enum_, &attr, udl_mode);
let meta_static_var = (!udl_mode).then(|| {
error_meta_static_var(ident, &enum_, attr.flat.is_some())
error_meta_static_var(ident, docstring, &enum_, attr.flat.is_some())
.unwrap_or_else(syn::Error::into_compile_error)
});

Expand Down Expand Up @@ -192,6 +193,7 @@ fn flat_error_ffi_converter_impl(

pub(crate) fn error_meta_static_var(
ident: &Ident,
docstring: String,
enum_: &DataEnum,
flat: bool,
) -> syn::Result<TokenStream> {
Expand All @@ -210,18 +212,23 @@ pub(crate) fn error_meta_static_var(
} else {
metadata_expr.extend(variant_metadata(enum_)?);
}
metadata_expr.extend(quote! { .concat_str(#docstring) });
Ok(create_metadata_items("error", &name, metadata_expr, None))
}

pub fn flat_error_variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
let variants_len =
try_metadata_value_from_usize(enum_.variants.len(), "UniFFI limits enums to 256 variants")?;
Ok(std::iter::once(quote! { .concat_value(#variants_len) })
std::iter::once(Ok(quote! { .concat_value(#variants_len) }))
.chain(enum_.variants.iter().map(|v| {
let name = ident_to_string(&v.ident);
quote! { .concat_str(#name) }
let docstring = extract_docstring(&v.attrs)?;
Ok(quote! {
.concat_str(#name)
.concat_str(#docstring)
})
}))
.collect())
.collect()
}

#[derive(Default)]
Expand Down
7 changes: 5 additions & 2 deletions uniffi_macros/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,21 @@ pub(crate) fn expand_export(
items,
self_ident,
callback_interface: false,
..
} => trait_interface::gen_trait_scaffolding(&mod_path, args, self_ident, items, udl_mode),
ExportItem::Trait {
items,
self_ident,
callback_interface: true,
docstring,
} => {
let trait_name = ident_to_string(&self_ident);
let trait_impl_ident = callback_interface::trait_impl_ident(&trait_name);
let trait_impl = callback_interface::trait_impl(&mod_path, &self_ident, &items)
.unwrap_or_else(|e| e.into_compile_error());
let metadata_items = callback_interface::metadata_items(&self_ident, &items, &mod_path)
.unwrap_or_else(|e| vec![e.into_compile_error()]);
let metadata_items =
callback_interface::metadata_items(&self_ident, &items, &mod_path, docstring)
.unwrap_or_else(|e| vec![e.into_compile_error()]);
let ffi_converter_tokens =
ffi_converter_callback_interface_impl(&self_ident, &trait_impl_ident, udl_mode);

Expand Down
23 changes: 13 additions & 10 deletions uniffi_macros/src/export/callback_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,18 +182,21 @@ pub(super) fn metadata_items(
self_ident: &Ident,
items: &[ImplItem],
module_path: &str,
docstring: Option<String>,
) -> syn::Result<Vec<TokenStream>> {
let trait_name = ident_to_string(self_ident);
let callback_interface_items = create_metadata_items(
"callback_interface",
&trait_name,
quote! {
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::CALLBACK_INTERFACE)
.concat_str(#module_path)
.concat_str(#trait_name)
},
None,
);

let mut metadata_expr = quote! {
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::CALLBACK_INTERFACE)
.concat_str(#module_path)
.concat_str(#trait_name)
};
if let Some(docstring) = docstring {
metadata_expr.extend(quote! { .concat_str(#docstring) })
}

let callback_interface_items =
create_metadata_items("callback_interface", &trait_name, metadata_expr, None);

iter::once(Ok(callback_interface_items))
.chain(items.iter().map(|item| match item {
Expand Down
21 changes: 19 additions & 2 deletions uniffi_macros/src/export/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use proc_macro2::{Ident, Span};
use quote::ToTokens;

use super::attributes::{ExportAttributeArguments, ExportedImplFnAttributes};
use crate::util::extract_docstring;
use uniffi_meta::UniffiTraitDiscriminants;

pub(super) enum ExportItem {
Expand All @@ -21,6 +22,7 @@ pub(super) enum ExportItem {
self_ident: Ident,
items: Vec<ImplItem>,
callback_interface: bool,
docstring: Option<String>,
},
Struct {
self_ident: Ident,
Expand All @@ -32,7 +34,8 @@ impl ExportItem {
pub fn new(item: syn::Item, args: &ExportAttributeArguments) -> syn::Result<Self> {
match item {
syn::Item::Fn(item) => {
let sig = FnSignature::new_function(item.sig)?;
let docstring = extract_docstring(&item.attrs)?;
let sig = FnSignature::new_function(item.sig, docstring)?;
Ok(Self::Function { sig })
}
syn::Item::Impl(item) => Self::from_impl(item, args.constructor.is_some()),
Expand Down Expand Up @@ -88,14 +91,20 @@ impl ExportItem {
}
};

let docstring = extract_docstring(&impl_fn.attrs)?;
let attrs = ExportedImplFnAttributes::new(&impl_fn.attrs)?;
let item = if force_constructor || attrs.constructor {
ImplItem::Constructor(FnSignature::new_constructor(
self_ident.clone(),
impl_fn.sig,
docstring,
)?)
} else {
ImplItem::Method(FnSignature::new_method(self_ident.clone(), impl_fn.sig)?)
ImplItem::Method(FnSignature::new_method(
self_ident.clone(),
impl_fn.sig,
docstring,
)?)
};

Ok(item)
Expand All @@ -117,6 +126,11 @@ impl ExportItem {
}

let self_ident = item.ident.to_owned();
let docstring = if callback_interface {
Some(extract_docstring(&item.attrs)?)
} else {
None
};
let items = item
.items
.into_iter()
Expand All @@ -132,6 +146,7 @@ impl ExportItem {
}
};

let docstring = extract_docstring(&tim.attrs)?;
let attrs = ExportedImplFnAttributes::new(&tim.attrs)?;
let item = if attrs.constructor {
return Err(syn::Error::new_spanned(
Expand All @@ -143,6 +158,7 @@ impl ExportItem {
self_ident.clone(),
tim.sig,
i as u32,
docstring,
)?)
};

Expand All @@ -154,6 +170,7 @@ impl ExportItem {
items,
self_ident,
callback_interface,
docstring,
})
}

Expand Down
2 changes: 1 addition & 1 deletion uniffi_macros/src/export/trait_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub(super) fn gen_trait_scaffolding(
.collect::<syn::Result<_>>()?;

let meta_static_var = (!udl_mode).then(|| {
interface_meta_static_var(&self_ident, true, mod_path)
interface_meta_static_var(&self_ident, true, mod_path, None)
.unwrap_or_else(syn::Error::into_compile_error)
});
let ffi_converter_tokens = ffi_converter(mod_path, &self_ident, false);
Expand Down
8 changes: 6 additions & 2 deletions uniffi_macros/src/export/utrait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use syn::ext::IdentExt;

use super::{attributes::ExportAttributeArguments, gen_ffi_function};
use crate::fnsig::FnSignature;
use crate::util::extract_docstring;
use uniffi_meta::UniffiTraitDiscriminants;

pub(crate) fn expand_uniffi_trait_export(
Expand Down Expand Up @@ -157,12 +158,15 @@ fn process_uniffi_trait_method(
unreachable!()
};

let docstring = extract_docstring(&item.attrs)?;

let ffi_func = gen_ffi_function(
&FnSignature::new_method(self_ident.clone(), item.sig.clone())?,
&FnSignature::new_method(self_ident.clone(), item.sig.clone(), docstring.clone())?,
&ExportAttributeArguments::default(),
udl_mode,
)?;
// metadata for the method, which will be packed inside metadata for the trait.
let method_meta = FnSignature::new_method(self_ident.clone(), item.sig)?.metadata_expr()?;
let method_meta =
FnSignature::new_method(self_ident.clone(), item.sig, docstring)?.metadata_expr()?;
Ok((ffi_func, method_meta))
}
Loading

0 comments on commit 143b0b7

Please sign in to comment.