Skip to content

Commit a489e9b

Browse files
committed
Added better inheritance tests, removed uneeded loops.
* Removed looping through all the items based on PR. * Added better unit tests. * Moved parent traversal to the codegen phase.
1 parent e29f69d commit a489e9b

File tree

8 files changed

+188
-210
lines changed

8 files changed

+188
-210
lines changed

src/codegen/mod.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3787,9 +3787,21 @@ impl CodeGenerator for ObjCInterface {
37873787
};
37883788
result.push(impl_trait);
37893789
}
3790-
for parent_id in self.parent_classes.iter() {
3791-
let parent = ctx.resolve_type(parent_id.expect_type_id(ctx));
3790+
let mut parent_class = self.parent_class;
3791+
while let Some(parent_id) = parent_class {
3792+
let mut parent = ctx.resolve_type(parent_id.expect_type_id(ctx));
3793+
3794+
parent = match parent.kind() {
3795+
TypeKind::ResolvedTypeRef(type_id) => {
3796+
ctx.resolve_type(*type_id)
3797+
},
3798+
_ => {
3799+
parent_class = None;
3800+
continue
3801+
}
3802+
};
37923803
if let TypeKind::ObjCInterface(ref parent) = parent.kind() {
3804+
parent_class = parent.parent_class;
37933805
let parent_name = ctx.rust_ident(parent.rust_name());
37943806
let impl_trait = if parent.is_template() {
37953807
let template_names: Vec<Ident> = parent
@@ -3807,6 +3819,8 @@ impl CodeGenerator for ObjCInterface {
38073819
}
38083820
};
38093821
result.push(impl_trait);
3822+
} else {
3823+
parent_class = None;
38103824
}
38113825
}
38123826
}

src/ir/objc.rs

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Objective C types
22
33
use super::context::{BindgenContext, ItemId};
4+
use super::item::Item;
5+
use parse::ClangItemParser;
46
use super::function::FunctionSig;
57
use super::traversal::{Trace, Tracer};
68
use super::ty::TypeKind;
@@ -35,8 +37,8 @@ pub struct ObjCInterface {
3537
/// The list of protocols that this interface conforms to.
3638
pub conforms_to: Vec<ItemId>,
3739

38-
/// The list of parents that this interface has.
39-
pub parent_classes: Vec<ItemId>,
40+
/// The direct parent for this interface.
41+
pub parent_class: Option<ItemId>,
4042

4143
/// List of the methods defined in this interfae
4244
methods: Vec<ObjCMethod>,
@@ -68,7 +70,7 @@ impl ObjCInterface {
6870
category: None,
6971
is_protocol: false,
7072
template_names: Vec::new(),
71-
parent_classes: Vec::new(),
73+
parent_class: None,
7274
conforms_to: Vec::new(),
7375
methods: Vec::new(),
7476
class_methods: Vec::new(),
@@ -185,37 +187,8 @@ impl ObjCInterface {
185187
interface.template_names.push(name);
186188
}
187189
CXCursor_ObjCSuperClassRef => {
188-
let items_map = ctx.items();
189-
190-
let needle = format!("I{}", c.spelling());
191-
debug!("Interface {} has a parent class {}, find the item", interface.name, needle);
192-
193-
for (id, item) in items_map
194-
{
195-
let ty = match item.as_type() {
196-
Some(ty) => ty,
197-
None => continue,
198-
};
199-
200-
let class = match *ty.kind() {
201-
TypeKind::ObjCInterface(ref class) => class,
202-
_ => continue,
203-
};
204-
205-
if class.is_protocol {
206-
continue;
207-
}
208-
209-
debug!("Checking class {}, ty.name {:?}", class.name, ty.name());
210-
if Some(needle.as_ref()) == ty.name() {
211-
debug!("Found parent class {:?}", item);
212-
interface.parent_classes.push(id);
213-
for i in &class.parent_classes {
214-
interface.parent_classes.push(*i);
215-
}
216-
break;
217-
}
218-
}
190+
let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx);
191+
interface.parent_class = Some(item.into());
219192
},
220193
_ => {}
221194
}

