From cd299d223fec1ee26e94ba9bd91fb08c357f63ad Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 19 Dec 2024 04:58:08 +0100 Subject: [PATCH] Prepare for using dispatch2 in framework crates --- crates/dispatch2/src/lib.rs | 7 ++++- crates/dispatch2/translation-config.toml | 20 +++++++++++++ crates/header-translator/src/config.rs | 35 +++++++++++++++++++---- crates/header-translator/src/id.rs | 12 ++++++++ crates/header-translator/src/main.rs | 7 +++++ crates/header-translator/src/rust_type.rs | 21 +++++++------- crates/header-translator/src/stmt.rs | 18 +++++------- 7 files changed, 91 insertions(+), 29 deletions(-) create mode 100644 crates/dispatch2/translation-config.toml diff --git a/crates/dispatch2/src/lib.rs b/crates/dispatch2/src/lib.rs index 8101a5391..af5fc40e8 100644 --- a/crates/dispatch2/src/lib.rs +++ b/crates/dispatch2/src/lib.rs @@ -1,6 +1,11 @@ //! # Apple's Dispatch (Grand Central Dispatch) //! -//! This crate allows interaction with the [Apple Dispatch](https://developer.apple.com/documentation/dispatch) library in a safe (``dispatch2`` module) and unsafe (``ffi`` module) way. +//! This crate allows interaction with the Apple's Grand Central Dispatch +//! library in a safe (``dispatch2`` module) and unsafe (``ffi`` module) way. +//! +//! See [Apple's documentation](https://developer.apple.com/documentation/dispatch) +//! and [the source code for libdispatch](https://github.com/swiftlang/swift-corelibs-libdispatch) +//! for more details. //! //! ## Example //! diff --git a/crates/dispatch2/translation-config.toml b/crates/dispatch2/translation-config.toml new file mode 100644 index 000000000..b59e4d504 --- /dev/null +++ b/crates/dispatch2/translation-config.toml @@ -0,0 +1,20 @@ +framework = "Dispatch" +crate = "dispatch2" +required-crates = [] +link = false +skipped = true +custom-lib-rs = true + +macos = "10.0" +maccatalyst = "13.0" +ios = "8.0" +tvos = "9.0" +watchos = "2.0" +visionos = "1.0" +gnustep = true + +typedef.dispatch_object_t.renamed = "DispatchObject" +typedef.dispatch_queue_t.renamed = "Queue" +typedef.dispatch_data_t.renamed = "Data" +typedef.dispatch_group_t.renamed = "Group" +typedef.dispatch_semaphore_t.renamed = "Semaphore" diff --git a/crates/header-translator/src/config.rs b/crates/header-translator/src/config.rs index 0380e0f11..f4df0fd76 100644 --- a/crates/header-translator/src/config.rs +++ b/crates/header-translator/src/config.rs @@ -66,6 +66,17 @@ impl Config { }) } + pub fn replace_typedef_name(&self, id: ItemIdentifier) -> ItemIdentifier { + let library_config = self.library(id.library_name()); + id.map_name(|name| { + library_config + .typedef_data + .get(&name) + .and_then(|data| data.renamed.clone()) + .unwrap_or(name) + }) + } + pub fn to_parse(&self) -> impl Iterator + Clone { self.libraries .iter() @@ -243,11 +254,11 @@ pub struct CategoryData { #[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct ProtocolData { - #[serde(default)] - pub renamed: Option, #[serde(default)] pub skipped: bool, #[serde(default)] + pub renamed: Option, + #[serde(default)] #[serde(rename = "requires-mainthreadonly")] pub requires_mainthreadonly: Option, #[serde(default)] @@ -273,6 +284,22 @@ pub struct EnumData { pub constants: HashMap, } +#[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct StaticData { + #[serde(default)] + pub skipped: bool, +} + +#[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct TypedefData { + #[serde(default)] + pub skipped: bool, + #[serde(default)] + pub renamed: Option, +} + #[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct MethodData { @@ -312,10 +339,6 @@ impl Default for FnData { } } -// TODO -pub type StaticData = StructData; -pub type TypedefData = StructData; - fn unsafe_default() -> bool { true } diff --git a/crates/header-translator/src/id.rs b/crates/header-translator/src/id.rs index 0879bd218..15aecfa56 100644 --- a/crates/header-translator/src/id.rs +++ b/crates/header-translator/src/id.rs @@ -369,6 +369,18 @@ impl ItemIdentifier { } } + pub fn copyhelper(mutable: bool) -> Self { + let name = if mutable { + "MutableCopyingHelper" + } else { + "CopyingHelper" + }; + Self { + name: name.into(), + location: Location::new("Foundation.NSObject"), + } + } + pub fn block() -> Self { Self { name: "Block".into(), diff --git a/crates/header-translator/src/main.rs b/crates/header-translator/src/main.rs index 797ab2197..6a15ce43b 100644 --- a/crates/header-translator/src/main.rs +++ b/crates/header-translator/src/main.rs @@ -183,6 +183,13 @@ fn load_config(workspace_dir: &Path) -> Result { let objc = basic_toml::from_str(&fs::read_to_string(path)?)?; libraries.insert("ObjectiveC".to_string(), objc); + let path = workspace_dir + .join("crates") + .join("dispatch2") + .join("translation-config.toml"); + let objc = basic_toml::from_str(&fs::read_to_string(path)?)?; + libraries.insert("Dispatch".to_string(), objc); + Config::new(libraries) } diff --git a/crates/header-translator/src/rust_type.rs b/crates/header-translator/src/rust_type.rs index 8694f8444..81bc81815 100644 --- a/crates/header-translator/src/rust_type.rs +++ b/crates/header-translator/src/rust_type.rs @@ -600,12 +600,8 @@ impl Ty { TypeKind::Double => Self::Primitive(Primitive::Double), TypeKind::Record => { let declaration = ty.get_declaration().expect("record declaration"); - let name = ty - .get_display_name() - .trim_start_matches("struct ") - .to_string(); Self::Struct { - id: ItemIdentifier::with_name(name, &declaration, context), + id: ItemIdentifier::new(&declaration, context), fields: ty .get_fields() .expect("struct fields") @@ -622,12 +618,8 @@ impl Ty { } TypeKind::Enum => { let declaration = ty.get_declaration().expect("enum declaration"); - let name = ty - .get_display_name() - .trim_start_matches("enum ") - .to_string(); Self::Enum { - id: ItemIdentifier::with_name(name, &declaration, context), + id: ItemIdentifier::new(&declaration, context), ty: Box::new(Ty::parse( declaration .get_enum_underlying_type() @@ -912,6 +904,10 @@ impl Ty { TypeKind::Typedef => { let typedef_name = ty.get_typedef_name().expect("typedef has name"); let declaration = ty.get_declaration().expect("typedef declaration"); + assert_eq!( + typedef_name, + declaration.get_name().expect("typedef declaration name") + ); let to = declaration .get_typedef_underlying_type() .expect("typedef underlying type"); @@ -1024,8 +1020,11 @@ impl Ty { }; } + let id = ItemIdentifier::new(&declaration, context); + let id = context.replace_typedef_name(id); + Self::TypeDef { - id: ItemIdentifier::with_name(typedef_name, &declaration, context), + id, nullability, lifetime, to: Box::new(Self::parse(to, Lifetime::Unspecified, context)), diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 339f35af9..b5db6c554 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1022,15 +1022,17 @@ impl Stmt { } EntityKind::TypedefDecl => { let id = ItemIdentifier::new(entity, context); + let id = context.replace_typedef_name(id); let availability = Availability::parse(entity, context); - if context + let data = context .library(id.library_name()) .typedef_data .get(&id.name) - .map(|data| data.skipped) - .unwrap_or_default() - { + .cloned() + .unwrap_or_default(); + + if data.skipped { return vec![]; } @@ -1983,13 +1985,7 @@ impl Stmt { // need to emit `CopyingHelper` impls to tell Rust which // return types they have. if matches!(&*protocol.name, "NSCopying" | "NSMutableCopying") { - let copy_helper = if protocol.name == "NSCopying" { - protocol.clone().map_name(|_| "CopyingHelper".to_string()) - } else { - protocol - .clone() - .map_name(|_| "MutableCopyingHelper".to_string()) - }; + let copy_helper = ItemIdentifier::copyhelper(protocol.name != "NSCopying"); let mut required_items = self.required_items();