Skip to content

Commit 8b69ba0

Browse files
csmulhernkulp
authored andcommitted
Enables blocklisting of Objective-C methods
1 parent e68b8c0 commit 8b69ba0

File tree

4 files changed

+78
-7
lines changed

4 files changed

+78
-7
lines changed

book/src/objc.md

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ methods found in `NSObject`.
3232
In order to initialize a class `Foo`, you will have to do something like `let
3333
foo = Foo(Foo::alloc().initWithStuff())`.
3434

35+
To blocklist an Objective-C method, you should add the bindgen generated method
36+
path (e.g. `IFoo::method` or `IFoo::class_method`) as a blocklist item.
3537

3638
## Supported Features
3739

src/codegen/mod.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -4191,9 +4191,19 @@ impl CodeGenerator for Function {
41914191
fn objc_method_codegen(
41924192
ctx: &BindgenContext,
41934193
method: &ObjCMethod,
4194+
methods: &mut Vec<proc_macro2::TokenStream>,
41944195
class_name: Option<&str>,
4196+
rust_class_name: &str,
41954197
prefix: &str,
4196-
) -> proc_macro2::TokenStream {
4198+
) {
4199+
// This would ideally resolve the method into an Item, and use
4200+
// Item::process_before_codegen; however, ObjC methods are not currently
4201+
// made into function items.
4202+
let name = format!("{}::{}{}", rust_class_name, prefix, method.rust_name());
4203+
if ctx.options().blocklisted_items.matches(name) {
4204+
return;
4205+
}
4206+
41974207
let signature = method.signature();
41984208
let fn_args = utils::fnsig_arguments(ctx, signature);
41994209
let fn_ret = utils::fnsig_return_ty(ctx, signature);
@@ -4229,11 +4239,11 @@ fn objc_method_codegen(
42294239
let method_name =
42304240
ctx.rust_ident(format!("{}{}", prefix, method.rust_name()));
42314241

4232-
quote! {
4242+
methods.push(quote! {
42334243
unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
42344244
#body
42354245
}
4236-
}
4246+
});
42374247
}
42384248

42394249
impl CodeGenerator for ObjCInterface {
@@ -4249,10 +4259,17 @@ impl CodeGenerator for ObjCInterface {
42494259
debug_assert!(item.is_enabled_for_codegen(ctx));
42504260

42514261
let mut impl_items = vec![];
4262+
let rust_class_name = item.path_for_allowlisting(ctx)[1..].join("::");
42524263

42534264
for method in self.methods() {
4254-
let impl_item = objc_method_codegen(ctx, method, None, "");
4255-
impl_items.push(impl_item);
4265+
objc_method_codegen(
4266+
ctx,
4267+
method,
4268+
&mut impl_items,
4269+
None,
4270+
&rust_class_name,
4271+
"",
4272+
);
42564273
}
42574274

42584275
for class_method in self.class_methods() {
@@ -4262,13 +4279,14 @@ impl CodeGenerator for ObjCInterface {
42624279
.map(|m| m.rust_name())
42634280
.any(|x| x == class_method.rust_name());
42644281
let prefix = if ambiquity { "class_" } else { "" };
4265-
let impl_item = objc_method_codegen(
4282+
objc_method_codegen(
42664283
ctx,
42674284
class_method,
4285+
&mut impl_items,
42684286
Some(self.name()),
4287+
&rust_class_name,
42694288
prefix,
42704289
);
4271-
impl_items.push(impl_item);
42724290
}
42734291

42744292
let trait_name = ctx.rust_ident(self.rust_name());

tests/expectations/tests/objc_blocklist.rs

+42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/headers/objc_blocklist.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// bindgen-flags: --objc-extern-crate --blocklist-item ISomeClass::class_ambiguouslyBlockedMethod --blocklist-item ISomeClass::blockedInstanceMethod -- -x objective-c
2+
// bindgen-osx-only
3+
4+
@interface SomeClass
5+
+ (void)ambiguouslyBlockedMethod;
6+
- (void)ambiguouslyBlockedMethod;
7+
- (void)instanceMethod;
8+
- (void)blockedInstanceMethod;
9+
@end

0 commit comments

Comments
 (0)