Skip to content

Commit a62b9dc

Browse files
committed
Add method_family attribute
Spelled as `#[unsafe(method_family($family))]`. This was previously a private "modifier" inside `#[method(...)]`, but it makes sense to have it as a separate attribute, if not only so that we can reduce the amount of private API that framework crates depend on.
1 parent 67e6f41 commit a62b9dc

15 files changed

+428
-228
lines changed

crates/header-translator/src/method.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -768,20 +768,31 @@ impl fmt::Display for Method {
768768
}
769769

770770
let id_mm_name = match &self.memory_management {
771-
MemoryManagement::IdCopy => Some("Copy"),
772-
MemoryManagement::IdMutableCopy => Some("MutableCopy"),
773-
MemoryManagement::IdNew => Some("New"),
774-
MemoryManagement::IdInit => Some("Init"),
775-
MemoryManagement::IdOther => Some("Other"),
771+
// MemoryManagement::IdAlloc => Some("alloc"), // Unsupported
772+
MemoryManagement::IdCopy => Some("copy"),
773+
MemoryManagement::IdMutableCopy => Some("mutableCopy"),
774+
MemoryManagement::IdNew => Some("new"),
775+
MemoryManagement::IdInit => Some("init"),
776+
MemoryManagement::IdOther => Some("none"),
776777
MemoryManagement::Normal => None,
777778
};
778779
if let Some(id_mm_name) = id_mm_name {
779-
write!(f, " #[method_id(@__method_family {id_mm_name} ")?;
780+
// TODO: Be explicit about when we emit this for better
781+
// compile-times, and when we do it for soundness.
782+
writeln!(f, " #[unsafe(method_family({id_mm_name}))]")?;
783+
};
784+
785+
let method_kind = if self.memory_management == MemoryManagement::Normal {
786+
"method"
780787
} else {
781-
write!(f, " #[method(")?;
782-
}
788+
"method_id"
789+
};
783790
let error_trailing = if self.is_error { "_" } else { "" };
784-
writeln!(f, "{}{})]", self.selector, error_trailing)?;
791+
writeln!(
792+
f,
793+
" #[{}({}{})]",
794+
method_kind, self.selector, error_trailing
795+
)?;
785796

786797
//
787798
// Signature

crates/objc2/src/__macro_helpers/method_family.rs

+17
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,30 @@
2121
#[derive(Debug)]
2222
pub struct MethodFamily<const INNER: u8> {}
2323

24+
/// The `new` family.
2425
pub type New = MethodFamily<1>;
26+
/// The `alloc` family.
2527
pub type Alloc = MethodFamily<2>;
28+
/// The `init` family.
2629
pub type Init = MethodFamily<3>;
30+
/// The `copy` family.
2731
pub type Copy = MethodFamily<4>;
32+
/// The `mutableCopy` family.
2833
pub type MutableCopy = MethodFamily<5>;
34+
/// No family.
2935
pub type Other = MethodFamily<6>;
3036

37+
/// Helper module where `#[method_family($family:ident)]` will import its
38+
/// value from.
39+
#[allow(non_camel_case_types)]
40+
pub mod method_family_import {
41+
// Rename to match Clang's `__attribute__((objc_method_family(family)))`.
42+
pub use super::{
43+
Alloc as alloc, Copy as copy, Init as init, MutableCopy as mutableCopy, New as new,
44+
Other as none,
45+
};
46+
}
47+
3148
pub const fn method_family(selector: &str) -> u8 {
3249
let selector = selector.as_bytes();
3350
match (

crates/objc2/src/__macro_helpers/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub use self::define_class::{
4141
pub use self::defined_ivars::DefinedIvarsHelper;
4242
pub use self::image_info::ImageInfo;
4343
pub use self::method_family::{
44-
method_family, Alloc, Copy, Init, MethodFamily, MutableCopy, New, Other,
44+
method_family, method_family_import, Alloc, Copy, Init, MethodFamily, MutableCopy, New, Other,
4545
};
4646
pub use self::module_info::ModuleInfo;
4747
pub use self::msg_send::MsgSend;

0 commit comments

Comments
 (0)