Skip to content

Commit

Permalink
Prepare for using dispatch2 in framework crates
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Dec 19, 2024
1 parent 210befc commit cd299d2
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 29 deletions.
7 changes: 6 additions & 1 deletion crates/dispatch2/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
//!
Expand Down
20 changes: 20 additions & 0 deletions crates/dispatch2/translation-config.toml
Original file line number Diff line number Diff line change
@@ -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"
35 changes: 29 additions & 6 deletions crates/header-translator/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item = (&str, &LibraryConfig)> + Clone {
self.libraries
.iter()
Expand Down Expand Up @@ -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<String>,
#[serde(default)]
pub skipped: bool,
#[serde(default)]
pub renamed: Option<String>,
#[serde(default)]
#[serde(rename = "requires-mainthreadonly")]
pub requires_mainthreadonly: Option<bool>,
#[serde(default)]
Expand All @@ -273,6 +284,22 @@ pub struct EnumData {
pub constants: HashMap<String, StructData>,
}

#[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<String>,
}

#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct MethodData {
Expand Down Expand Up @@ -312,10 +339,6 @@ impl Default for FnData {
}
}

// TODO
pub type StaticData = StructData;
pub type TypedefData = StructData;

fn unsafe_default() -> bool {
true
}
Expand Down
12 changes: 12 additions & 0 deletions crates/header-translator/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
7 changes: 7 additions & 0 deletions crates/header-translator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ fn load_config(workspace_dir: &Path) -> Result<Config, BoxError> {
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)
}

Expand Down
21 changes: 10 additions & 11 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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()
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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)),
Expand Down
18 changes: 7 additions & 11 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![];
}

Expand Down Expand Up @@ -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();

Expand Down

0 comments on commit cd299d2

Please sign in to comment.