Skip to content

Commit

Permalink
Merge pull request #1509 from matrix-org/jplatte/rhash
Browse files Browse the repository at this point in the history
Post-#1469 cleanup
  • Loading branch information
bendk authored Apr 6, 2023
2 parents 0a1d3b2 + 9fe221c commit 58f4f5a
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 145 deletions.
1 change: 0 additions & 1 deletion uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ impl<'a> SwiftWrapper<'a> {
pub fn initialization_fns(&self) -> Vec<String> {
self.ci
.iter_types()
.into_iter()
.filter_map(|t| t.initialization_fn(&SwiftCodeOracle))
.collect()
}
Expand Down
108 changes: 24 additions & 84 deletions uniffi_bindgen/src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub use record::{Field, Record};

pub mod ffi;
pub use ffi::{FfiArgument, FfiFunction, FfiType};
use uniffi_meta::{FnMetadata, MethodMetadata, ObjectMetadata};
use uniffi_meta::{MethodMetadata, ObjectMetadata};

// This needs to match the minor version of the `uniffi` crate. See
// `docs/uniffi-versioning.md` for details.
Expand Down Expand Up @@ -539,6 +539,11 @@ impl ComponentInterface {
pub(super) fn add_enum_definition(&mut self, defn: Enum) -> Result<()> {
match self.enums.entry(defn.name().to_owned()) {
Entry::Vacant(v) => {
for variant in defn.variants() {
for field in variant.fields() {
self.types.add_known_type(field.type_())?;
}
}
v.insert(defn);
}
Entry::Occupied(o) => {
Expand All @@ -561,6 +566,9 @@ impl ComponentInterface {
pub(super) fn add_record_definition(&mut self, defn: Record) -> Result<()> {
match self.records.entry(defn.name().to_owned()) {
Entry::Vacant(v) => {
for field in defn.fields() {
self.types.add_known_type(field.type_())?;
}
v.insert(defn);
}
Entry::Occupied(o) => {
Expand All @@ -579,7 +587,15 @@ impl ComponentInterface {
Ok(())
}

fn add_function_impl(&mut self, defn: Function) -> Result<()> {
/// Called by `APIBuilder` impls to add a newly-parsed function definition to the `ComponentInterface`.
pub(super) fn add_function_definition(&mut self, defn: Function) -> Result<()> {
for arg in &defn.arguments {
self.types.add_known_type(&arg.type_)?;
}
if let Some(ty) = &defn.return_type {
self.types.add_known_type(ty)?;
}

// Since functions are not a first-class type, we have to check for duplicates here
// rather than relying on the type-finding pass to catch them.
if self.functions.iter().any(|f| f.name == defn.name) {
Expand All @@ -593,25 +609,19 @@ impl ComponentInterface {
Ok(())
}

/// Called by `APIBuilder` impls to add a newly-parsed function definition to the `ComponentInterface`.
fn add_function_definition(&mut self, defn: Function) -> Result<()> {
pub(super) fn add_method_meta(&mut self, meta: MethodMetadata) -> Result<()> {
let object = get_or_insert_object(&mut self.objects, &meta.self_name);
let defn: Method = meta.into();

for arg in &defn.arguments {
self.types.add_known_type(&arg.type_)?;
}
if let Some(ty) = &defn.return_type {
self.types.add_known_type(ty)?;
}
object.methods.push(defn);

self.add_function_impl(defn)
}

pub(super) fn add_fn_meta(&mut self, meta: FnMetadata) -> Result<()> {
self.add_function_impl(meta.into())
}

pub(super) fn add_method_meta(&mut self, meta: MethodMetadata) {
let object = get_or_insert_object(&mut self.objects, &meta.self_name);
object.methods.push(meta.into())
Ok(())
}

pub(super) fn add_object_free_fn(&mut self, meta: ObjectMetadata) {
Expand Down Expand Up @@ -653,76 +663,6 @@ impl ComponentInterface {
Ok(())
}

/// Resolve unresolved types within proc-macro function / method signatures.
pub fn resolve_types(&mut self) -> Result<()> {
fn handle_unresolved_in(
ty: &mut Type,
f: impl Fn(&str) -> Result<Type> + Clone,
) -> Result<()> {
match ty {
Type::Optional(inner) => {
handle_unresolved_in(inner, f)?;
}
Type::Sequence(inner) => {
handle_unresolved_in(inner, f)?;
}
Type::Map(k, v) => {
handle_unresolved_in(k, f.clone())?;
handle_unresolved_in(v, f)?;
}
_ => {}
}

Ok(())
}

let fn_sig_types = self.functions.iter_mut().flat_map(|fun| {
fun.arguments
.iter_mut()
.map(|arg| &mut arg.type_)
.chain(&mut fun.return_type)
});
let method_sig_types = self.objects.iter_mut().flat_map(|obj| {
obj.methods.iter_mut().flat_map(|m| {
m.arguments
.iter_mut()
.map(|arg| &mut arg.type_)
.chain(&mut m.return_type)
})
});

let record_fields_types = self
.records
.values_mut()
.flat_map(|r| r.fields.iter_mut().map(|f| &mut f.type_));
let enum_fields_types = self.enums.values_mut().flat_map(|e| {
e.variants
.iter_mut()
.flat_map(|r| r.fields.iter_mut().map(|f| &mut f.type_))
});

let possibly_unresolved_types = fn_sig_types
.chain(method_sig_types)
.chain(record_fields_types)
.chain(enum_fields_types);

for ty in possibly_unresolved_types {
handle_unresolved_in(ty, |unresolved_ty_name| {
match self.types.get_type_definition(unresolved_ty_name) {
Some(def) => Ok(def),
None => bail!("Failed to resolve type `{unresolved_ty_name}`"),
}
})?;

// The proc-macro scanning metadata code doesn't add known types
// when they could contain unresolved types, so we have to do it
// here after replacing unresolveds.
self.types.add_known_type(ty)?;
}

Ok(())
}

/// Perform global consistency checks on the declared interface.
///
/// This method checks for consistency problems in the declared interface
Expand Down
5 changes: 2 additions & 3 deletions uniffi_bindgen/src/macro_metadata/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ pub fn add_to_ci(
match item {
Metadata::Namespace(_) => unreachable!(),
Metadata::Func(meta) => {
iface.add_fn_meta(meta)?;
iface.add_function_definition(meta.into())?;
}
Metadata::Method(meta) => {
iface.add_method_meta(meta);
iface.add_method_meta(meta)?;
}
Metadata::Record(meta) => {
let ty = Type::Record(meta.name.clone());
Expand Down Expand Up @@ -94,7 +94,6 @@ pub fn add_to_ci(
}
}

iface.resolve_types().context("Failed to resolve types")?;
iface
.derive_ffi_funcs()
.context("Failed to derive FFI functions")?;
Expand Down
25 changes: 10 additions & 15 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, Path};

use crate::util::{
create_metadata_items, mod_path, tagged_impl_header, try_metadata_value_from_usize,
try_read_field, type_name, AttributeSliceExt, CommonAttr,
create_metadata_items, ident_to_string, mod_path, tagged_impl_header,
try_metadata_value_from_usize, try_read_field, AttributeSliceExt, CommonAttr,
};

pub fn expand_enum(input: DeriveInput) -> syn::Result<TokenStream> {
Expand Down Expand Up @@ -74,7 +74,7 @@ fn enum_or_error_ffi_converter_impl(
tag: Option<&Path>,
metadata_type_code: TokenStream,
) -> TokenStream {
let name = ident.to_string();
let name = ident_to_string(ident);
let impl_spec = tagged_impl_header("FfiConverter", ident, tag);
let write_match_arms = enum_.variants.iter().enumerate().map(|(i, v)| {
let v_ident = &v.ident;
Expand Down Expand Up @@ -142,21 +142,16 @@ fn write_field(f: &Field) -> TokenStream {
}

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

let mut metadata_expr = quote! {
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::ENUM)
.concat_str(#module_path)
.concat_str(#name)
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::ENUM)
.concat_str(#module_path)
.concat_str(#name)
};
metadata_expr.extend(variant_metadata(enum_)?);
Ok(create_metadata_items(
"enum",
&ident.to_string(),
metadata_expr,
None,
))
Ok(create_metadata_items("enum", &name, metadata_expr, None))
}

pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
Expand All @@ -183,11 +178,11 @@ pub fn variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStream>> {
"UniFFI only supports enum variants with named fields (or no fields at all)",
)
)
.map(|i| i.to_string())
.map(ident_to_string)
})
.collect::<syn::Result<Vec<_>>>()?;

let name = type_name(&v.ident);
let name = ident_to_string(&v.ident);
let field_types = v.fields.iter().map(|f| &f.ty);
Ok(quote! {
.concat_str(#name)
Expand Down
12 changes: 6 additions & 6 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, either_attribute_arg, mod_path, parse_comma_separated,
tagged_impl_header, try_metadata_value_from_usize, type_name, AttributeSliceExt,
UniffiAttribute,
chain, create_metadata_items, either_attribute_arg, ident_to_string, mod_path,
parse_comma_separated, tagged_impl_header, try_metadata_value_from_usize,
AttributeSliceExt, UniffiAttribute,
},
};

Expand Down Expand Up @@ -85,7 +85,7 @@ fn flat_error_ffi_converter_impl(
tag: Option<&Path>,
implement_try_read: bool,
) -> TokenStream {
let name = ident.to_string();
let name = ident_to_string(ident);
let impl_spec = tagged_impl_header("FfiConverter", ident, tag);

let write_impl = {
Expand Down Expand Up @@ -151,7 +151,7 @@ pub(crate) fn error_meta_static_var(
enum_: &DataEnum,
flat: bool,
) -> syn::Result<TokenStream> {
let name = ident.to_string();
let name = ident_to_string(ident);
let module_path = mod_path()?;
let flat_code = u8::from(flat);
let mut metadata_expr = quote! {
Expand All @@ -173,7 +173,7 @@ pub fn flat_error_variant_metadata(enum_: &DataEnum) -> syn::Result<Vec<TokenStr
try_metadata_value_from_usize(enum_.variants.len(), "UniFFI limits enums to 256 variants")?;
Ok(std::iter::once(quote! { .concat_value(#variants_len) })
.chain(enum_.variants.iter().map(|v| {
let name = type_name(&v.ident);
let name = ident_to_string(&v.ident);
quote! { .concat_str(#name) }
}))
.collect())
Expand Down
20 changes: 10 additions & 10 deletions uniffi_macros/src/export/scaffolding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@

use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::{ext::IdentExt, spanned::Spanned, FnArg, Pat};
use syn::{spanned::Spanned, FnArg, Pat};

use super::{AsyncRuntime, ExportAttributeArguments, Signature};
use crate::util::{create_metadata_items, try_metadata_value_from_usize, type_name};
use crate::util::{create_metadata_items, ident_to_string, try_metadata_value_from_usize};

pub(super) fn gen_fn_scaffolding(
sig: &Signature,
mod_path: &str,
arguments: &ExportAttributeArguments,
) -> syn::Result<TokenStream> {
let name = &sig.ident;
let name_s = name.to_string();
let name_s = ident_to_string(name);

let ffi_ident = Ident::new(
&uniffi_meta::fn_ffi_symbol_name(mod_path, &name_s),
Expand All @@ -42,10 +42,10 @@ pub(super) fn gen_method_scaffolding(
arguments: &ExportAttributeArguments,
) -> syn::Result<TokenStream> {
let ident = &sig.ident;
let name_s = ident.unraw().to_string();
let name_s = ident_to_string(ident);

let ffi_ident = Ident::new(
&uniffi_meta::method_fn_symbol_name(mod_path, &self_ident.unraw().to_string(), &name_s),
&uniffi_meta::method_fn_symbol_name(mod_path, &ident_to_string(self_ident), &name_s),
Span::call_site(),
);

Expand Down Expand Up @@ -159,7 +159,7 @@ impl ScaffoldingBits {
self.collect_param_receiver_error(i, receiver_error_msg);
continue;
}
Pat::Ident(i) => Some(i.ident.to_string()),
Pat::Ident(i) => Some(ident_to_string(&i.ident)),
_ => None,
};

Expand Down Expand Up @@ -215,7 +215,7 @@ impl ScaffoldingBits {
sig: &Signature,
mod_path: &str,
) -> syn::Result<TokenStream> {
let name = type_name(&sig.ident);
let name = ident_to_string(&sig.ident);
let return_ty = &sig.output;
let is_async = sig.is_async;
let args_len = try_metadata_value_from_usize(
Expand Down Expand Up @@ -247,8 +247,8 @@ impl ScaffoldingBits {
sig: &Signature,
mod_path: &str,
) -> syn::Result<TokenStream> {
let object_name = type_name(self_ident);
let name = type_name(&sig.ident);
let object_name = ident_to_string(self_ident);
let name = ident_to_string(&sig.ident);
let return_ty = &sig.output;
let is_async = sig.is_async;
let args_len = try_metadata_value_from_usize(
Expand Down Expand Up @@ -286,7 +286,7 @@ fn gen_ffi_function(
bits: &ScaffoldingBits,
arguments: &ExportAttributeArguments,
) -> TokenStream {
let name = sig.ident.to_string();
let name = ident_to_string(&sig.ident);
let rust_fn_call = bits.rust_fn_call();
let fn_params = &bits.params;
let return_ty = &sig.output;
Expand Down
5 changes: 3 additions & 2 deletions uniffi_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![cfg_attr(feature = "nightly", feature(proc_macro_expand))]
#![warn(rust_2018_idioms, unused_qualifications)]

//! Macros for `uniffi`.
//!
Expand Down Expand Up @@ -179,7 +180,7 @@ pub fn ffi_converter_interface(attrs: TokenStream, input: TokenStream) -> TokenS
///
#[proc_macro]
pub fn include_scaffolding(component_name: TokenStream) -> TokenStream {
let name = syn::parse_macro_input!(component_name as syn::LitStr);
let name = syn::parse_macro_input!(component_name as LitStr);
if std::env::var("OUT_DIR").is_err() {
quote! {
compile_error!("This macro assumes the crate has a build.rs script, but $OUT_DIR is not present");
Expand All @@ -204,7 +205,7 @@ pub fn include_scaffolding(component_name: TokenStream) -> TokenStream {
///
#[proc_macro]
pub fn generate_and_include_scaffolding(udl_file: TokenStream) -> TokenStream {
let udl_file = syn::parse_macro_input!(udl_file as syn::LitStr);
let udl_file = syn::parse_macro_input!(udl_file as LitStr);
let udl_file_string = udl_file.value();
let udl_file_path = Utf8Path::new(&udl_file_string);
if std::env::var("OUT_DIR").is_err() {
Expand Down
Loading

0 comments on commit 58f4f5a

Please sign in to comment.