summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikko Lehtonen <scoopr@iki.fi>2017-05-01 03:53:43 +0300
committerMikko Lehtonen <scoopr@iki.fi>2017-05-03 00:54:14 +0300
commit839036dc264dc6ddcad3e8f51708a25ecb45a55e (patch)
treeb1296aa0f882d437f6ddb2f023890a83a25385e6
parentcf41afd5e280d275d9a4c596ebc13eb5e30a8949 (diff)
objc: Handle class and instance method with same name
Prefixes the clashing class method with class_ prefix
-rw-r--r--src/codegen/mod.rs22
-rw-r--r--tests/expectations/tests/objc_method_clash.rs22
-rw-r--r--tests/headers/objc_method_clash.h7
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