Skip to content

Commit 6b3b9d3

Browse files
committed
An initial implementation of objective-c templates
1 parent 899f599 commit 6b3b9d3

File tree

8 files changed

+115
-25
lines changed

8 files changed

+115
-25
lines changed

src/codegen/mod.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3728,18 +3728,36 @@ impl CodeGenerator for ObjCInterface {
37283728

37293729
let trait_name = ctx.rust_ident(self.rust_name());
37303730

3731-
let trait_block = quote! {
3732-
pub trait #trait_name {
3733-
#( #trait_items )*
3731+
let trait_block = if self.is_template() {
3732+
let template_names : Vec<Ident> = self.template_names.iter().map(|g| ctx.rust_ident(g)).collect();
3733+
quote! {
3734+
pub trait #trait_name <#(#template_names),*>{
3735+
#( #trait_items )*
3736+
}
3737+
}
3738+
} else {
3739+
quote! {
3740+
pub trait #trait_name {
3741+
#( #trait_items )*
3742+
}
37343743
}
37353744
};
37363745

37373746
let ty_for_impl = quote! {
37383747
id
37393748
};
3740-
let impl_block = quote! {
3741-
impl #trait_name for #ty_for_impl {
3742-
#( #impl_items )*
3749+
let impl_block = if self.is_template() {
3750+
let template_names : Vec<Ident> = self.template_names.iter().map(|g| ctx.rust_ident(g)).collect();
3751+
quote! {
3752+
impl <#(#template_names :'static),*> #trait_name <#(#template_names),*> for #ty_for_impl {
3753+
#( #impl_items )*
3754+
}
3755+
}
3756+
} else {
3757+
quote! {
3758+
impl #trait_name for #ty_for_impl {
3759+
#( #impl_items )*
3760+
}
37433761
}
37443762
};
37453763

src/ir/objc.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use clang_sys::CXCursor_ObjCClassRef;
1212
use clang_sys::CXCursor_ObjCInstanceMethodDecl;
1313
use clang_sys::CXCursor_ObjCProtocolDecl;
1414
use clang_sys::CXCursor_ObjCProtocolRef;
15+
use clang_sys::CXCursor_TemplateTypeParameter;
1516
use proc_macro2::{Ident, Span, TokenStream};
1617