tests/expectations/tests/libclang-3.8/objc_inheritance.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,57 +14,55 @@ extern crate objc;
1414
pub type id = *mut objc::runtime::Object;
1515
#[repr(transparent)]
1616
#[derive(Clone, Copy)]
17-
pub struct Baz(pub id);
18-
impl std::ops::Deref for Baz {
17+
pub struct Foo(pub id);
18+
impl std::ops::Deref for Foo {
1919
type Target = objc::runtime::Object;
2020
fn deref(&self) -> &Self::Target {
2121
unsafe { &*self.0 }
2222
}
2323
}
24-
unsafe impl objc::Message for Baz {}
25-
impl Baz {
24+
unsafe impl objc::Message for Foo {}
25+
impl Foo {
2626
pub fn alloc() -> Self {
27-
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
28-
}
29-
}
30-
impl IBaz for Baz {}
31-
pub trait IBaz: Sized + std::ops::Deref {
32-
unsafe fn initWithFirstNumber_(
33-
self,
34-
firstNumber: ::std::os::raw::c_int,
35-
) -> instancetype
36-
where
37-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
38-
{
39-
msg_send!(self, initWithFirstNumber: firstNumber)
27+
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
4028
}
4129
}
30+
impl IFoo for Foo {}
31+
pub trait IFoo: Sized + std::ops::Deref {}
4232
#[repr(transparent)]
4333
#[derive(Clone, Copy)]
44-
pub struct Foo(pub id);
45-
impl std::ops::Deref for Foo {
34+
pub struct Bar(pub id);
35+
impl std::ops::Deref for Bar {
4636
type Target = objc::runtime::Object;
4737
fn deref(&self) -> &Self::Target {
4838
unsafe { &*self.0 }
4939
}
5040
}
51-
unsafe impl objc::Message for Foo {}
52-
impl Foo {
41+
unsafe impl objc::Message for Bar {}
42+
impl Bar {
5343
pub fn alloc() -> Self {
54-
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
44+
Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
5545
}
5646
}
57-
impl IBaz for Foo {}
58-
impl IFoo for Foo {}
59-
pub trait IFoo: Sized + std::ops::Deref {
60-
unsafe fn initWithFirstNumber_(
61-
self,
62-
firstNumber: ::std::os::raw::c_int,
63-
) -> instancetype
64-
where
65-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
66-
{
67-
msg_send!(self, initWithFirstNumber: firstNumber)
47+
impl IFoo for Bar {}
48+
impl IBar for Bar {}
49+
pub trait IBar: Sized + std::ops::Deref {}
50+
#[repr(transparent)]
51+
#[derive(Clone, Copy)]
52+
pub struct Baz(pub id);
53+
impl std::ops::Deref for Baz {
54+
type Target = objc::runtime::Object;
55+
fn deref(&self) -> &Self::Target {
56+
unsafe { &*self.0 }
57+
}
58+
}
59+
unsafe impl objc::Message for Baz {}
60+
impl Baz {
61+
pub fn alloc() -> Self {
62+
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
6863
}
6964
}
70-
pub type instancetype = id;
65+
impl IBar for Baz {}
66+
impl IFoo for Baz {}
67+
impl IBaz for Baz {}
68+
pub trait IBaz: Sized + std::ops::Deref {}

tests/expectations/tests/libclang-3.9/objc_inheritance.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,57 +14,55 @@ extern crate objc;
1414
pub type id = *mut objc::runtime::Object;
1515
#[repr(transparent)]
1616
#[derive(Clone, Copy)]
17-
pub struct Baz(pub id);
18-
impl std::ops::Deref for Baz {
17+
pub struct Foo(pub id);
18+
impl std::ops::Deref for Foo {
1919
type Target = objc::runtime::Object;
2020
fn deref(&self) -> &Self::Target {
2121
unsafe { &*self.0 }
2222
}
2323
}
24-
unsafe impl objc::Message for Baz {}
25-
impl Baz {
24+
unsafe impl objc::Message for Foo {}
25+
impl Foo {
2626
pub fn alloc() -> Self {
27-
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
28-
}
29-
}
30-
impl IBaz for Baz {}
31-
pub trait IBaz: Sized + std::ops::Deref {
32-
unsafe fn initWithFirstNumber_(
33-
self,
34-
firstNumber: ::std::os::raw::c_int,
35-
) -> instancetype
36-
where
37-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
38-
{
39-
msg_send!(self, initWithFirstNumber: firstNumber)
27+
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
4028
}
4129
}
30+
impl IFoo for Foo {}
31+
pub trait IFoo: Sized + std::ops::Deref {}
4232
#[repr(transparent)]
4333
#[derive(Clone, Copy)]
44-
pub struct Foo(pub id);
45-
impl std::ops::Deref for Foo {
34+
pub struct Bar(pub id);
35+
impl std::ops::Deref for Bar {
4636
type Target = objc::runtime::Object;
4737
fn deref(&self) -> &Self::Target {
4838
unsafe { &*self.0 }
4939
}
5040
}
51-
unsafe impl objc::Message for Foo {}
52-
impl Foo {
41+
unsafe impl objc::Message for Bar {}
42+
impl Bar {
5343
pub fn alloc() -> Self {
54-
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
44+
Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
5545
}
5646
}
57-
impl IBaz for Foo {}
58-
impl IFoo for Foo {}
59-
pub trait IFoo: Sized + std::ops::Deref {
60-
unsafe fn initWithFirstNumber_(
61-
self,
62-
firstNumber: ::std::os::raw::c_int,
63-
) -> instancetype
64-
where
65-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
66-
{
67-
msg_send!(self, initWithFirstNumber: firstNumber)
47+
impl IFoo for Bar {}
48+
impl IBar for Bar {}
49+
pub trait IBar: Sized + std::ops::Deref {}
50+
#[repr(transparent)]
51+
#[derive(Clone, Copy)]
52+
pub struct Baz(pub id);
53+
impl std::ops::Deref for Baz {
54+
type Target = objc::runtime::Object;
55+
fn deref(&self) -> &Self::Target {
56+
unsafe { &*self.0 }
57+
}
58+
}
59+
unsafe impl objc::Message for Baz {}
60+
impl Baz {
61+
pub fn alloc() -> Self {
62+
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
6863
}
6964
}
70-
pub type instancetype = id;
65+
impl IBar for Baz {}
66+
impl IFoo for Baz {}
67+
impl IBaz for Baz {}
68+
pub trait IBaz: Sized + std::ops::Deref {}

tests/expectations/tests/libclang-4/objc_inheritance.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,57 +14,55 @@ extern crate objc;
1414
pub type id = *mut objc::runtime::Object;
1515
#[repr(transparent)]
1616
#[derive(Clone, Copy)]
17-
pub struct Baz(pub id);
18-
impl std::ops::Deref for Baz {
17+
pub struct Foo(pub id);
18+
impl std::ops::Deref for Foo {
1919
type Target = objc::runtime::Object;
2020
fn deref(&self) -> &Self::Target {
2121
unsafe { &*self.0 }
2222
}
2323
}
24-
unsafe impl objc::Message for Baz {}
25-
impl Baz {
24+
unsafe impl objc::Message for Foo {}
25+
impl Foo {
2626
pub fn alloc() -> Self {
27-
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
28-
}
29-
}
30-
impl IBaz for Baz {}
31-
pub trait IBaz: Sized + std::ops::Deref {
32-
unsafe fn initWithFirstNumber_(
33-
self,
34-
firstNumber: ::std::os::raw::c_int,
35-
) -> instancetype
36-
where
37-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
38-
{
39-
msg_send!(self, initWithFirstNumber: firstNumber)
27+
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
4028
}
4129
}
30+
impl IFoo for Foo {}
31+
pub trait IFoo: Sized + std::ops::Deref {}
4232
#[repr(transparent)]
4333
#[derive(Clone, Copy)]
44-
pub struct Foo(pub id);
45-
impl std::ops::Deref for Foo {
34+
pub struct Bar(pub id);
35+
impl std::ops::Deref for Bar {
4636
type Target = objc::runtime::Object;
4737
fn deref(&self) -> &Self::Target {
4838
unsafe { &*self.0 }
4939
}
5040
}
51-
unsafe impl objc::Message for Foo {}
52-
impl Foo {
41+
unsafe impl objc::Message for Bar {}
42+
impl Bar {
5343
pub fn alloc() -> Self {
54-
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
44+
Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
5545
}
5646
}
57-
impl IBaz for Foo {}
58-
impl IFoo for Foo {}
59-
pub trait IFoo: Sized + std::ops::Deref {
60-
unsafe fn initWithFirstNumber_(
61-
self,
62-
firstNumber: ::std::os::raw::c_int,
63-
) -> instancetype
64-
where
65-
<Self as std::ops::Deref>::Target: objc::Message + Sized,
66-
{
67-
msg_send!(self, initWithFirstNumber: firstNumber)
47+
impl IFoo for Bar {}
48+
impl IBar for Bar {}
49+
pub trait IBar: Sized + std::ops::Deref {}
50+
#[repr(transparent)]
51+
#[derive(Clone, Copy)]
52+
pub struct Baz(pub id);
53+
impl std::ops::Deref for Baz {
54+
type Target = objc::runtime::Object;
55+
fn deref(&self) -> &Self::Target {
56+
unsafe { &*self.0 }
57+
}
58+
}
59+
unsafe impl objc::Message for Baz {}
60+
impl Baz {
61+
pub fn alloc() -> Self {
62+
Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
6863
}
6964
}
70-
pub type instancetype = id;
65+
impl IBar for Baz {}
66+
impl IFoo for Baz {}
67+
impl IBaz for Baz {}
68+
pub trait IBaz: Sized + std::ops::Deref {}

0 commit comments

Comments
 (0)