-
Notifications
You must be signed in to change notification settings - Fork 748
[Objc] Add From<ChildClass>, TryFrom<ParentClass>, function ownership updates and Protocol inheritance #1883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
b1b1d03
64a16c9
600cbdd
c50ca59
d9d030d
314cca5
0054fab
e4fb4a7
6c5f592
5d5c5a5
b88fc1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ use crate::{Entry, HashMap, HashSet}; | |
use std; | ||
use std::borrow::Cow; | ||
use std::cell::Cell; | ||
use std::collections::HashSet as CollectionHashSet; | ||
use std::collections::VecDeque; | ||
use std::fmt::Write; | ||
use std::iter; | ||
|
@@ -3806,7 +3807,7 @@ fn objc_method_codegen( | |
} | ||
} else { | ||
let fn_args = fn_args.clone(); | ||
let args = iter::once(quote! { self }).chain(fn_args.into_iter()); | ||
let args = iter::once(quote! { &self }).chain(fn_args.into_iter()); | ||
quote! { | ||
( #( #args ),* ) #fn_ret | ||
} | ||
|
@@ -3825,7 +3826,7 @@ fn objc_method_codegen( | |
} | ||
} else { | ||
quote! { | ||
msg_send!(self, #methods_and_args) | ||
msg_send!(*self, #methods_and_args) | ||
} | ||
}; | ||
|
||
|
@@ -3901,7 +3902,7 @@ impl CodeGenerator for ObjCInterface { | |
if !self.is_category() && !self.is_protocol() { | ||
let struct_block = quote! { | ||
#[repr(transparent)] | ||
#[derive(Clone, Copy)] | ||
#[derive(Clone)] | ||
pub struct #class_name(pub id); | ||
impl std::ops::Deref for #class_name { | ||
type Target = objc::runtime::Object; | ||
|
@@ -3921,7 +3922,10 @@ impl CodeGenerator for ObjCInterface { | |
} | ||
}; | ||
result.push(struct_block); | ||
let mut protocol_set: CollectionHashSet<ItemId> = | ||
CollectionHashSet::new(); | ||
for protocol_id in self.conforms_to.iter() { | ||
protocol_set.insert(*protocol_id); | ||
let protocol_name = ctx.rust_ident( | ||
ctx.resolve_type(protocol_id.expect_type_id(ctx)) | ||
.name() | ||
|
@@ -3962,6 +3966,50 @@ impl CodeGenerator for ObjCInterface { | |
} | ||
}; | ||
result.push(impl_trait); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is getting kinda gnarly, it may be worth factoring this |
||
for protocol_id in parent.conforms_to.iter() { | ||
if !protocol_set.contains(protocol_id) { | ||
protocol_set.insert(*protocol_id); | ||
simlay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 !parent.is_template() { | ||
let parent_struct_name = parent.name(); | ||
let child_struct_name = self.name(); | ||
let parent_struct = ctx.rust_ident(parent_struct_name); | ||
let from_block = quote! { | ||
impl From<#class_name> for #parent_struct { | ||
fn from(child: #class_name) -> #parent_struct { | ||
#parent_struct(child.0) | ||
} | ||
} | ||
}; | ||
result.push(from_block); | ||
|
||
let try_into_block = quote! { | ||
impl std::convert::TryFrom<#parent_struct> for #class_name { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can't use |
||
type Error = String; | ||
fn try_from(parent: #parent_struct) -> Result<#class_name, Self::Error> { | ||
let is_kind_of : bool = unsafe { msg_send!(parent, isKindOfClass:class!(#class_name))}; | ||
if is_kind_of { | ||
Ok(#class_name(parent.0)) | ||
} else { | ||
Err(format!("This {} is not an cannot be downcasted to {}", #parent_struct_name, #child_struct_name)) | ||
simlay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
}; | ||
result.push(try_into_block); | ||
} | ||
parent.parent_class | ||
} else { | ||
None | ||
|
Uh oh!
There was an error while loading. Please reload this page.