Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objective-c categories aren't included in inheritance traits and impl blocks #1779

Open
simlay opened this issue May 13, 2020 · 2 comments
Open

Comments

@simlay
Copy link
Contributor

simlay commented May 13, 2020

Objective-c categories are a way of extending a given objective-c class. It almost feels like categories are used to organize various sections of their codebase. As a result, there are a lot of categories in the apple frameworks.

In #1750 I added better inheritance support for the binding generation but didn't add the impl blocks for the traits generated from the Objective-c categories.

It's unclear to me how to best implement this because a given class has no reference to the classes it implements. The only reference to the classes are from the categories to the classes they extend.

Input C/C++ Header

// bindgen-flags: --objc-extern-crate -- -x objective-c
// bindgen-osx-only

@interface Foo
-(void)method;
@end

@interface Foo (BarCategory)
-(void)categoryMethod;
@end

@interface Bar: Foo
@end

Bindgen Invocation

$ bindgen input.h --objc-extern-crate -- -x objective-c

Actual Results

/* automatically generated by rust-bindgen */

#![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(Clone, Copy)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {
    unsafe fn method(self)
    where
        <Self as std::ops::Deref>::Target: objc::Message + Sized,
    {
        msg_send!(self, method)
    }
}
impl Foo_BarCategory for Foo {}
pub trait Foo_BarCategory: Sized + std::ops::Deref {
    unsafe fn categoryMethod(self)
    where
        <Self as std::ops::Deref>::Target: objc::Message + Sized,
    {
        msg_send!(self, categoryMethod)
    }
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}
impl IBar for Bar {}
pub trait IBar: Sized + std::ops::Deref {}

Expected Results

impl Foo_BarCategory for Bar {} is missing and should be something like the following:

...
impl IFoo for Bar {}
impl IBar for Bar {}
impl Foo_BarCategory for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
@afranchuk
Copy link

afranchuk commented Aug 29, 2023

Adding support for categories (even if ugly or with manual steps in the Builder configuration) would be much appreciated. For instance, NSString and NSMutableString have their convenient APIs entirely in categories, making it very difficult to work with some of the most primitive classes in apple frameworks.

@afranchuk
Copy link

Adding support for categories (even if ugly or with manual steps in the Builder configuration) would be much appreciated. For instance, NSString and NSMutableString have their convenient APIs entirely in categories, making it very difficult to work with some of the most primitive classes in apple frameworks.

I misinterpreted the purpose of this bug, and now realize that categories are supported: you have to allowlist CLASS_CATEGORY, which I didn't expect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants