@@ -13,6 +13,7 @@ use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
13
13
use ir:: item_kind:: ItemKind ;
14
14
use ir:: layout:: Layout ;
15
15
use ir:: module:: Module ;
16
+ use ir:: objc:: ObjCInterface ;
16
17
use ir:: ty:: { Type , TypeKind } ;
17
18
use ir:: type_collector:: ItemSet ;
18
19
use ir:: var:: Var ;
@@ -84,6 +85,8 @@ struct CodegenResult<'a> {
84
85
/// Whether an union has been generated at least once.
85
86
saw_union : bool ,
86
87
88
+ saw_objc : bool ,
89
+
87
90
items_seen : HashSet < ItemId > ,
88
91
/// The set of generated function/var names, needed because in C/C++ is
89
92
/// legal to do something like:
@@ -115,6 +118,7 @@ impl<'a> CodegenResult<'a> {
115
118
CodegenResult {
116
119
items : vec ! [ ] ,
117
120
saw_union : false ,
121
+ saw_objc : false ,
118
122
codegen_id : codegen_id,
119
123
items_seen : Default :: default ( ) ,
120
124
functions_seen : Default :: default ( ) ,
@@ -132,6 +136,10 @@ impl<'a> CodegenResult<'a> {
132
136
self . saw_union = true ;
133
137
}
134
138
139
+ fn saw_objc ( & mut self ) {
140
+ self . saw_objc = true ;
141
+ }
142
+
135
143
fn seen ( & self , item : ItemId ) -> bool {
136
144
self . items_seen . contains ( & item)
137
145
}
@@ -175,6 +183,7 @@ impl<'a> CodegenResult<'a> {
175
183
cb ( & mut new) ;
176
184
177
185
self . saw_union |= new. saw_union ;
186
+ self . saw_objc |= new. saw_objc ;
178
187
179
188
new. items
180
189
}
@@ -342,6 +351,9 @@ impl CodeGenerator for Module {
342
351
if ctx. need_bindegen_complex_type ( ) {
343
352
utils:: prepend_complex_type ( ctx, & mut * result) ;
344
353
}
354
+ if result. saw_objc {
355
+ utils:: prepend_objc_header ( ctx, & mut * result) ;
356
+ }
345
357
}
346
358
} ;
347
359
@@ -586,6 +598,9 @@ impl CodeGenerator for Type {
586
598
TypeKind :: Enum ( ref ei) => {
587
599
ei. codegen ( ctx, result, whitelisted_items, item)
588
600
}
601
+ TypeKind :: ObjCInterface ( ref interface) => {
602
+ interface. codegen ( ctx, result, whitelisted_items, item)
603
+ }
589
604
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
590
605
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
591
606
}
@@ -2062,6 +2077,13 @@ impl ToRustTy for Type {
2062
2077
let ident = ctx. rust_ident ( & name) ;
2063
2078
quote_ty ! ( ctx. ext_cx( ) , $ident)
2064
2079
}
2080
+
2081
+ TypeKind :: ObjCInterface ( ..) => {
2082
+ let name = item. canonical_name ( ctx) ;
2083
+ let ident = ctx. rust_ident ( & name) ;
2084
+ quote_ty ! ( ctx. ext_cx( ) , $ident)
2085
+ }
2086
+
2065
2087
ref u @ TypeKind :: UnresolvedTypeRef ( ..) => {
2066
2088
unreachable ! ( "Should have been resolved after parsing {:?}!" , u)
2067
2089
}
@@ -2095,10 +2117,27 @@ impl ToRustTy for FunctionSig {
2095
2117
// the array type derivation.
2096
2118
//
2097
2119
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2098
- let arg_ty = if let TypeKind :: Array ( t, _) = * arg_ty. canonical_type ( ctx) . kind ( ) {
2120
+
2121
+
2122
+ let arg_ty = match * arg_ty. canonical_type ( ctx) . kind ( )
2123
+ {
2124
+ TypeKind :: Array ( t, _) =>
2125
+ {
2099
2126
t. to_rust_ty ( ctx) . to_ptr ( arg_ty. is_const ( ) , ctx. span ( ) )
2127
+ } ,
2128
+ TypeKind :: Pointer ( inner) => {
2129
+ let inner = ctx. resolve_item ( inner) ;
2130
+ let inner_ty = inner. expect_type ( ) ;
2131
+ if let TypeKind :: ObjCInterface ( _) = * inner_ty. canonical_type ( ctx) . kind ( ) {
2132
+ aster:: ty:: TyBuilder :: new ( ) . id ( "id" )
2133
+ //inner.to_rust_ty(ctx)
2100
2134
} else {
2101
2135
arg_item. to_rust_ty ( ctx)
2136
+ }
2137
+ } ,
2138
+ _ => {
2139
+ arg_item. to_rust_ty ( ctx)
2140
+ }
2102
2141
} ;
2103
2142
2104
2143
let arg_name = match * name {
@@ -2214,6 +2253,90 @@ impl CodeGenerator for Function {
2214
2253
}
2215
2254
}
2216
2255
2256
+ impl CodeGenerator for ObjCInterface {
2257
+ type Extra = Item ;
2258
+ fn codegen < ' a > ( & self ,
2259
+ ctx : & BindgenContext ,
2260
+ result : & mut CodegenResult < ' a > ,
2261
+ _whitelisted_items : & ItemSet ,
2262
+ _: & Item ) {
2263
+
2264
+ let mut impl_items = vec ! [ ] ;
2265
+ let mut trait_items = vec ! [ ] ;
2266
+
2267
+ for method in & self . methods {
2268
+ let method_name = ctx. rust_ident ( & method. name ) ;
2269
+
2270
+ let body = quote_stmt ! ( ctx. ext_cx( ) , msg_send![ self , $method_name] )
2271
+ . unwrap ( ) ;
2272
+ let block = ast:: Block {
2273
+ stmts : vec ! [ body] ,
2274
+ id : ast:: DUMMY_NODE_ID ,
2275
+ rules : ast:: BlockCheckMode :: Default ,
2276
+ span : ctx. span ( ) ,
2277
+ } ;
2278
+
2279
+ let sig = aster:: AstBuilder :: new ( )
2280
+ . method_sig ( )
2281
+ . unsafe_ ( )
2282
+ . fn_decl ( )
2283
+ . self_ ( )
2284
+ . build ( ast:: SelfKind :: Value ( ast:: Mutability :: Immutable ) ) //ast::SelfKind::Region(None, ast::Mutability::Mutable))
2285
+ . build ( ast:: FunctionRetTy :: Default ( ctx. span ( ) ) ) ;
2286
+ let attrs = vec ! [ ] ;
2287
+
2288
+ let impl_item = ast:: ImplItem {
2289
+ id : ast:: DUMMY_NODE_ID ,
2290
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2291
+ vis : ast:: Visibility :: Inherited , // Public,
2292
+ attrs : attrs. clone ( ) ,
2293
+ node : ast:: ImplItemKind :: Method ( sig. clone ( ) , P ( block) ) ,
2294
+ defaultness : ast:: Defaultness :: Final ,
2295
+ span : ctx. span ( ) ,
2296
+ } ;
2297
+
2298
+ let trait_item = ast:: TraitItem {
2299
+ id : ast:: DUMMY_NODE_ID ,
2300
+ ident : ctx. rust_ident ( & method. rust_name ) ,
2301
+ attrs : attrs,
2302
+ node : ast:: TraitItemKind :: Method ( sig, None ) ,
2303
+ span : ctx. span ( ) ,
2304
+ } ;
2305
+
2306
+ impl_items. push ( impl_item) ;
2307
+ trait_items. push ( trait_item)
2308
+ }
2309
+
2310
+
2311
+ let trait_block = aster:: AstBuilder :: new ( )
2312
+ . item ( )
2313
+ . pub_ ( )
2314
+ . trait_ ( & self . name )
2315
+ . with_items ( trait_items)
2316
+ . build ( ) ;
2317
+
2318
+ let ty_for_impl = aster:: AstBuilder :: new ( )
2319
+ . ty ( )
2320
+ . path ( )
2321
+ . id ( ctx. rust_ident ( "id" ) )
2322
+ . build ( ) ;
2323
+ let impl_block = aster:: AstBuilder :: new ( )
2324
+ . item ( )
2325
+ . impl_ ( )
2326
+ . trait_ ( )
2327
+ . id ( & self . name )
2328
+ . build ( )
2329
+ . with_items ( impl_items)
2330
+ . build_ty ( ty_for_impl) ;
2331
+
2332
+ result. push ( trait_block) ;
2333
+ result. push ( impl_block) ;
2334
+ result. saw_objc ( ) ;
2335
+ }
2336
+ }
2337
+
2338
+
2339
+
2217
2340
pub fn codegen ( context : & mut BindgenContext ) -> Vec < P < ast:: Item > > {
2218
2341
context. gen ( |context| {
2219
2342
let counter = Cell :: new ( 0 ) ;
@@ -2247,6 +2370,25 @@ mod utils {
2247
2370
use syntax:: ast;
2248
2371
use syntax:: ptr:: P ;
2249
2372
2373
+
2374
+ pub fn prepend_objc_header ( ctx : & BindgenContext ,
2375
+ result : & mut Vec < P < ast:: Item > > ) {
2376
+
2377
+ let use_objc = quote_item ! ( ctx. ext_cx( ) ,
2378
+ use objc;
2379
+ )
2380
+ . unwrap ( ) ;
2381
+ let id_type = quote_item ! ( ctx. ext_cx( ) ,
2382
+ #[ allow( non_camel_case_types) ]
2383
+ pub type id = * mut objc:: runtime:: Object ;
2384
+ )
2385
+ . unwrap ( ) ;
2386
+
2387
+ let items = vec ! [ use_objc, id_type] ;
2388
+ let old_items = mem:: replace ( result, items) ;
2389
+ result. extend ( old_items. into_iter ( ) ) ;
2390
+ }
2391
+
2250
2392
pub fn prepend_union_types ( ctx : & BindgenContext ,
2251
2393
result : & mut Vec < P < ast:: Item > > ) {
2252
2394
let prefix = ctx. trait_prefix ( ) ;
0 commit comments