diff options
author | Mikko Lehtonen <scoopr@iki.fi> | 2017-05-01 03:53:43 +0300 |
---|---|---|
committer | Mikko Lehtonen <scoopr@iki.fi> | 2017-05-03 00:54:14 +0300 |
commit | 839036dc264dc6ddcad3e8f51708a25ecb45a55e (patch) | |
tree | b1296aa0f882d437f6ddb2f023890a83a25385e6 | |
parent | cf41afd5e280d275d9a4c596ebc13eb5e30a8949 (diff) |
objc: Handle class and instance method with same name
Prefixes the clashing class method with class_ prefix
-rw-r--r-- | src/codegen/mod.rs | 22 | ||||
-rw-r--r-- | tests/expectations/tests/objc_method_clash.rs | 22 | ||||
-rw-r--r-- | tests/headers/objc_method_clash.h | 7 |
3 files changed, 46 insertions, 5 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 39b115fa..001b2909 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2805,7 +2805,8 @@ impl CodeGenerator for Function { fn objc_method_codegen(ctx: &BindgenContext, method: &ObjCMethod, - class_name: Option<&str>) + class_name: Option<&str>, + prefix: &str) -> (ast::ImplItem, ast::TraitItem) { let signature = method.signature(); let fn_args = utils::fnsig_arguments(ctx, signature); @@ -2864,9 +2865,11 @@ fn objc_method_codegen(ctx: &BindgenContext, let attrs = vec![]; + let method_name = format!("{}{}", prefix, method.rust_name()); + let impl_item = ast::ImplItem { id: ast::DUMMY_NODE_ID, - ident: ctx.rust_ident(method.rust_name()), + ident: ctx.rust_ident(&method_name), vis: ast::Visibility::Inherited, // Public, attrs: attrs.clone(), node: ast::ImplItemKind::Method(sig.clone(), P(block)), @@ -2876,7 +2879,7 @@ fn objc_method_codegen(ctx: &BindgenContext, let trait_item = ast::TraitItem { id: ast::DUMMY_NODE_ID, - ident: ctx.rust_ident(method.rust_name()), + ident: ctx.rust_ident(&method_name), attrs: attrs, node: ast::TraitItemKind::Method(sig, None), span: ctx.span(), @@ -2898,14 +2901,23 @@ impl CodeGenerator for ObjCInterface { for method in self.methods() { let (impl_item, trait_item) = - objc_method_codegen(ctx, method, None); + objc_method_codegen(ctx, method, None, ""); impl_items.push(impl_item); trait_items.push(trait_item) } + let instance_method_names : Vec<_> = self.methods().iter().map( { |m| m.rust_name() } ).collect(); + for class_method in self.class_methods() { + + let ambiquity = instance_method_names.contains(&class_method.rust_name()); + let prefix = if ambiquity { + "class_" + } else { + "" + }; let (impl_item, trait_item) = - objc_method_codegen(ctx, class_method, Some(self.name())); + objc_method_codegen(ctx, class_method, Some(self.name()), prefix); impl_items.push(impl_item); trait_items.push(trait_item) } diff --git a/tests/expectations/tests/objc_method_clash.rs b/tests/expectations/tests/objc_method_clash.rs new file mode 100644 index 00000000..07dedc4c --- /dev/null +++ b/tests/expectations/tests/objc_method_clash.rs @@ -0,0 +1,22 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + +#![cfg(target_os="macos")] + +#[macro_use] +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(); +} +impl Foo for id { + unsafe fn foo(self) { msg_send!(self , foo) } + unsafe fn class_foo() { + msg_send!(objc :: runtime :: Class :: get ( "Foo" ) . expect ( + "Couldn\'t find Foo" ) , foo) + } +} diff --git a/tests/headers/objc_method_clash.h b/tests/headers/objc_method_clash.h new file mode 100644 index 00000000..a56e39db --- /dev/null +++ b/tests/headers/objc_method_clash.h @@ -0,0 +1,7 @@ +// bindgen-flags: --objc-extern-crate -- -x objective-c +// bindgen-osx-only + +@interface Foo ++ (void)foo; +- (void)foo; +@end |