summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs38
-rw-r--r--src/ir/objc.rs18
-rw-r--r--tests/expectations/tests/libclang-3.8/objc_template.rs14
-rw-r--r--tests/expectations/tests/libclang-3.9/objc_template.rs14
-rw-r--r--tests/expectations/tests/libclang-4/objc_template.rs14
-rw-r--r--tests/expectations/tests/libclang-5/objc_template.rs32
-rw-r--r--tests/expectations/tests/libclang-9/objc_template.rs14
-rw-r--r--tests/headers/objc_template.h4
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