diff options
-rw-r--r-- | src/codegen/mod.rs | 38 | ||||
-rw-r--r-- | src/ir/objc.rs | 18 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-3.8/objc_template.rs | 14 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-3.9/objc_template.rs | 14 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-4/objc_template.rs | 14 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-5/objc_template.rs | 32 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-9/objc_template.rs | 14 | ||||
-rw-r--r-- | tests/headers/objc_template.h | 4 |
8 files changed, 123 insertions, 25 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f5e898ad..5ac8dc11 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3728,18 +3728,44 @@ impl CodeGenerator for ObjCInterface { let trait_name = ctx.rust_ident(self.rust_name()); - let trait_block = quote! { - pub trait #trait_name { - #( #trait_items )* + let trait_block = if self.is_template() { + let template_names: Vec<Ident> = self + .template_names + .iter() + .map(|g| ctx.rust_ident(g)) + .collect(); + quote! { + pub trait #trait_name <#(#template_names),*>{ + #( #trait_items )* + } + } + } else { + quote! { + pub trait #trait_name { + #( #trait_items )* + } } }; let ty_for_impl = quote! { id }; - let impl_block = quote! { - impl #trait_name for #ty_for_impl { - #( #impl_items )* + let impl_block = if self.is_template() { + let template_names: Vec<Ident> = self + .template_names + .iter() + .map(|g| ctx.rust_ident(g)) + .collect(); + quote! { + impl <#(#template_names :'static),*> #trait_name <#(#template_names),*> for #ty_for_impl { + #( #impl_items )* + } + } + } else { + quote! { + impl #trait_name for #ty_for_impl { + #( #impl_items )* + } } }; diff --git a/src/ir/objc.rs b/src/ir/objc.rs index 0b75e55a..1b2bd5de 100644 --- a/src/ir/objc.rs +++ b/src/ir/objc.rs @@ -12,6 +12,7 @@ use clang_sys::CXCursor_ObjCClassRef; use clang_sys::CXCursor_ObjCInstanceMethodDecl; use clang_sys::CXCursor_ObjCProtocolDecl; use clang_sys::CXCursor_ObjCProtocolRef; +use clang_sys::CXCursor_TemplateTypeParameter; use proc_macro2::{Ident, Span, TokenStream}; /// Objective C interface as used in TypeKind @@ -27,6 +28,9 @@ pub struct ObjCInterface { is_protocol: bool, + /// The list of template names almost always, ObjectType or KeyType + pub template_names: Vec<String>, + conforms_to: Vec<ItemId>, /// List of the methods defined in this interfae @@ -58,6 +62,7 @@ impl ObjCInterface { name: name.to_owned(), category: None, is_protocol: false, + template_names: Vec::new(), conforms_to: Vec::new(), methods: Vec::new(), class_methods: Vec::new(), @@ -85,6 +90,11 @@ impl ObjCInterface { } } + /// Is this a template interface? + pub fn is_template(&self) -> bool { + !self.template_names.is_empty() + } + /// List of the methods defined in this interface pub fn methods(&self) -> &Vec<ObjCMethod> { &self.methods @@ -154,6 +164,10 @@ impl ObjCInterface { let method = ObjCMethod::new(&name, signature, is_class_method); interface.add_method(method); } + CXCursor_TemplateTypeParameter => { + let name = c.spelling(); + interface.template_names.push(name); + } _ => {} } CXChildVisit_Continue @@ -183,8 +197,8 @@ impl ObjCMethod { ObjCMethod { name: name.to_owned(), rust_name: rust_name.to_owned(), - signature: signature, - is_class_method: is_class_method, + signature, + is_class_method, } } diff --git a/tests/expectations/tests/libclang-3.8/objc_template.rs b/tests/expectations/tests/libclang-3.8/objc_template.rs index c5d16ae1..1a6f8ec3 100644 --- a/tests/expectations/tests/libclang-3.8/objc_template.rs +++ b/tests/expectations/tests/libclang-3.8/objc_template.rs @@ -8,11 +8,21 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -pub trait Foo { +pub trait Foo<ObjectType> { unsafe fn get(self) -> id; } -impl Foo for id { +impl<ObjectType: 'static> Foo<ObjectType> for id { unsafe fn get(self) -> id { msg_send!(self, get) } } +pub trait FooMultiGeneric<KeyType, ObjectType> { + unsafe fn objectForKey_(self, key: id) -> id; +} +impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType> + for id +{ + unsafe fn objectForKey_(self, key: id) -> id { + msg_send!(self, objectForKey: key) + } +} diff --git a/tests/expectations/tests/libclang-3.9/objc_template.rs b/tests/expectations/tests/libclang-3.9/objc_template.rs index c5d16ae1..1a6f8ec3 100644 --- a/tests/expectations/tests/libclang-3.9/objc_template.rs +++ b/tests/expectations/tests/libclang-3.9/objc_template.rs @@ -8,11 +8,21 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -pub trait Foo { +pub trait Foo<ObjectType> { unsafe fn get(self) -> id; } -impl Foo for id { +impl<ObjectType: 'static> Foo<ObjectType> for id { unsafe fn get(self) -> id { msg_send!(self, get) } } +pub trait FooMultiGeneric<KeyType, ObjectType> { + unsafe fn objectForKey_(self, key: id) -> id; +} +impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType> + for id +{ + unsafe fn objectForKey_(self, key: id) -> id { + msg_send!(self, objectForKey: key) + } +} diff --git a/tests/expectations/tests/libclang-4/objc_template.rs b/tests/expectations/tests/libclang-4/objc_template.rs index 06a9a55f..1aaab177 100644 --- a/tests/expectations/tests/libclang-4/objc_template.rs +++ b/tests/expectations/tests/libclang-4/objc_template.rs @@ -9,10 +9,20 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -pub trait Foo { +pub trait Foo<ObjectType> { unsafe fn get(self) -> *mut ObjectType; } -impl Foo for id { +impl<ObjectType: 'static> Foo<ObjectType> for id { unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) } } +pub trait FooMultiGeneric<KeyType, ObjectType> { + unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType; +} +impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType> + for id +{ + unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType { + msg_send!(self, objectForKey: key) + } +} diff --git a/tests/expectations/tests/libclang-5/objc_template.rs b/tests/expectations/tests/libclang-5/objc_template.rs index 06a9a55f..23a23695 100644 --- a/tests/expectations/tests/libclang-5/objc_template.rs +++ b/tests/expectations/tests/libclang-5/objc_template.rs @@ -1,18 +1,32 @@ /* automatically generated by rust-bindgen */ - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - -#![cfg(target_os="macos")] +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] +#![cfg(target_os = "macos")] #[macro_use] extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -pub trait Foo { - unsafe fn get(self) - -> *mut ObjectType; +pub trait Foo<ObjectType> { + unsafe fn get(self) -> *mut ObjectType; +} +impl<ObjectType: 'static> Foo<ObjectType> for id { + unsafe fn get(self) -> *mut ObjectType { + msg_send!(self, get) + } +} +pub trait FooMultiGeneric<KeyType, ObjectType> { + unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType; } -impl Foo for id { - unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) } +impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType> + for id +{ + unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType { + msg_send!(self, objectForKey: key) + } } diff --git a/tests/expectations/tests/libclang-9/objc_template.rs b/tests/expectations/tests/libclang-9/objc_template.rs index 84eef1ef..089f0398 100644 --- a/tests/expectations/tests/libclang-9/objc_template.rs +++ b/tests/expectations/tests/libclang-9/objc_template.rs @@ -12,11 +12,21 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -pub trait Foo { +pub trait Foo<ObjectType> { unsafe fn get(self) -> u64; } -impl Foo for id { +impl<ObjectType: 'static> Foo<ObjectType> for id { unsafe fn get(self) -> u64 { msg_send!(self, get) } } +pub trait FooMultiGeneric<KeyType, ObjectType> { + unsafe fn objectForKey_(self, key: u64) -> u64; +} +impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType> + for id +{ + unsafe fn objectForKey_(self, key: u64) -> u64 { + msg_send!(self, objectForKey: key) + } +} diff --git a/tests/headers/objc_template.h b/tests/headers/objc_template.h index 62398eb7..a4d0055c 100644 --- a/tests/headers/objc_template.h +++ b/tests/headers/objc_template.h @@ -4,3 +4,7 @@ @interface Foo<__covariant ObjectType> - (ObjectType)get; @end + +@interface FooMultiGeneric<__covariant KeyType, __covariant ObjectType> +- (nullable ObjectType)objectForKey:(KeyType)key; +@end |