1718
/// Objective C interface as used in TypeKind
@@ -27,6 +28,9 @@ pub struct ObjCInterface {
2728

2829
is_protocol: bool,
2930

31+
/// The list of template names almost always, ObjectType or KeyType
32+
pub template_names: Vec<String>,
33+
3034
conforms_to: Vec<ItemId>,
3135

3236
/// List of the methods defined in this interfae
@@ -58,6 +62,7 @@ impl ObjCInterface {
5862
name: name.to_owned(),
5963
category: None,
6064
is_protocol: false,
65+
template_names: Vec::new(),
6166
conforms_to: Vec::new(),
6267
methods: Vec::new(),
6368
class_methods: Vec::new(),
@@ -85,6 +90,11 @@ impl ObjCInterface {
8590
}
8691
}
8792

93+
/// Is this a template interface?
94+
pub fn is_template(&self) -> bool {
95+
!self.template_names.is_empty()
96+
}
97+
8898
/// List of the methods defined in this interface
8999
pub fn methods(&self) -> &Vec<ObjCMethod> {
90100
&self.methods
@@ -154,6 +164,10 @@ impl ObjCInterface {
154164
let method = ObjCMethod::new(&name, signature, is_class_method);
155165
interface.add_method(method);
156166
}
167+
CXCursor_TemplateTypeParameter => {
168+
let name = c.spelling();
169+
interface.template_names.push(name);
170+
}
157171
_ => {}
158172
}
159173
CXChildVisit_Continue
@@ -183,8 +197,8 @@ impl ObjCMethod {
183197
ObjCMethod {
184198
name: name.to_owned(),
185199
rust_name: rust_name.to_owned(),
186-
signature: signature,
187-
is_class_method: is_class_method,
200+
signature,
201+
is_class_method,
188202
}
189203
}
190204

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88
extern crate objc;
99
#[allow(non_camel_case_types)]
1010
pub type id = *mut objc::runtime::Object;
11-
pub trait Foo {
11+
pub trait Foo<ObjectType> {
1212
unsafe fn get(self) -> id;
1313
}
14-
impl Foo for id {
14+
impl<ObjectType: 'static> Foo<ObjectType> for id {
1515
unsafe fn get(self) -> id {
1616
msg_send!(self, get)
1717
}
1818
}
19+
pub trait FooMultiGeneric<KeyType, ObjectType> {
20+
unsafe fn objectForKey_(self, key: id) -> id;
21+
}
22+
impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
23+
for id
24+
{
25+
unsafe fn objectForKey_(self, key: id) -> id {
26+
msg_send!(self, objectForKey: key)
27+
}
28+
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88
extern crate objc;
99
#[allow(non_camel_case_types)]
1010
pub type id = *mut objc::runtime::Object;
11-
pub trait Foo {
11+
pub trait Foo<ObjectType> {
1212
unsafe fn get(self) -> id;
1313
}
14-
impl Foo for id {
14+
impl<ObjectType: 'static> Foo<ObjectType> for id {
1515
unsafe fn get(self) -> id {
1616
msg_send!(self, get)
1717
}
1818
}
19+
pub trait FooMultiGeneric<KeyType, ObjectType> {
20+
unsafe fn objectForKey_(self, key: id) -> id;
21+
}
22+
impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
23+
for id
24+
{
25+
unsafe fn objectForKey_(self, key: id) -> id {
26+
msg_send!(self, objectForKey: key)
27+
}
28+
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,20 @@
99
extern crate objc;
1010
#[allow(non_camel_case_types)]
1111
pub type id = *mut objc::runtime::Object;
12-
pub trait Foo {
12+
pub trait Foo<ObjectType> {
1313
unsafe fn get(self)
1414
-> *mut ObjectType;
1515
}
16-
impl Foo for id {
16+
impl<ObjectType: 'static> Foo<ObjectType> for id {
1717
unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) }
1818
}
19+
pub trait FooMultiGeneric<KeyType, ObjectType> {
20+
unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType;
21+
}
22+
impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
23+
for id
24+
{
25+
unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType {
26+
msg_send!(self, objectForKey: key)
27+
}
28+
}
Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
6-
#![cfg(target_os="macos")]
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
#![cfg(target_os = "macos")]
710

811
#[macro_use]
912
extern crate objc;
1013
#[allow(non_camel_case_types)]
1114
pub type id = *mut objc::runtime::Object;
12-
pub trait Foo {
13-
unsafe fn get(self)
14-
-> *mut ObjectType;
15+
pub trait Foo<ObjectType> {
16+
unsafe fn get(self) -> *mut ObjectType;
17+
}
18+
impl<ObjectType: 'static> Foo<ObjectType> for id {
19+
unsafe fn get(self) -> *mut ObjectType {
20+
msg_send!(self, get)
21+
}
22+
}
23+
pub trait FooMultiGeneric<KeyType, ObjectType> {
24+
unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType;
1525
}
16-
impl Foo for id {
17-
unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) }
26+
impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
27+
for id
28+
{
29+
unsafe fn objectForKey_(self, key: *mut KeyType) -> *mut ObjectType {
30+
msg_send!(self, objectForKey: key)
31+
}
1832
}

tests/expectations/tests/libclang-9/objc_template.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@
1212
extern crate objc;
1313
#[allow(non_camel_case_types)]
1414
pub type id = *mut objc::runtime::Object;
15-
pub trait Foo {
15+
pub trait Foo<ObjectType> {
1616
unsafe fn get(self) -> u64;
1717
}
18-
impl Foo for id {
18+
impl<ObjectType: 'static> Foo<ObjectType> for id {
1919
unsafe fn get(self) -> u64 {
2020
msg_send!(self, get)
2121
}
2222
}
23+
pub trait FooMultiGeneric<KeyType, ObjectType> {
24+
unsafe fn objectForKey_(self, key: u64) -> u64;
25+
}
26+
impl<KeyType: 'static, ObjectType: 'static> FooMultiGeneric<KeyType, ObjectType>
27+
for id
28+
{
29+
unsafe fn objectForKey_(self, key: u64) -> u64 {
30+
msg_send!(self, objectForKey: key)
31+
}
32+
}

tests/headers/objc_template.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@
44
@interface Foo<__covariant ObjectType>
55
- (ObjectType)get;
66
@end
7+
8+
@interface FooMultiGeneric<__covariant KeyType, __covariant ObjectType>
9+
- (nullable ObjectType)objectForKey:(KeyType)key;
10+
@end

0 commit comments

Comments
 (0)