mirror of
https://gitee.com/openharmony/third_party_rust_bindgen
synced 2024-12-11 17:14:31 +00:00
Enables blocklisting of Objective-C methods
This commit is contained in:
parent
e68b8c0e2b
commit
8b69ba05aa
@ -32,6 +32,8 @@ methods found in `NSObject`.
|
||||
In order to initialize a class `Foo`, you will have to do something like `let
|
||||
foo = Foo(Foo::alloc().initWithStuff())`.
|
||||
|
||||
To blocklist an Objective-C method, you should add the bindgen generated method
|
||||
path (e.g. `IFoo::method` or `IFoo::class_method`) as a blocklist item.
|
||||
|
||||
## Supported Features
|
||||
|
||||
|
@ -4191,9 +4191,19 @@ impl CodeGenerator for Function {
|
||||
fn objc_method_codegen(
|
||||
ctx: &BindgenContext,
|
||||
method: &ObjCMethod,
|
||||
methods: &mut Vec<proc_macro2::TokenStream>,
|
||||
class_name: Option<&str>,
|
||||
rust_class_name: &str,
|
||||
prefix: &str,
|
||||
) -> proc_macro2::TokenStream {
|
||||
) {
|
||||
// This would ideally resolve the method into an Item, and use
|
||||
// Item::process_before_codegen; however, ObjC methods are not currently
|
||||
// made into function items.
|
||||
let name = format!("{}::{}{}", rust_class_name, prefix, method.rust_name());
|
||||
if ctx.options().blocklisted_items.matches(name) {
|
||||
return;
|
||||
}
|
||||
|
||||
let signature = method.signature();
|
||||
let fn_args = utils::fnsig_arguments(ctx, signature);
|
||||
let fn_ret = utils::fnsig_return_ty(ctx, signature);
|
||||
@ -4229,11 +4239,11 @@ fn objc_method_codegen(
|
||||
let method_name =
|
||||
ctx.rust_ident(format!("{}{}", prefix, method.rust_name()));
|
||||
|
||||
quote! {
|
||||
methods.push(quote! {
|
||||
unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
|
||||
#body
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
impl CodeGenerator for ObjCInterface {
|
||||
@ -4249,10 +4259,17 @@ impl CodeGenerator for ObjCInterface {
|
||||
debug_assert!(item.is_enabled_for_codegen(ctx));
|
||||
|
||||
let mut impl_items = vec![];
|
||||
let rust_class_name = item.path_for_allowlisting(ctx)[1..].join("::");
|
||||
|
||||
for method in self.methods() {
|
||||
let impl_item = objc_method_codegen(ctx, method, None, "");
|
||||
impl_items.push(impl_item);
|
||||
objc_method_codegen(
|
||||
ctx,
|
||||
method,
|
||||
&mut impl_items,
|
||||
None,
|
||||
&rust_class_name,
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
for class_method in self.class_methods() {
|
||||
@ -4262,13 +4279,14 @@ impl CodeGenerator for ObjCInterface {
|
||||
.map(|m| m.rust_name())
|
||||
.any(|x| x == class_method.rust_name());
|
||||
let prefix = if ambiquity { "class_" } else { "" };
|
||||
let impl_item = objc_method_codegen(
|
||||
objc_method_codegen(
|
||||
ctx,
|
||||
class_method,
|
||||
&mut impl_items,
|
||||
Some(self.name()),
|
||||
&rust_class_name,
|
||||
prefix,
|
||||
);
|
||||
impl_items.push(impl_item);
|
||||
}
|
||||
|
||||
let trait_name = ctx.rust_ident(self.rust_name());
|
||||
|
42
tests/expectations/tests/objc_blocklist.rs
generated
Normal file
42
tests/expectations/tests/objc_blocklist.rs
generated
Normal file
@ -0,0 +1,42 @@
|
||||
#![allow(
|
||||
dead_code,
|
||||
non_snake_case,
|
||||
non_camel_case_types,
|
||||
non_upper_case_globals
|
||||
)]
|
||||
#![cfg(target_os = "macos")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate objc;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type id = *mut objc::runtime::Object;
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct SomeClass(pub id);
|
||||
impl std::ops::Deref for SomeClass {
|
||||
type Target = objc::runtime::Object;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*self.0 }
|
||||
}
|
||||
}
|
||||
unsafe impl objc::Message for SomeClass {}
|
||||
impl SomeClass {
|
||||
pub fn alloc() -> Self {
|
||||
Self(unsafe { msg_send!(class!(SomeClass), alloc) })
|
||||
}
|
||||
}
|
||||
impl ISomeClass for SomeClass {}
|
||||
pub trait ISomeClass: Sized + std::ops::Deref {
|
||||
unsafe fn ambiguouslyBlockedMethod(&self)
|
||||
where
|
||||
<Self as std::ops::Deref>::Target: objc::Message + Sized,
|
||||
{
|
||||
msg_send!(*self, ambiguouslyBlockedMethod)
|
||||
}
|
||||
unsafe fn instanceMethod(&self)
|
||||
where
|
||||
<Self as std::ops::Deref>::Target: objc::Message + Sized,
|
||||
{
|
||||
msg_send!(*self, instanceMethod)
|
||||
}
|
||||
}
|
9
tests/headers/objc_blocklist.h
Normal file
9
tests/headers/objc_blocklist.h
Normal file
@ -0,0 +1,9 @@
|
||||
// bindgen-flags: --objc-extern-crate --blocklist-item ISomeClass::class_ambiguouslyBlockedMethod --blocklist-item ISomeClass::blockedInstanceMethod -- -x objective-c
|
||||
// bindgen-osx-only
|
||||
|
||||
@interface SomeClass
|
||||
+ (void)ambiguouslyBlockedMethod;
|
||||
- (void)ambiguouslyBlockedMethod;
|
||||
- (void)instanceMethod;
|
||||
- (void)blockedInstanceMethod;
|
||||
@end
|
Loading…
Reference in New Issue
Block a user