summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs127
-rw-r--r--src/ir/objc.rs21
-rw-r--r--tests/expectations/tests/libclang-3.8/objc_template.rs53
-rw-r--r--tests/expectations/tests/libclang-3.9/objc_template.rs53
-rw-r--r--tests/expectations/tests/libclang-4/objc_template.rs56
-rw-r--r--tests/expectations/tests/libclang-5/objc_template.rs53
-rw-r--r--tests/expectations/tests/libclang-9/objc_template.rs53
-rw-r--r--tests/expectations/tests/objc_category.rs35
-rw-r--r--tests/expectations/tests/objc_class.rs26
-rw-r--r--tests/expectations/tests/objc_class_method.rs84
-rw-r--r--tests/expectations/tests/objc_interface.rs22
-rw-r--r--tests/expectations/tests/objc_interface_type.rs23
-rw-r--r--tests/expectations/tests/objc_method.rs70
-rw-r--r--tests/expectations/tests/objc_method_clash.rs35
-rw-r--r--tests/expectations/tests/objc_property_fnptr.rs42
-rw-r--r--tests/expectations/tests/objc_protocol.rs23
-rw-r--r--tests/expectations/tests/objc_whitelist.rs36
17 files changed, 557 insertions, 255 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 9a3b10d7..2be9794b 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -3394,9 +3394,12 @@ impl TryToRustTy for Type {
TypeKind::ObjCSel => Ok(quote! {
objc::runtime::Sel
}),
- TypeKind::ObjCId | TypeKind::ObjCInterface(..) => Ok(quote! {
+ TypeKind::ObjCId => Ok(quote! {
id
}),
+ TypeKind::ObjCInterface(..) => Ok(quote! {
+ objc::runtime::Object
+ }),
ref u @ TypeKind::UnresolvedTypeRef(..) => {
unreachable!("Should have been resolved after parsing {:?}!", u)
}
@@ -3644,7 +3647,7 @@ fn objc_method_codegen(
method: &ObjCMethod,
class_name: Option<&str>,
prefix: &str,
-) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) {
+) -> proc_macro2::TokenStream {
let signature = method.signature();
let fn_args = utils::fnsig_arguments(ctx, signature);
let fn_ret = utils::fnsig_return_ty(ctx, signature);
@@ -3665,15 +3668,13 @@ fn objc_method_codegen(
let methods_and_args = method.format_method_call(&fn_args);
let body = if method.is_class_method() {
- let class_name = class_name
- .expect("Generating a class method without class name?")
- .to_owned();
- let expect_msg = proc_macro2::Literal::string(&format!(
- "Couldn't find {}",
+ let class_name = ctx.rust_ident(
class_name
- ));
+ .expect("Generating a class method without class name?")
+ .to_owned(),
+ );
quote! {
- msg_send!(objc::runtime::Class::get(#class_name).expect(#expect_msg), #methods_and_args)
+ msg_send!(class!(#class_name), #methods_and_args)
}
} else {
quote! {
@@ -3684,16 +3685,11 @@ fn objc_method_codegen(
let method_name =
ctx.rust_ident(format!("{}{}", prefix, method.rust_name()));
- (
- quote! {
- unsafe fn #method_name #sig {
- #body
- }
- },
- quote! {
- unsafe fn #method_name #sig ;
- },
- )
+ quote! {
+ unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
+ #body
+ }
+ }
}
impl CodeGenerator for ObjCInterface {
@@ -3708,13 +3704,10 @@ impl CodeGenerator for ObjCInterface {
debug_assert!(item.is_enabled_for_codegen(ctx));
let mut impl_items = vec![];
- let mut trait_items = vec![];
for method in self.methods() {
- let (impl_item, trait_item) =
- objc_method_codegen(ctx, method, None, "");
+ let impl_item = objc_method_codegen(ctx, method, None, "");
impl_items.push(impl_item);
- trait_items.push(trait_item)
}
let instance_method_names: Vec<_> =
@@ -3724,61 +3717,97 @@ impl CodeGenerator for ObjCInterface {
let ambiquity =
instance_method_names.contains(&class_method.rust_name());
let prefix = if ambiquity { "class_" } else { "" };
- let (impl_item, trait_item) = objc_method_codegen(
+ let impl_item = objc_method_codegen(
ctx,
class_method,
Some(self.name()),
prefix,
);
impl_items.push(impl_item);
- trait_items.push(trait_item)
}
let trait_name = ctx.rust_ident(self.rust_name());
-
+ let trait_constraints = quote! {
+ Sized + std::ops::Deref
+ };
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 )*
+ pub trait #trait_name <#(#template_names),*> : #trait_constraints {
+ #( #impl_items )*
}
}
} else {
quote! {
- pub trait #trait_name {
- #( #trait_items )*
+ pub trait #trait_name : #trait_constraints {
+ #( #impl_items )*
}
}
};
- let ty_for_impl = quote! {
- id
- };
- 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 )*
+ let class_name = ctx.rust_ident(self.name());
+ if !self.is_category() && !self.is_protocol() {
+ let struct_block = quote! {
+ #[repr(transparent)]
+ #[derive(Clone, Copy)]
+ pub struct #class_name(pub id);
+ impl std::ops::Deref for #class_name {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe {
+ &*self.0
+ }
+ }
}
- }
- } else {
- quote! {
- impl #trait_name for #ty_for_impl {
- #( #impl_items )*
+ unsafe impl objc::Message for #class_name { }
+ impl #class_name {
+ pub fn alloc() -> Self {
+ Self(unsafe {
+ msg_send!(objc::class!(#class_name), alloc)
+ })
+ }
}
+ };
+ result.push(struct_block);
+ for protocol_id in self.conforms_to.iter() {
+ let protocol_name = ctx.rust_ident(
+ ctx.resolve_type(protocol_id.expect_type_id(ctx))
+ .name()
+ .unwrap(),
+ );
+ let impl_trait = quote! {
+ impl #protocol_name for #class_name { }
+ };
+ result.push(impl_trait);
}
- };
+ }
+
+ if !self.is_protocol() {
+ 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 #class_name {
+ }
+ }
+ } else {
+ quote! {
+ impl #trait_name for #class_name {
+ }
+ }
+ };
+ result.push(impl_block);
+ }
result.push(trait_block);
- result.push(impl_block);
result.saw_objc();
}
}
diff --git a/src/ir/objc.rs b/src/ir/objc.rs
index cfbf3dd0..ba650d57 100644
--- a/src/ir/objc.rs
+++ b/src/ir/objc.rs
@@ -31,7 +31,8 @@ pub struct ObjCInterface {
/// The list of template names almost always, ObjectType or KeyType
pub template_names: Vec<String>,
- conforms_to: Vec<ItemId>,
+ /// The list of protocols that this interface conforms to.
+ pub conforms_to: Vec<ItemId>,
/// List of the methods defined in this interfae
methods: Vec<ObjCMethod>,
@@ -77,15 +78,15 @@ impl ObjCInterface {
/// Formats the name for rust
/// Can be like NSObject, but with categories might be like NSObject_NSCoderMethods
- /// and protocols are like protocol_NSObject
+ /// and protocols are like PNSObject
pub fn rust_name(&self) -> String {
if let Some(ref cat) = self.category {
format!("{}_{}", self.name(), cat)
} else {
if self.is_protocol {
- format!("protocol_{}", self.name())
+ format!("P{}", self.name())
} else {
- self.name().to_owned()
+ format!("I{}", self.name().to_owned())
}
}
}
@@ -100,6 +101,16 @@ impl ObjCInterface {
&self.methods
}
+ /// Is this a protocol?
+ pub fn is_protocol(&self) -> bool {
+ self.is_protocol
+ }
+
+ /// Is this a category?
+ pub fn is_category(&self) -> bool {
+ self.category.is_some()
+ }
+
/// List of the class methods defined in this interface
pub fn class_methods(&self) -> &Vec<ObjCMethod> {
&self.class_methods
@@ -129,7 +140,7 @@ impl ObjCInterface {
}
CXCursor_ObjCProtocolRef => {
// Gather protocols this interface conforms to
- let needle = format!("protocol_{}", c.spelling());
+ let needle = format!("P{}", c.spelling());
let items_map = ctx.items();
debug!("Interface {} conforms to {}, find the item", interface.name, needle);
diff --git a/tests/expectations/tests/libclang-3.8/objc_template.rs b/tests/expectations/tests/libclang-3.8/objc_template.rs
index 1a6f8ec3..23a6de90 100644
--- a/tests/expectations/tests/libclang-3.8/objc_template.rs
+++ b/tests/expectations/tests/libclang-3.8/objc_template.rs
@@ -8,21 +8,56 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo<ObjectType> {
- unsafe fn get(self) -> id;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl<ObjectType: 'static> Foo<ObjectType> for id {
- unsafe fn get(self) -> id {
+impl<ObjectType: 'static> IFoo<ObjectType> for Foo {}
+pub trait IFoo<ObjectType>: Sized + std::ops::Deref {
+ unsafe fn get(self) -> id
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, get)
}
}
-pub trait FooMultiGeneric<KeyType, ObjectType> {
- unsafe fn objectForKey_(self, key: id) -> id;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct FooMultiGeneric(pub id);
+impl std::ops::Deref for FooMultiGeneric {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for FooMultiGeneric {}
+impl FooMultiGeneric {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) })
+ }
+}
+impl<KeyType: 'static, ObjectType: 'static>
+ IFooMultiGeneric<KeyType, ObjectType> for FooMultiGeneric
+{
}
-impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
- for id
+pub trait IFooMultiGeneric<KeyType, ObjectType>:
+ Sized + std::ops::Deref
{
- unsafe fn objectForKey_(self, key: id) -> id {
+ unsafe fn objectForKey_(self, key: id) -> id
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
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 1a6f8ec3..23a6de90 100644
--- a/tests/expectations/tests/libclang-3.9/objc_template.rs
+++ b/tests/expectations/tests/libclang-3.9/objc_template.rs
@@ -8,21 +8,56 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo<ObjectType> {
- unsafe fn get(self) -> id;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl<ObjectType: 'static> Foo<ObjectType> for id {
- unsafe fn get(self) -> id {
+impl<ObjectType: 'static> IFoo<ObjectType> for Foo {}
+pub trait IFoo<ObjectType>: Sized + std::ops::Deref {
+ unsafe fn get(self) -> id
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, get)
}
}
-pub trait FooMultiGeneric<KeyType, ObjectType> {
- unsafe fn objectForKey_(self, key: id) -> id;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct FooMultiGeneric(pub id);
+impl std::ops::Deref for FooMultiGeneric {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for FooMultiGeneric {}
+impl FooMultiGeneric {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) })
+ }
+}
+impl<KeyType: 'static, ObjectType: 'static>
+ IFooMultiGeneric<KeyType, ObjectType> for FooMultiGeneric
+{
}
-impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
- for id
+pub trait IFooMultiGeneric<KeyType, ObjectType>:
+ Sized + std::ops::Deref
{
- unsafe fn objectForKey_(self, key: id) -> id {
+ unsafe fn objectForKey_(self, key: id) -> id
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
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 1aaab177..25276c00 100644
--- a/tests/expectations/tests/libclang-4/objc_template.rs
+++ b/tests/expectations/tests/libclang-4/objc_template.rs
@@ -9,20 +9,56 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo<ObjectType> {
- unsafe fn get(self)
- -> *mut ObjectType;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
}
-impl<ObjectType: 'static> Foo<ObjectType> for id {
- unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) }
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-pub trait FooMultiGeneric<KeyType, ObjectType> {
- unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType;
+impl<ObjectType: 'static> IFoo<ObjectType> for Foo {}
+pub trait IFoo<ObjectType>: Sized + std::ops::Deref {
+ unsafe fn get(self) -> *mut ObjectType
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(self , get)
+ }
+}
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct FooMultiGeneric(pub id);
+impl std::ops::Deref for FooMultiGeneric {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for FooMultiGeneric {}
+impl FooMultiGeneric {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) })
+ }
+}
+impl<KeyType: 'static, ObjectType: 'static>
+ IFooMultiGeneric<KeyType, ObjectType> for FooMultiGeneric
+{
}
-impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
- for id
+pub trait IFooMultiGeneric<KeyType, ObjectType>:
+ Sized + std::ops::Deref
{
- unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType {
+ unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
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 23a23695..b4c11704 100644
--- a/tests/expectations/tests/libclang-5/objc_template.rs
+++ b/tests/expectations/tests/libclang-5/objc_template.rs
@@ -12,21 +12,56 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo<ObjectType> {
- unsafe fn get(self) -> *mut ObjectType;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl<ObjectType: 'static> Foo<ObjectType> for id {
- unsafe fn get(self) -> *mut ObjectType {
+impl<ObjectType: 'static> IFoo<ObjectType> for Foo {}
+pub trait IFoo<ObjectType>: Sized + std::ops::Deref {
+ unsafe fn get(self) -> *mut ObjectType
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, get)
}
}
-pub trait FooMultiGeneric<KeyType, ObjectType> {
- unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct FooMultiGeneric(pub id);
+impl std::ops::Deref for FooMultiGeneric {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for FooMultiGeneric {}
+impl FooMultiGeneric {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) })
+ }
+}
+impl<KeyType: 'static, ObjectType: 'static>
+ IFooMultiGeneric<KeyType, ObjectType> for FooMultiGeneric
+{
}
-impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
- for id
+pub trait IFooMultiGeneric<KeyType, ObjectType>:
+ Sized + std::ops::Deref
{
- unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType {
+ unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
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 089f0398..4bf234d7 100644
--- a/tests/expectations/tests/libclang-9/objc_template.rs
+++ b/tests/expectations/tests/libclang-9/objc_template.rs
@@ -12,21 +12,56 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo<ObjectType> {
- unsafe fn get(self) -> u64;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl<ObjectType: 'static> Foo<ObjectType> for id {
- unsafe fn get(self) -> u64 {
+impl<ObjectType: 'static> IFoo<ObjectType> for Foo {}
+pub trait IFoo<ObjectType>: Sized + std::ops::Deref {
+ unsafe fn get(self) -> u64
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, get)
}
}
-pub trait FooMultiGeneric<KeyType, ObjectType> {
- unsafe fn objectForKey_(self, key: u64) -> u64;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct FooMultiGeneric(pub id);
+impl std::ops::Deref for FooMultiGeneric {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for FooMultiGeneric {}
+impl FooMultiGeneric {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(FooMultiGeneric), alloc) })
+ }
+}
+impl<KeyType: 'static, ObjectType: 'static>
+ IFooMultiGeneric<KeyType, ObjectType> for FooMultiGeneric
+{
}
-impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
- for id
+pub trait IFooMultiGeneric<KeyType, ObjectType>:
+ Sized + std::ops::Deref
{
- unsafe fn objectForKey_(self, key: u64) -> u64 {
+ unsafe fn objectForKey_(self, key: u64) -> u64
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, objectForKey: key)
}
}
diff --git a/tests/expectations/tests/objc_category.rs b/tests/expectations/tests/objc_category.rs
index 48970fde..544903f5 100644
--- a/tests/expectations/tests/objc_category.rs
+++ b/tests/expectations/tests/objc_category.rs
@@ -12,19 +12,36 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {
- unsafe fn method(self);
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
}
-impl Foo for id {
- unsafe fn method(self) {
- msg_send!(self, method)
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
}
}
-pub trait Foo_BarCategory {
- unsafe fn categoryMethod(self);
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
+ unsafe fn method(self)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(self, method)
+ }
}
-impl Foo_BarCategory for id {
- unsafe fn categoryMethod(self) {
+impl Foo_BarCategory for Foo {}
+pub trait Foo_BarCategory: Sized + std::ops::Deref {
+ unsafe fn categoryMethod(self)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, categoryMethod)
}
}
diff --git a/tests/expectations/tests/objc_class.rs b/tests/expectations/tests/objc_class.rs
index e312f7a5..515d1c16 100644
--- a/tests/expectations/tests/objc_class.rs
+++ b/tests/expectations/tests/objc_class.rs
@@ -13,13 +13,29 @@ extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
extern "C" {
- pub static mut fooVar: *mut id;
+ pub static mut fooVar: *mut objc::runtime::Object;
}
-pub trait Foo {
- unsafe fn method(self);
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl Foo for id {
- unsafe fn method(self) {
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
+ unsafe fn method(self)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, method)
}
}
diff --git a/tests/expectations/tests/objc_class_method.rs b/tests/expectations/tests/objc_class_method.rs
index 42245b99..d6a3343c 100644
--- a/tests/expectations/tests/objc_class_method.rs
+++ b/tests/expectations/tests/objc_class_method.rs
@@ -12,54 +12,60 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {
- unsafe fn method();
- unsafe fn methodWithInt_(foo: ::std::os::raw::c_int);
- unsafe fn methodWithFoo_(foo: id);
- unsafe fn methodReturningInt() -> ::std::os::raw::c_int;
- unsafe fn methodReturningFoo() -> *mut id;
- unsafe fn methodWithArg1_andArg2_andArg3_(
- intvalue: ::std::os::raw::c_int,
- ptr: *mut ::std::os::raw::c_char,
- floatvalue: f32,
- );
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl Foo for id {
- unsafe fn method() {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- method
- )
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
+ unsafe fn method()
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), method)
}
- unsafe fn methodWithInt_(foo: ::std::os::raw::c_int) {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- methodWithInt: foo
- )
+ unsafe fn methodWithInt_(foo: ::std::os::raw::c_int)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), methodWithInt: foo)
}
- unsafe fn methodWithFoo_(foo: id) {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- methodWithFoo: foo
- )
+ unsafe fn methodWithFoo_(foo: id)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), methodWithFoo: foo)
}
- unsafe fn methodReturningInt() -> ::std::os::raw::c_int {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- methodReturningInt
- )
+ unsafe fn methodReturningInt() -> ::std::os::raw::c_int
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), methodReturningInt)
}
- unsafe fn methodReturningFoo() -> *mut id {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- methodReturningFoo
- )
+ unsafe fn methodReturningFoo() -> *mut objc::runtime::Object
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), methodReturningFoo)
}
unsafe fn methodWithArg1_andArg2_andArg3_(
intvalue: ::std::os::raw::c_int,
ptr: *mut ::std::os::raw::c_char,
floatvalue: f32,
- ) {
- msg_send ! ( objc :: runtime :: Class :: get ( "Foo" ) . expect ( "Couldn't find Foo" ) , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue )
+ ) where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send ! ( class ! ( Foo ) , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue )
}
}
diff --git a/tests/expectations/tests/objc_interface.rs b/tests/expectations/tests/objc_interface.rs
index b49f21f7..c2671317 100644
--- a/tests/expectations/tests/objc_interface.rs
+++ b/tests/expectations/tests/objc_interface.rs
@@ -12,7 +12,21 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {}
-impl Foo for id {}
-pub trait protocol_bar {}
-impl protocol_bar for id {}
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
+}
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {}
+pub trait Pbar: Sized + std::ops::Deref {}
diff --git a/tests/expectations/tests/objc_interface_type.rs b/tests/expectations/tests/objc_interface_type.rs
index 5868aa7f..b6d166da 100644
--- a/tests/expectations/tests/objc_interface_type.rs
+++ b/tests/expectations/tests/objc_interface_type.rs
@@ -12,12 +12,27 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {}
-impl Foo for id {}
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
+}
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct FooStruct {
- pub foo: *mut id,
+ pub foo: *mut objc::runtime::Object,
}
#[test]
fn bindgen_test_layout_FooStruct() {
@@ -53,5 +68,5 @@ extern "C" {
pub fn fooFunc(foo: id);
}
extern "C" {
- pub static mut kFoo: *const id;
+ pub static mut kFoo: *const objc::runtime::Object;
}
diff --git a/tests/expectations/tests/objc_method.rs b/tests/expectations/tests/objc_method.rs
index 255d8510..381646c4 100644
--- a/tests/expectations/tests/objc_method.rs
+++ b/tests/expectations/tests/objc_method.rs
@@ -12,40 +12,51 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {
- unsafe fn method(self);
- unsafe fn methodWithInt_(self, foo: ::std::os::raw::c_int);
- unsafe fn methodWithFoo_(self, foo: id);
- unsafe fn methodReturningInt(self) -> ::std::os::raw::c_int;
- unsafe fn methodReturningFoo(self) -> *mut id;
- unsafe fn methodWithArg1_andArg2_andArg3_(
- self,
- intvalue: ::std::os::raw::c_int,
- ptr: *mut ::std::os::raw::c_char,
- floatvalue: f32,
- );
- unsafe fn methodWithAndWithoutKeywords_arg2Name__arg4Name_(
- self,
- arg1: ::std::os::raw::c_int,
- arg2: f32,
- arg3: f32,
- arg4: ::std::os::raw::c_int,
- ) -> instancetype;
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl Foo for id {
- unsafe fn method(self) {
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
+ unsafe fn method(self)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, method)
}
- unsafe fn methodWithInt_(self, foo: ::std::os::raw::c_int) {
+ unsafe fn methodWithInt_(self, foo: ::std::os::raw::c_int)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, methodWithInt: foo)
}
- unsafe fn methodWithFoo_(self, foo: id) {
+ unsafe fn methodWithFoo_(self, foo: id)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, methodWithFoo: foo)
}
- unsafe fn methodReturningInt(self) -> ::std::os::raw::c_int {
+ unsafe fn methodReturningInt(self) -> ::std::os::raw::c_int
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, methodReturningInt)
}
- unsafe fn methodReturningFoo(self) -> *mut id {
+ unsafe fn methodReturningFoo(self) -> *mut objc::runtime::Object
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, methodReturningFoo)
}
unsafe fn methodWithArg1_andArg2_andArg3_(
@@ -53,7 +64,9 @@ impl Foo for id {
intvalue: ::std::os::raw::c_int,
ptr: *mut ::std::os::raw::c_char,
floatvalue: f32,
- ) {
+ ) where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send ! ( self , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue )
}
unsafe fn methodWithAndWithoutKeywords_arg2Name__arg4Name_(
@@ -62,7 +75,10 @@ impl Foo for id {
arg2: f32,
arg3: f32,
arg4: ::std::os::raw::c_int,
- ) -> instancetype {
+ ) -> instancetype
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send ! ( self , methodWithAndWithoutKeywords : arg1 arg2Name : arg2 arg3 : arg3 arg4Name : arg4 )
}
}
diff --git a/tests/expectations/tests/objc_method_clash.rs b/tests/expectations/tests/objc_method_clash.rs
index 739d2aa9..92b7930b 100644
--- a/tests/expectations/tests/objc_method_clash.rs
+++ b/tests/expectations/tests/objc_method_clash.rs
@@ -12,18 +12,33 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {
- unsafe fn foo(self);
- unsafe fn class_foo();
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl Foo for id {
- unsafe fn foo(self) {
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
+ unsafe fn foo(self)
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, foo)
}
- unsafe fn class_foo() {
- msg_send!(
- objc::runtime::Class::get("Foo").expect("Couldn't find Foo"),
- foo
- )
+ unsafe fn class_foo()
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
+ msg_send!(class!(Foo), foo)
}
}
diff --git a/tests/expectations/tests/objc_property_fnptr.rs b/tests/expectations/tests/objc_property_fnptr.rs
index a1c4b3d2..8b5ab0ac 100644
--- a/tests/expectations/tests/objc_property_fnptr.rs
+++ b/tests/expectations/tests/objc_property_fnptr.rs
@@ -12,24 +12,23 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait Foo {
- unsafe fn func(
- self,
- ) -> ::std::option::Option<
- unsafe extern "C" fn(
- arg1: ::std::os::raw::c_char,
- arg2: ::std::os::raw::c_short,
- arg3: f32,
- ) -> ::std::os::raw::c_int,
- >;
- unsafe fn setFunc_(
- self,
- func: ::std::option::Option<
- unsafe extern "C" fn() -> ::std::os::raw::c_int,
- >,
- );
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
}
-impl Foo for id {
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {
unsafe fn func(
self,
) -> ::std::option::Option<
@@ -38,7 +37,10 @@ impl Foo for id {
arg2: ::std::os::raw::c_short,
arg3: f32,
) -> ::std::os::raw::c_int,
- > {
+ >
+ where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, func)
}
unsafe fn setFunc_(
@@ -46,7 +48,9 @@ impl Foo for id {
func: ::std::option::Option<
unsafe extern "C" fn() -> ::std::os::raw::c_int,
>,
- ) {
+ ) where
+ <Self as std::ops::Deref>::Target: objc::Message + Sized,
+ {
msg_send!(self, setFunc: func)
}
}
diff --git a/tests/expectations/tests/objc_protocol.rs b/tests/expectations/tests/objc_protocol.rs
index aeb6de02..25870f2a 100644
--- a/tests/expectations/tests/objc_protocol.rs
+++ b/tests/expectations/tests/objc_protocol.rs
@@ -12,7 +12,22 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait protocol_Foo {}
-impl protocol_Foo for id {}
-pub trait Foo {}
-impl Foo for id {}
+pub trait PFoo: Sized + std::ops::Deref {}
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct Foo(pub id);
+impl std::ops::Deref for Foo {
+ type Target = objc::runtime::Object;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*self.0 }
+ }
+}
+unsafe impl objc::Message for Foo {}
+impl Foo {
+ pub fn alloc() -> Self {
+ Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
+ }
+}
+impl PFoo for Foo {}
+impl IFoo for Foo {}
+pub trait IFoo: Sized + std::ops::Deref {}
diff --git a/tests/expectations/tests/objc_whitelist.rs b/tests/expectations/tests/objc_whitelist.rs
index 3089fb7f..f4c0e231 100644
--- a/tests/expectations/tests/objc_whitelist.rs
+++ b/tests/expectations/tests/objc_whitelist.rs
@@ -12,37 +12,5 @@
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
-pub trait protocol_SomeProtocol {
- unsafe fn protocolMethod(self);
- unsafe fn protocolClassMethod();
-}
-impl protocol_SomeProtocol for id {
- unsafe fn protocolMethod(self) {
- msg_send!(self, protocolMethod)
- }
- unsafe fn protocolClassMethod() {
- msg_send!(
- objc::runtime::Class::get("SomeProtocol")
- .expect("Couldn't find SomeProtocol"),
- protocolClassMethod
- )
- }
-}
-pub trait WhitelistMe {
- unsafe fn method(self);
- unsafe fn classMethod();
-}
-impl WhitelistMe for id {
- unsafe fn method(self) {
- msg_send!(self, method)
- }
- unsafe fn classMethod() {
- msg_send!(
- objc::runtime::Class::get("WhitelistMe")
- .expect("Couldn't find WhitelistMe"),
- classMethod
- )
- }
-}
-pub trait WhitelistMe_InterestingCategory {}
-impl WhitelistMe_InterestingCategory for id {}
+impl WhitelistMe_InterestingCategory for WhitelistMe {}
+pub trait WhitelistMe_InterestingCategory: Sized + std::ops::Deref {}