From fabf5eddf0eff8a10570e6b07436adfc5ee4a67b Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Sun, 2 Apr 2023 16:45:37 -0400 Subject: [PATCH 01/23] Added target_os cfg feature to header translator --- crates/header-translator/src/availability.rs | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 264909101..0c1fc1e54 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -15,6 +15,31 @@ struct Unavailable { watchos: bool, tvos: bool, } +impl fmt::Display for Unavailable { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut unavailable_oses = Vec::new(); + if self.ios { + unavailable_oses.push("target_os = \"ios\""); + } + + if self.macos { + unavailable_oses.push("target_os = \"macos\""); + } + if self.watchos { + unavailable_oses.push("target_os = \"tvos\""); + } + + if self.watchos { + unavailable_oses.push("target_os = \"watchos\""); + } + + if !unavailable_oses.is_empty() { + let unavailable_oses = unavailable_oses.join(","); + writeln!(f, "#[cfg(not(any({unavailable_oses})))]")?; + } + Ok(()) + } +} #[derive(Debug, Clone, PartialEq, Default)] struct Versions { @@ -157,6 +182,8 @@ impl fmt::Display for Availability { } } } + writeln!(f, "{}", self.unavailable)?; + // TODO: Emit `cfg` attributes based on `self.unavailable` // TODO: Emit availability checks based on `self.introduced` Ok(()) From 7de510bb9fc6e3d748ce58ac872800dedd79b5ff Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Sun, 2 Apr 2023 17:00:38 -0400 Subject: [PATCH 02/23] Removed irrelevant comment --- crates/header-translator/src/availability.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 0c1fc1e54..0058dd0f0 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -21,14 +21,12 @@ impl fmt::Display for Unavailable { if self.ios { unavailable_oses.push("target_os = \"ios\""); } - if self.macos { unavailable_oses.push("target_os = \"macos\""); } if self.watchos { unavailable_oses.push("target_os = \"tvos\""); } - if self.watchos { unavailable_oses.push("target_os = \"watchos\""); } @@ -184,7 +182,6 @@ impl fmt::Display for Availability { } writeln!(f, "{}", self.unavailable)?; - // TODO: Emit `cfg` attributes based on `self.unavailable` // TODO: Emit availability checks based on `self.introduced` Ok(()) } From 615c4de99926a35ab2ed424feb6aa4ea1dd0d4e1 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Sun, 2 Apr 2023 17:29:09 -0400 Subject: [PATCH 03/23] Remove empty new lines from generation --- crates/header-translator/src/availability.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 0058dd0f0..77d5f7ae0 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -180,7 +180,7 @@ impl fmt::Display for Availability { } } } - writeln!(f, "{}", self.unavailable)?; + write!(f, "{}", self.unavailable)?; // TODO: Emit availability checks based on `self.introduced` Ok(()) From 429ac57c569aa34ca8a4d1964d345bfd21166c1a Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Mon, 3 Apr 2023 17:04:58 -0400 Subject: [PATCH 04/23] Update ref to submodule --- crates/icrate/src/generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 46fbfc138..d1785653e 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 46fbfc13869f718f7e6bd480ae407cfe001cbbb9 +Subproject commit d1785653e35e5bc4b00fe5fb2024336273fbfdea From 3db4f6ccafc14511f11f12d871c487ae5c32461f Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 15:08:37 -0400 Subject: [PATCH 05/23] Added library_unavailability to remove un-needed config attributes --- crates/header-translator/src/availability.rs | 32 ++++++++++++-------- crates/header-translator/src/config.rs | 13 ++++++++ crates/header-translator/src/library.rs | 5 ++- crates/header-translator/src/main.rs | 4 +-- crates/header-translator/src/method.rs | 8 +++-- crates/header-translator/src/output.rs | 7 +++-- crates/header-translator/src/stmt.rs | 30 ++++++++++-------- 7 files changed, 64 insertions(+), 35 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 77d5f7ae0..865646073 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -6,30 +6,35 @@ use clang::{Entity, PlatformAvailability, Version}; use crate::context::Context; #[derive(Debug, Clone, PartialEq, Default)] -struct Unavailable { - ios: bool, - ios_app_extension: bool, - macos: bool, - macos_app_extension: bool, - maccatalyst: bool, - watchos: bool, - tvos: bool, +pub struct Unavailable { + pub(crate) ios: bool, + pub(crate) ios_app_extension: bool, + pub(crate) macos: bool, + pub(crate) macos_app_extension: bool, + pub(crate) maccatalyst: bool, + pub(crate) watchos: bool, + pub(crate) tvos: bool, + pub(crate) library_unavailablility: Box, } impl fmt::Display for Unavailable { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut unavailable_oses = Vec::new(); - if self.ios { + if self.ios && !self.library_unavailablility.ios { unavailable_oses.push("target_os = \"ios\""); } - if self.macos { + if self.macos && !self.library_unavailablility.macos { unavailable_oses.push("target_os = \"macos\""); } - if self.watchos { + if self.tvos && !self.library_unavailablility.tvos { unavailable_oses.push("target_os = \"tvos\""); } - if self.watchos { + if self.watchos && !self.library_unavailablility.watchos { unavailable_oses.push("target_os = \"watchos\""); } + if self.maccatalyst && !self.library_unavailablility.maccatalyst { + unavailable_oses.push("target = \"aarch64-apple-ios-macabi\""); + unavailable_oses.push("target = \"x86_64-apple-ios-macabi\""); + } if !unavailable_oses.is_empty() { let unavailable_oses = unavailable_oses.join(","); @@ -60,12 +65,13 @@ pub struct Availability { } impl Availability { - pub fn parse(entity: &Entity<'_>, _context: &Context<'_>) -> Self { + pub fn parse(entity: &Entity<'_>, _context: &Context<'_>, library_unavailablility: &Unavailable) -> Self { let availabilities = entity .get_platform_availability() .expect("platform availability"); let mut unavailable = Unavailable::default(); + unavailable.library_unavailablility = Box::new(library_unavailablility.clone()); let mut introduced = Versions::default(); let mut deprecated = Versions::default(); let mut message = None; diff --git a/crates/header-translator/src/config.rs b/crates/header-translator/src/config.rs index f6c0d4e29..f21f81849 100644 --- a/crates/header-translator/src/config.rs +++ b/crates/header-translator/src/config.rs @@ -8,6 +8,7 @@ use serde::Deserialize; use crate::data; use crate::rust_type::Ownership; use crate::stmt::Derives; +use crate::availability::Unavailable; #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] @@ -81,6 +82,18 @@ pub struct LibraryData { #[serde(default)] pub watchos: Option, } +impl LibraryData { + pub(crate) fn unavailability(&self) -> Unavailable { + Unavailable { + ios: self.ios.is_none(), + macos: self.macos.is_none(), + tvos: self.tvos.is_none(), + watchos: self.watchos.is_none(), + maccatalyst: self.maccatalyst.is_none(), + ..Default::default() + } + } +} #[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index c1051d189..ed04f6cfa 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -5,16 +5,19 @@ use std::io; use std::path::Path; use crate::file::{File, FILE_PRELUDE}; +use crate::availability::Unavailable; #[derive(Debug, PartialEq, Default)] pub struct Library { pub files: BTreeMap, + pub unavailability: Unavailable, } impl Library { - pub fn new() -> Self { + pub(crate) fn new(unavailability: Unavailable) -> Self { Self { files: BTreeMap::new(), + unavailability, } } diff --git a/crates/header-translator/src/main.rs b/crates/header-translator/src/main.rs index 09bb9423d..652d79eac 100644 --- a/crates/header-translator/src/main.rs +++ b/crates/header-translator/src/main.rs @@ -196,7 +196,7 @@ fn parse_sdk(index: &Index<'_>, sdk: &SdkPath, llvm_target: &str, config: &Confi let tu = get_translation_unit(index, sdk, llvm_target); let mut preprocessing = true; - let mut result = Output::from_libraries(config.libraries.keys()); + let mut result = Output::from_libraries(&config.libraries); let mut library_span = None; let mut library_span_name = String::new(); @@ -269,7 +269,7 @@ fn parse_sdk(index: &Index<'_>, sdk: &SdkPath, llvm_target: &str, config: &Confi preprocessing = false; // No more includes / macro expansions after this line let file = library.files.get_mut(&file_name).expect("file"); - for stmt in Stmt::parse(&entity, &context) { + for stmt in Stmt::parse(&entity, &context, &library.unavailability) { file.add_stmt(stmt); } } diff --git a/crates/header-translator/src/method.rs b/crates/header-translator/src/method.rs index 70ff1270c..0d2043c87 100644 --- a/crates/header-translator/src/method.rs +++ b/crates/header-translator/src/method.rs @@ -3,7 +3,7 @@ use std::fmt; use clang::{Entity, EntityKind, ObjCAttributes, ObjCQualifiers}; use tracing::span::EnteredSpan; -use crate::availability::Availability; +use crate::availability::{Availability, Unavailable}; use crate::config::MethodData; use crate::context::Context; use crate::id::ItemIdentifier; @@ -328,6 +328,7 @@ impl<'tu> PartialMethod<'tu> { data: MethodData, is_protocol: bool, context: &Context<'_>, + library_unavailablility: &Unavailable, ) -> Option<(bool, Method)> { let Self { entity, @@ -346,7 +347,7 @@ impl<'tu> PartialMethod<'tu> { return None; } - let availability = Availability::parse(&entity, context); + let availability = Availability::parse(&entity, context, library_unavailablility); let modifiers = MethodModifiers::parse(&entity, context); @@ -465,6 +466,7 @@ impl PartialProperty<'_> { setter_data: Option, is_protocol: bool, context: &Context<'_>, + library_unavailablility: &Unavailable, ) -> (Option, Option) { let Self { entity, @@ -483,7 +485,7 @@ impl PartialProperty<'_> { return (None, None); } - let availability = Availability::parse(&entity, context); + let availability = Availability::parse(&entity, context, library_unavailablility); let modifiers = MethodModifiers::parse(&entity, context); diff --git a/crates/header-translator/src/output.rs b/crates/header-translator/src/output.rs index f274a56fc..4b8cdb195 100644 --- a/crates/header-translator/src/output.rs +++ b/crates/header-translator/src/output.rs @@ -1,7 +1,8 @@ use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{HashMap}; use std::str::FromStr; -use crate::config::Config; +use crate::config::{Config, LibraryData}; use crate::library::Library; use crate::stmt::Stmt; @@ -11,10 +12,10 @@ pub struct Output { } impl Output { - pub fn from_libraries(libraries: impl IntoIterator>) -> Self { + pub fn from_libraries(libraries: &HashMap) -> Self { let libraries = libraries .into_iter() - .map(|name| (name.into(), Library::new())) + .map(|(name, library_data)| (name.into(), Library::new(library_data.unavailability()))) .collect(); Self { libraries } } diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 1bf0004e5..8c6b6ce24 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -7,7 +7,7 @@ use std::mem; use clang::{Entity, EntityKind, EntityVisitResult}; -use crate::availability::Availability; +use crate::availability::{Availability, Unavailable}; use crate::config::{ClassData, MethodData}; use crate::context::Context; use crate::expr::Expr; @@ -99,6 +99,7 @@ fn parse_objc_decl( mut generics: Option<&mut Vec>, get_data: impl Fn(&str) -> MethodData, context: &Context<'_>, + library_unavailablility: &Unavailable, ) -> (BTreeSet, Vec, Vec) { let mut protocols = BTreeSet::new(); let mut methods = Vec::new(); @@ -153,7 +154,7 @@ fn parse_objc_decl( if !properties.remove(&(partial.is_class, partial.fn_name.clone())) { let data = get_data(&partial.fn_name); if let Some((designated_initializer, method)) = - partial.parse(data, generics.is_none(), context) + partial.parse(data, generics.is_none(), context, library_unavailablility) { if designated_initializer { designated_initializers.push(method.fn_name.clone()); @@ -173,7 +174,7 @@ fn parse_objc_decl( .map(|setter_name| get_data(setter_name)); let (getter, setter) = - partial.parse(getter_data, setter_data, generics.is_none(), context); + partial.parse(getter_data, setter_data, generics.is_none(), context, library_unavailablility); if let Some(getter) = getter { if !properties.insert((getter.is_class, getter.fn_name.clone())) { error!(?setter, "already exisiting property"); @@ -379,7 +380,7 @@ fn parse_fn_param_children(entity: &Entity<'_>, context: &Context<'_>) { } impl Stmt { - pub fn parse(entity: &Entity<'_>, context: &Context<'_>) -> Vec { + pub fn parse(entity: &Entity<'_>, context: &Context<'_>, library_unavailablility: &Unavailable) -> Vec { let _span = debug_span!( "stmt", kind = ?entity.get_kind(), @@ -399,7 +400,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let mut generics = Vec::new(); let (_, methods, designated_initializers) = parse_objc_decl( @@ -408,6 +409,7 @@ impl Stmt { Some(&mut generics), |name| ClassData::get_method_data(data, name), context, + library_unavailablility, ); let mut protocols = Default::default(); @@ -462,7 +464,7 @@ impl Stmt { } EntityKind::ObjCCategoryDecl => { let category = ItemIdentifier::new_optional(entity, context); - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let mut cls = None; entity.visit_children(|entity, _parent| { @@ -505,6 +507,7 @@ impl Stmt { Some(&mut generics), |name| ClassData::get_method_data(data, name), context, + library_unavailablility, ); if !designated_initializers.is_empty() { @@ -550,7 +553,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let (protocols, methods, designated_initializers) = parse_objc_decl( entity, @@ -562,6 +565,7 @@ impl Stmt { .unwrap_or_default() }, context, + library_unavailablility, ); if !designated_initializers.is_empty() { @@ -580,7 +584,7 @@ impl Stmt { } EntityKind::TypedefDecl => { let id = ItemIdentifier::new(entity, context); - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let mut struct_ = None; let mut encoding_name = "?".to_string(); let mut skip_struct = false; @@ -668,7 +672,7 @@ impl Stmt { } EntityKind::StructDecl => { if let Some(name) = entity.get_name() { - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let id = ItemIdentifier::with_name(name, entity, context); if context @@ -716,7 +720,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let ty = entity.get_enum_underlying_type().expect("enum type"); let is_signed = ty.is_signed_integer(); @@ -727,7 +731,7 @@ impl Stmt { immediate_children(entity, |entity, _span| match entity.get_kind() { EntityKind::EnumConstantDecl => { let name = entity.get_name().expect("enum constant name"); - let availability = Availability::parse(&entity, context); + let availability = Availability::parse(&entity, context, library_unavailablility); if data .constants @@ -802,7 +806,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let ty = entity.get_type().expect("var type"); let ty = Ty::parse_static(ty, context); let mut value = None; @@ -856,7 +860,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context); + let availability = Availability::parse(entity, context, library_unavailablility); let result_type = entity.get_result_type().expect("function result type"); let result_type = Ty::parse_function_return(result_type, context); let mut arguments = Vec::new(); From 57d3bd71cef5224b846cb1f427912776acb62122 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 15:11:08 -0400 Subject: [PATCH 06/23] Removed cfg target for maccatalyst --- crates/header-translator/src/availability.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 865646073..66b69af93 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -31,10 +31,6 @@ impl fmt::Display for Unavailable { if self.watchos && !self.library_unavailablility.watchos { unavailable_oses.push("target_os = \"watchos\""); } - if self.maccatalyst && !self.library_unavailablility.maccatalyst { - unavailable_oses.push("target = \"aarch64-apple-ios-macabi\""); - unavailable_oses.push("target = \"x86_64-apple-ios-macabi\""); - } if !unavailable_oses.is_empty() { let unavailable_oses = unavailable_oses.join(","); From 39ce7d59c9884b69a4b7822c2449fab2bd9f46a2 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 18:30:02 -0400 Subject: [PATCH 07/23] Made use of cfg target in library imports --- crates/header-translator/src/availability.rs | 15 ++--- crates/header-translator/src/library.rs | 59 ++++++++++---------- crates/header-translator/src/stmt.rs | 20 +++---- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 66b69af93..0199f7842 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -14,21 +14,22 @@ pub struct Unavailable { pub(crate) maccatalyst: bool, pub(crate) watchos: bool, pub(crate) tvos: bool, - pub(crate) library_unavailablility: Box, + pub(crate) library_unavailablility: Option>, } impl fmt::Display for Unavailable { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut unavailable_oses = Vec::new(); - if self.ios && !self.library_unavailablility.ios { + if self.ios && !self.library_unavailablility.as_ref().map(|u| u.ios).unwrap_or_else(|| false) + { unavailable_oses.push("target_os = \"ios\""); } - if self.macos && !self.library_unavailablility.macos { + if self.macos && !self.library_unavailablility.as_ref().map(|u| u.macos).unwrap_or_else(|| false) { unavailable_oses.push("target_os = \"macos\""); } - if self.tvos && !self.library_unavailablility.tvos { + if self.tvos && !self.library_unavailablility.as_ref().map(|u| u.tvos).unwrap_or_else(|| false) { unavailable_oses.push("target_os = \"tvos\""); } - if self.watchos && !self.library_unavailablility.watchos { + if self.watchos && !self.library_unavailablility.as_ref().map(|u| u.watchos).unwrap_or_else(|| false) { unavailable_oses.push("target_os = \"watchos\""); } @@ -53,7 +54,7 @@ struct Versions { #[derive(Debug, Clone, PartialEq)] pub struct Availability { - unavailable: Unavailable, + pub(crate) unavailable: Unavailable, introduced: Versions, deprecated: Versions, message: Option, @@ -67,7 +68,7 @@ impl Availability { .expect("platform availability"); let mut unavailable = Unavailable::default(); - unavailable.library_unavailablility = Box::new(library_unavailablility.clone()); + unavailable.library_unavailablility = Some(Box::new(library_unavailablility.clone())); let mut introduced = Versions::default(); let mut deprecated = Versions::default(); let mut message = None; diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index ed04f6cfa..38d2f8020 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -63,39 +63,36 @@ impl fmt::Display for Library { // NOTE: some SDK files have '+' in the file name let name = name.replace('+', "_"); for stmt in &file.stmts { - let mut iter = stmt.declared_types(); - if let Some(item) = iter.next() { - // Use a set to deduplicate features, and to have them in - // a consistent order - let mut features = BTreeSet::new(); - stmt.visit_required_types(|item| { - if let Some(feature) = item.feature() { - features.insert(format!("feature = \"{feature}\"")); - } - }); - match features.len() { - 0 => {} - 1 => { - writeln!(f, "#[cfg({})]", features.first().unwrap())?; - } - _ => { - writeln!( - f, - "#[cfg(all({}))]", - features - .iter() - .map(|s| &**s) - .collect::>() - .join(",") - )?; - } + // Use a set to deduplicate features, and to have them in + // a consistent order + let mut features = BTreeSet::new(); + stmt.visit_required_types(|item| { + if let Some(feature) = item.feature() { + features.insert(format!("feature = \"{feature}\"")); } - - writeln!(f, "pub use self::__{name}::{{{item}")?; - for item in iter { - writeln!(f, ", {item}")?; + }); + match features.len() { + 0 => {} + 1 => { + writeln!(f, "#[cfg({})]", features.first().unwrap())?; + } + _ => { + writeln!( + f, + "#[cfg(all({}))]", + features + .iter() + .map(|s| &**s) + .collect::>() + .join(",") + )?; } - writeln!(f, "}};")?; + } + let mut iter = stmt.declared_types(); + + for (item, unavailability) in iter { + writeln!(f, "{unavailability}")?; + writeln!(f, "pub use self::__{name}::{{{item}}};")?; } } } diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 8c6b6ce24..bcf84f19d 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -976,24 +976,24 @@ impl Stmt { } } - pub(crate) fn declared_types(&self) -> impl Iterator { + pub(crate) fn declared_types(&self) -> impl Iterator { match self { - Stmt::ClassDecl { id, .. } => Some(&*id.name), + Stmt::ClassDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), Stmt::Methods { .. } => None, - Stmt::ProtocolDecl { id, .. } => Some(&*id.name), + Stmt::ProtocolDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), Stmt::ProtocolImpl { .. } => None, - Stmt::StructDecl { id, .. } => Some(&*id.name), - Stmt::EnumDecl { id, .. } => id.name.as_deref(), - Stmt::VarDecl { id, .. } => Some(&*id.name), - Stmt::FnDecl { id, body, .. } if body.is_none() => Some(&*id.name), + Stmt::StructDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), + Stmt::EnumDecl { id, availability, .. } => id.name.as_deref().map(|name| (name, &availability.unavailable)), + Stmt::VarDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), + Stmt::FnDecl { id, body, availability, .. } if body.is_none() => Some((&*id.name, &availability.unavailable)), // TODO Stmt::FnDecl { .. } => None, - Stmt::AliasDecl { id, .. } => Some(&*id.name), + Stmt::AliasDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), } .into_iter() .chain({ - if let Stmt::EnumDecl { variants, .. } = self { - variants.iter().map(|(name, _, _)| &**name).collect() + if let Stmt::EnumDecl { variants, availability, .. } = self { + variants.iter().map(|(name, _, _)| (&**name, &availability.unavailable)).collect() } else { vec![] } From e04eaa8c280c7a7fd8d38a678977f79745cab4e1 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 18:32:16 -0400 Subject: [PATCH 08/23] cargo fmt --- crates/header-translator/src/availability.rs | 37 +++++++++-- crates/header-translator/src/config.rs | 2 +- crates/header-translator/src/library.rs | 29 +++++++-- crates/header-translator/src/output.rs | 2 +- crates/header-translator/src/stmt.rs | 67 ++++++++++++++++---- 5 files changed, 110 insertions(+), 27 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 0199f7842..8149a0642 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -19,17 +19,40 @@ pub struct Unavailable { impl fmt::Display for Unavailable { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut unavailable_oses = Vec::new(); - if self.ios && !self.library_unavailablility.as_ref().map(|u| u.ios).unwrap_or_else(|| false) + if self.ios + && !self + .library_unavailablility + .as_ref() + .map(|u| u.ios) + .unwrap_or_else(|| false) { unavailable_oses.push("target_os = \"ios\""); } - if self.macos && !self.library_unavailablility.as_ref().map(|u| u.macos).unwrap_or_else(|| false) { + if self.macos + && !self + .library_unavailablility + .as_ref() + .map(|u| u.macos) + .unwrap_or_else(|| false) + { unavailable_oses.push("target_os = \"macos\""); } - if self.tvos && !self.library_unavailablility.as_ref().map(|u| u.tvos).unwrap_or_else(|| false) { + if self.tvos + && !self + .library_unavailablility + .as_ref() + .map(|u| u.tvos) + .unwrap_or_else(|| false) + { unavailable_oses.push("target_os = \"tvos\""); } - if self.watchos && !self.library_unavailablility.as_ref().map(|u| u.watchos).unwrap_or_else(|| false) { + if self.watchos + && !self + .library_unavailablility + .as_ref() + .map(|u| u.watchos) + .unwrap_or_else(|| false) + { unavailable_oses.push("target_os = \"watchos\""); } @@ -62,7 +85,11 @@ pub struct Availability { } impl Availability { - pub fn parse(entity: &Entity<'_>, _context: &Context<'_>, library_unavailablility: &Unavailable) -> Self { + pub fn parse( + entity: &Entity<'_>, + _context: &Context<'_>, + library_unavailablility: &Unavailable, + ) -> Self { let availabilities = entity .get_platform_availability() .expect("platform availability"); diff --git a/crates/header-translator/src/config.rs b/crates/header-translator/src/config.rs index f21f81849..12c33d637 100644 --- a/crates/header-translator/src/config.rs +++ b/crates/header-translator/src/config.rs @@ -5,10 +5,10 @@ use std::path::Path; use serde::Deserialize; +use crate::availability::Unavailable; use crate::data; use crate::rust_type::Ownership; use crate::stmt::Derives; -use crate::availability::Unavailable; #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index 38d2f8020..fe2d5f9d1 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -4,8 +4,8 @@ use std::fs; use std::io; use std::path::Path; -use crate::file::{File, FILE_PRELUDE}; use crate::availability::Unavailable; +use crate::file::{File, FILE_PRELUDE}; #[derive(Debug, PartialEq, Default)] pub struct Library { @@ -81,16 +81,33 @@ impl fmt::Display for Library { f, "#[cfg(all({}))]", features - .iter() - .map(|s| &**s) - .collect::>() - .join(",") + .iter() + .map(|s| &**s) + .collect::>() + .join(",") )?; } } - let mut iter = stmt.declared_types(); + let iter = stmt.declared_types(); for (item, unavailability) in iter { + match features.len() { + 0 => {} + 1 => { + writeln!(f, "#[cfg({})]", features.first().unwrap())?; + } + _ => { + writeln!( + f, + "#[cfg(all({}))]", + features + .iter() + .map(|s| &**s) + .collect::>() + .join(",") + )?; + } + } writeln!(f, "{unavailability}")?; writeln!(f, "pub use self::__{name}::{{{item}}};")?; } diff --git a/crates/header-translator/src/output.rs b/crates/header-translator/src/output.rs index 4b8cdb195..2270805b8 100644 --- a/crates/header-translator/src/output.rs +++ b/crates/header-translator/src/output.rs @@ -1,5 +1,5 @@ +use std::collections::HashMap; use std::collections::{BTreeMap, BTreeSet}; -use std::collections::{HashMap}; use std::str::FromStr; use crate::config::{Config, LibraryData}; diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index bcf84f19d..8a6c978c0 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -173,8 +173,13 @@ fn parse_objc_decl( .as_ref() .map(|setter_name| get_data(setter_name)); - let (getter, setter) = - partial.parse(getter_data, setter_data, generics.is_none(), context, library_unavailablility); + let (getter, setter) = partial.parse( + getter_data, + setter_data, + generics.is_none(), + context, + library_unavailablility, + ); if let Some(getter) = getter { if !properties.insert((getter.is_class, getter.fn_name.clone())) { error!(?setter, "already exisiting property"); @@ -380,7 +385,11 @@ fn parse_fn_param_children(entity: &Entity<'_>, context: &Context<'_>) { } impl Stmt { - pub fn parse(entity: &Entity<'_>, context: &Context<'_>, library_unavailablility: &Unavailable) -> Vec { + pub fn parse( + entity: &Entity<'_>, + context: &Context<'_>, + library_unavailablility: &Unavailable, + ) -> Vec { let _span = debug_span!( "stmt", kind = ?entity.get_kind(), @@ -672,7 +681,8 @@ impl Stmt { } EntityKind::StructDecl => { if let Some(name) = entity.get_name() { - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = + Availability::parse(entity, context, library_unavailablility); let id = ItemIdentifier::with_name(name, entity, context); if context @@ -731,7 +741,8 @@ impl Stmt { immediate_children(entity, |entity, _span| match entity.get_kind() { EntityKind::EnumConstantDecl => { let name = entity.get_name().expect("enum constant name"); - let availability = Availability::parse(&entity, context, library_unavailablility); + let availability = + Availability::parse(&entity, context, library_unavailablility); if data .constants @@ -978,22 +989,50 @@ impl Stmt { pub(crate) fn declared_types(&self) -> impl Iterator { match self { - Stmt::ClassDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), + Stmt::ClassDecl { + id, availability, .. + } => Some((&*id.name, &availability.unavailable)), Stmt::Methods { .. } => None, - Stmt::ProtocolDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), + Stmt::ProtocolDecl { + id, availability, .. + } => Some((&*id.name, &availability.unavailable)), Stmt::ProtocolImpl { .. } => None, - Stmt::StructDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), - Stmt::EnumDecl { id, availability, .. } => id.name.as_deref().map(|name| (name, &availability.unavailable)), - Stmt::VarDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), - Stmt::FnDecl { id, body, availability, .. } if body.is_none() => Some((&*id.name, &availability.unavailable)), + Stmt::StructDecl { + id, availability, .. + } => Some((&*id.name, &availability.unavailable)), + Stmt::EnumDecl { + id, availability, .. + } => id + .name + .as_deref() + .map(|name| (name, &availability.unavailable)), + Stmt::VarDecl { + id, availability, .. + } => Some((&*id.name, &availability.unavailable)), + Stmt::FnDecl { + id, + body, + availability, + .. + } if body.is_none() => Some((&*id.name, &availability.unavailable)), // TODO Stmt::FnDecl { .. } => None, - Stmt::AliasDecl { id, availability, .. } => Some((&*id.name, &availability.unavailable)), + Stmt::AliasDecl { + id, availability, .. + } => Some((&*id.name, &availability.unavailable)), } .into_iter() .chain({ - if let Stmt::EnumDecl { variants, availability, .. } = self { - variants.iter().map(|(name, _, _)| (&**name, &availability.unavailable)).collect() + if let Stmt::EnumDecl { + variants, + availability, + .. + } = self + { + variants + .iter() + .map(|(name, _, _)| (&**name, &availability.unavailable)) + .collect() } else { vec![] } From cce841aa15e4d8c66e1bb7ecbbac28234e73215d Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 18:34:10 -0400 Subject: [PATCH 09/23] submodule bump --- crates/icrate/src/generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index d1785653e..02a8e45de 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit d1785653e35e5bc4b00fe5fb2024336273fbfdea +Subproject commit 02a8e45de963d52c358e95725c6b4141b0a6eb35 From 747216d35aee6ada11526d8f6d17e41b70148ccd Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 4 Apr 2023 19:45:48 -0400 Subject: [PATCH 10/23] update submodule --- crates/header-translator/src/library.rs | 20 +------------------- crates/icrate/src/generated | 2 +- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index fe2d5f9d1..4b62c073d 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -71,26 +71,8 @@ impl fmt::Display for Library { features.insert(format!("feature = \"{feature}\"")); } }); - match features.len() { - 0 => {} - 1 => { - writeln!(f, "#[cfg({})]", features.first().unwrap())?; - } - _ => { - writeln!( - f, - "#[cfg(all({}))]", - features - .iter() - .map(|s| &**s) - .collect::>() - .join(",") - )?; - } - } - let iter = stmt.declared_types(); - for (item, unavailability) in iter { + for (item, unavailability) in stmt.declared_types() { match features.len() { 0 => {} 1 => { diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 02a8e45de..120e8b1a0 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 02a8e45de963d52c358e95725c6b4141b0a6eb35 +Subproject commit 120e8b1a048ec26fe9bc176807a8ac2db16e1aa6 From ae84ab997cc03418fc98ad157a6fe679c9a0901f Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Wed, 5 Apr 2023 15:34:16 -0400 Subject: [PATCH 11/23] Fix compiling for macos --- crates/header-translator/src/availability.rs | 12 +++++++++--- crates/header-translator/src/library.rs | 4 +++- crates/header-translator/src/stmt.rs | 4 ++-- crates/icrate/src/generated | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 8149a0642..477edf7b1 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -16,8 +16,9 @@ pub struct Unavailable { pub(crate) tvos: bool, pub(crate) library_unavailablility: Option>, } -impl fmt::Display for Unavailable { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + +impl Unavailable { + pub fn list_oses(&self) -> Vec<&str> { let mut unavailable_oses = Vec::new(); if self.ios && !self @@ -55,7 +56,12 @@ impl fmt::Display for Unavailable { { unavailable_oses.push("target_os = \"watchos\""); } - + unavailable_oses + } +} +impl fmt::Display for Unavailable { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let unavailable_oses = self.list_oses(); if !unavailable_oses.is_empty() { let unavailable_oses = unavailable_oses.join(","); writeln!(f, "#[cfg(not(any({unavailable_oses})))]")?; diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index 4b62c073d..79e0eb370 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -90,7 +90,9 @@ impl fmt::Display for Library { )?; } } - writeln!(f, "{unavailability}")?; + if !unavailability.list_oses().is_empty() { + writeln!(f, "{unavailability}")?; + } writeln!(f, "pub use self::__{name}::{{{item}}};")?; } } diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 8a6c978c0..c934f2b5e 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1025,13 +1025,13 @@ impl Stmt { .chain({ if let Stmt::EnumDecl { variants, - availability, + //availability, .. } = self { variants .iter() - .map(|(name, _, _)| (&**name, &availability.unavailable)) + .map(|(name, availability, _)| (&**name, &availability.unavailable)) .collect() } else { vec![] diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 120e8b1a0..b19f0112b 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 120e8b1a048ec26fe9bc176807a8ac2db16e1aa6 +Subproject commit b19f0112b72e58725fce83078d70087660a765f8 From 5fb969ea0d39dacfe73acfd5900078f34501ce7c Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Wed, 5 Apr 2023 15:51:15 -0400 Subject: [PATCH 12/23] Fix iOS and macOS compiling --- crates/header-translator/src/availability.rs | 2 +- crates/header-translator/src/library.rs | 4 +--- crates/header-translator/src/stmt.rs | 12 +++++++++--- crates/icrate/src/generated | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 477edf7b1..d1f7cf12c 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -64,7 +64,7 @@ impl fmt::Display for Unavailable { let unavailable_oses = self.list_oses(); if !unavailable_oses.is_empty() { let unavailable_oses = unavailable_oses.join(","); - writeln!(f, "#[cfg(not(any({unavailable_oses})))]")?; + write!(f, "#[cfg(not(any({unavailable_oses})))]")?; } Ok(()) } diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index 79e0eb370..4c22900f4 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -90,9 +90,7 @@ impl fmt::Display for Library { )?; } } - if !unavailability.list_oses().is_empty() { - writeln!(f, "{unavailability}")?; - } + write!(f, "{unavailability}")?; writeln!(f, "pub use self::__{name}::{{{item}}};")?; } } diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index c934f2b5e..44c7f3db8 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1332,6 +1332,7 @@ impl fmt::Display for Stmt { } writeln!(f, " }}")?; writeln!(f)?; + write!(f, "{availability}")?; writeln!(f, " unsafe impl ProtocolType for dyn {} {{}}", id.name)?; writeln!(f, ");")?; } @@ -1391,18 +1392,20 @@ impl fmt::Display for Stmt { } Self::VarDecl { id, - availability: _, + availability, ty, value: None, } => { + write!(f, "{availability}")?; writeln!(f, "extern_static!({}: {ty});", id.name)?; } Self::VarDecl { id, - availability: _, + availability, ty, value: Some(expr), } => { + write!(f, "{availability}")?; writeln!(f, "extern_static!({}: {ty} = {expr});", id.name)?; } Self::FnDecl { @@ -1468,20 +1471,23 @@ impl fmt::Display for Stmt { } Self::AliasDecl { id, - availability: _, + availability, ty, kind, } => { match kind { Some(UnexposedAttr::TypedEnum) => { + write!(f, "{availability}")?; writeln!(f, "typed_enum!(pub type {} = {ty};);", id.name)?; } Some(UnexposedAttr::TypedExtensibleEnum) => { + write!(f, "{availability}")?; writeln!(f, "typed_extensible_enum!(pub type {} = {ty};);", id.name)?; } None | Some(UnexposedAttr::BridgedTypedef) => { // "bridged" typedefs should just use a normal type // alias. + write!(f, "{availability}")?; writeln!(f, "pub type {} = {ty};", id.name)?; } kind => panic!("invalid alias kind {kind:?} for {ty:?}"), diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index b19f0112b..8379c8f29 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit b19f0112b72e58725fce83078d70087660a765f8 +Subproject commit 8379c8f294ff49d5050f3b75df7faa8f3e916b5c From f9d3d4ff8d0bd8a062df5cf881c35a175ac8bdd8 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Thu, 6 Apr 2023 18:46:01 -0400 Subject: [PATCH 13/23] Fixed enum variant imports --- crates/header-translator/src/availability.rs | 33 ++++++++++--- crates/header-translator/src/cache.rs | 3 +- crates/header-translator/src/stmt.rs | 48 ++++++++++++------- .../header-translator/translation-config.toml | 6 +++ crates/icrate/src/generated | 2 +- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index d1f7cf12c..15caf6089 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -18,7 +18,7 @@ pub struct Unavailable { } impl Unavailable { - pub fn list_oses(&self) -> Vec<&str> { + fn list_unavailable_oses(&self) -> Vec<&str> { let mut unavailable_oses = Vec::new(); if self.ios && !self @@ -27,7 +27,7 @@ impl Unavailable { .map(|u| u.ios) .unwrap_or_else(|| false) { - unavailable_oses.push("target_os = \"ios\""); + unavailable_oses.push("ios"); } if self.macos && !self @@ -36,7 +36,7 @@ impl Unavailable { .map(|u| u.macos) .unwrap_or_else(|| false) { - unavailable_oses.push("target_os = \"macos\""); + unavailable_oses.push("macos"); } if self.tvos && !self @@ -45,7 +45,7 @@ impl Unavailable { .map(|u| u.tvos) .unwrap_or_else(|| false) { - unavailable_oses.push("target_os = \"tvos\""); + unavailable_oses.push("tvos"); } if self.watchos && !self @@ -54,16 +54,35 @@ impl Unavailable { .map(|u| u.watchos) .unwrap_or_else(|| false) { - unavailable_oses.push("target_os = \"watchos\""); + unavailable_oses.push("watchos"); } unavailable_oses } + + /// In some cases of enums, we need to know the availability of the parent enum and the enum + /// variant. + pub fn merge(&self, other: &Self) -> Self { + Self { + ios: self.ios || other.ios, + ios_app_extension: self.ios_app_extension || other.ios_app_extension, + macos: self.macos || other.macos, + macos_app_extension: self.macos_app_extension || other.macos_app_extension, + tvos: self.tvos || other.tvos, + watchos: self.watchos || other.watchos, + maccatalyst: self.maccatalyst || other.maccatalyst, + library_unavailablility: self.library_unavailablility.clone(), + } + } } impl fmt::Display for Unavailable { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let unavailable_oses = self.list_oses(); + let unavailable_oses = self.list_unavailable_oses(); + let unavailable_oses = unavailable_oses + .iter() + .map(|os| format!("target_os = \"{}\"", os)) + .collect::>() + .join(","); if !unavailable_oses.is_empty() { - let unavailable_oses = unavailable_oses.join(","); write!(f, "#[cfg(not(any({unavailable_oses})))]")?; } Ok(()) diff --git a/crates/header-translator/src/cache.rs b/crates/header-translator/src/cache.rs index dd22bc82e..4cfa3bbf2 100644 --- a/crates/header-translator/src/cache.rs +++ b/crates/header-translator/src/cache.rs @@ -164,6 +164,7 @@ impl<'a> Cache<'a> { id, generics, superclasses, + availability, .. } => { let _span = debug_span!("Stmt::ClassDecl", ?id).entered(); @@ -203,7 +204,7 @@ impl<'a> Cache<'a> { cls: id.clone(), generics: generics.clone(), category: cache.category.clone(), - availability: cache.availability.clone(), + availability: availability.clone(), superclasses: superclasses.clone(), methods, description: Some(format!( diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 44c7f3db8..501ef4ffa 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -987,51 +987,54 @@ impl Stmt { } } - pub(crate) fn declared_types(&self) -> impl Iterator { + pub(crate) fn declared_types(&self) -> impl Iterator { match self { Stmt::ClassDecl { id, availability, .. - } => Some((&*id.name, &availability.unavailable)), + } => Some((&*id.name, availability.unavailable.clone())), Stmt::Methods { .. } => None, Stmt::ProtocolDecl { id, availability, .. - } => Some((&*id.name, &availability.unavailable)), + } => Some((&*id.name, availability.unavailable.clone())), Stmt::ProtocolImpl { .. } => None, Stmt::StructDecl { id, availability, .. - } => Some((&*id.name, &availability.unavailable)), + } => Some((&*id.name, availability.unavailable.clone())), Stmt::EnumDecl { id, availability, .. } => id .name .as_deref() - .map(|name| (name, &availability.unavailable)), + .map(|name| (name, availability.unavailable.clone())), Stmt::VarDecl { id, availability, .. - } => Some((&*id.name, &availability.unavailable)), + } => Some((&*id.name, availability.unavailable.clone())), Stmt::FnDecl { id, body, availability, .. - } if body.is_none() => Some((&*id.name, &availability.unavailable)), + } if body.is_none() => Some((&*id.name, availability.unavailable.clone())), // TODO Stmt::FnDecl { .. } => None, Stmt::AliasDecl { id, availability, .. - } => Some((&*id.name, &availability.unavailable)), + } => Some((&*id.name, availability.unavailable.clone())), } .into_iter() .chain({ if let Stmt::EnumDecl { variants, - //availability, + availability, .. } = self { variants .iter() - .map(|(name, availability, _)| (&**name, &availability.unavailable)) + .map(|(name, variant_availability, _)| { + let unavailable = availability.unavailable.merge(&variant_availability.unavailable).clone(); + (&**name, unavailable) + }) .collect() } else { vec![] @@ -1130,6 +1133,7 @@ impl fmt::Display for Stmt { writeln!(f)?; + write!(f, "{availability}")?; if let Some(feature) = id.feature() { writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } @@ -1180,7 +1184,7 @@ impl fmt::Display for Stmt { generics, category, // TODO: Output `#[deprecated]` only on categories - availability: _, + availability, superclasses, methods, description, @@ -1198,6 +1202,8 @@ impl fmt::Display for Stmt { if let Some(feature) = cls.feature() { writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!( f, " unsafe impl{} {}{} {{", @@ -1225,6 +1231,8 @@ impl fmt::Display for Stmt { features.insert(format!("feature = \"{feature}\"")); } }); + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; match features.len() { 0 => {} 1 => { @@ -1260,11 +1268,13 @@ impl fmt::Display for Stmt { cls, generics, protocol, - availability: _, + availability, } => { if let Some(feature) = cls.feature() { writeln!(f, "#[cfg(feature = \"{feature}\")]")?; } + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!( f, "unsafe impl{} {} for {}{} {{}}", @@ -1332,7 +1342,8 @@ impl fmt::Display for Stmt { } writeln!(f, " }}")?; writeln!(f)?; - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, " unsafe impl ProtocolType for dyn {} {{}}", id.name)?; writeln!(f, ");")?; } @@ -1375,9 +1386,9 @@ impl fmt::Display for Stmt { Some(UnexposedAttr::ErrorEnum) => "ns_error_enum", _ => panic!("invalid enum kind"), }; + write!(f, "{availability}")?; writeln!(f, "{macro_name}!(")?; writeln!(f, " #[underlying({ty})]")?; - write!(f, "{availability}")?; writeln!( f, " pub enum {} {{", @@ -1477,17 +1488,20 @@ impl fmt::Display for Stmt { } => { match kind { Some(UnexposedAttr::TypedEnum) => { - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "typed_enum!(pub type {} = {ty};);", id.name)?; } Some(UnexposedAttr::TypedExtensibleEnum) => { - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "typed_extensible_enum!(pub type {} = {ty};);", id.name)?; } None | Some(UnexposedAttr::BridgedTypedef) => { // "bridged" typedefs should just use a normal type // alias. - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "pub type {} = {ty};", id.name)?; } kind => panic!("invalid alias kind {kind:?} for {ty:?}"), diff --git a/crates/header-translator/translation-config.toml b/crates/header-translator/translation-config.toml index b9c2d12f1..dd3d34758 100644 --- a/crates/header-translator/translation-config.toml +++ b/crates/header-translator/translation-config.toml @@ -1542,3 +1542,9 @@ skipped = true # `os_log_t` not defined; skip for now [class.MXMetricManager.methods.makeLogHandleWithCategory] skipped = true + +# The MPMediaQueryAddition definition does not have API_UNAVAILABLE annotations +# where as the MPMediaItem does. This results in problematic conditional compliation: +# https://github.com/phracker/MacOSX-SDKs/blob/041600eda65c6a668f66cb7d56b7d1da3e8bcc93/MacOSX11.3.sdk/System/Library/Frameworks/MediaPlayer.framework/Versions/A/Headers/MPMediaQuery.h#L103-L118 +[class.MPMediaItem.categories.MPMediaQueryAdditions] +skipped = true diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 8379c8f29..b794785a5 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 8379c8f294ff49d5050f3b75df7faa8f3e916b5c +Subproject commit b794785a5e318b0174d0f6bf2782ab4ebd26f7cf From 492e0a8fe72c7298be3528fe079c0c7ed3dc7e74 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Thu, 6 Apr 2023 18:46:35 -0400 Subject: [PATCH 14/23] cargo fmt --- crates/header-translator/src/stmt.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 501ef4ffa..33526833c 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1032,7 +1032,10 @@ impl Stmt { variants .iter() .map(|(name, variant_availability, _)| { - let unavailable = availability.unavailable.merge(&variant_availability.unavailable).clone(); + let unavailable = availability + .unavailable + .merge(&variant_availability.unavailable) + .clone(); (&**name, unavailable) }) .collect() From 7edae2c5f8a10358a017a99ad44a30e1191b2c9d Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Thu, 6 Apr 2023 20:51:04 -0400 Subject: [PATCH 15/23] Fix clippy lints maybe --- crates/header-translator/src/availability.rs | 6 ++++-- crates/header-translator/src/output.rs | 2 +- crates/header-translator/src/stmt.rs | 11 ++++++----- crates/icrate/src/generated | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 15caf6089..a819a1dcb 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -119,8 +119,10 @@ impl Availability { .get_platform_availability() .expect("platform availability"); - let mut unavailable = Unavailable::default(); - unavailable.library_unavailablility = Some(Box::new(library_unavailablility.clone())); + let mut unavailable = Unavailable { + library_unavailablility: Some(Box::new(library_unavailablility.clone())), + ..Default::default() + }; let mut introduced = Versions::default(); let mut deprecated = Versions::default(); let mut message = None; diff --git a/crates/header-translator/src/output.rs b/crates/header-translator/src/output.rs index 2270805b8..c783f7391 100644 --- a/crates/header-translator/src/output.rs +++ b/crates/header-translator/src/output.rs @@ -14,7 +14,7 @@ pub struct Output { impl Output { pub fn from_libraries(libraries: &HashMap) -> Self { let libraries = libraries - .into_iter() + .iter() .map(|(name, library_data)| (name.into(), Library::new(library_data.unavailability()))) .collect(); Self { libraries } diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 33526833c..7aa0265be 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1034,8 +1034,7 @@ impl Stmt { .map(|(name, variant_availability, _)| { let unavailable = availability .unavailable - .merge(&variant_availability.unavailable) - .clone(); + .merge(&variant_availability.unavailable); (&**name, unavailable) }) .collect() @@ -1389,9 +1388,9 @@ impl fmt::Display for Stmt { Some(UnexposedAttr::ErrorEnum) => "ns_error_enum", _ => panic!("invalid enum kind"), }; - write!(f, "{availability}")?; writeln!(f, "{macro_name}!(")?; writeln!(f, " #[underlying({ty})]")?; + write!(f, "{availability}")?; writeln!( f, " pub enum {} {{", @@ -1410,7 +1409,8 @@ impl fmt::Display for Stmt { ty, value: None, } => { - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "extern_static!({}: {ty});", id.name)?; } Self::VarDecl { @@ -1419,7 +1419,8 @@ impl fmt::Display for Stmt { ty, value: Some(expr), } => { - write!(f, "{availability}")?; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "extern_static!({}: {ty} = {expr});", id.name)?; } Self::FnDecl { diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index b794785a5..4c76705a8 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit b794785a5e318b0174d0f6bf2782ab4ebd26f7cf +Subproject commit 4c76705a8d4e172b3620e3ce9caa8129b03505fe From 61d1aa71feab2d06abb4eba6c869b4c29713f9cf Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Thu, 6 Apr 2023 20:55:09 -0400 Subject: [PATCH 16/23] Fix clippy lint --- crates/header-translator/src/availability.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index a819a1dcb..f0a98e383 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -79,7 +79,7 @@ impl fmt::Display for Unavailable { let unavailable_oses = self.list_unavailable_oses(); let unavailable_oses = unavailable_oses .iter() - .map(|os| format!("target_os = \"{}\"", os)) + .map(|os| format!("target_os = \"{os}\"")) .collect::>() .join(","); if !unavailable_oses.is_empty() { From 13a8a32b08d5c4e539995249c076ae0b0966800b Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Sun, 9 Apr 2023 16:21:02 -0400 Subject: [PATCH 17/23] Updates from code review --- crates/header-translator/src/stmt.rs | 17 ++++++++--------- crates/icrate/src/generated | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 7aa0265be..cd14527c6 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1191,6 +1191,8 @@ impl fmt::Display for Stmt { methods, description, } => { + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "extern_methods!(")?; if let Some(description) = description { writeln!(f, " /// {description}")?; @@ -1204,8 +1206,6 @@ impl fmt::Display for Stmt { if let Some(feature) = cls.feature() { writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } - let unavailable = availability.unavailable.clone(); - write!(f, "{unavailable}")?; writeln!( f, " unsafe impl{} {}{} {{", @@ -1233,8 +1233,6 @@ impl fmt::Display for Stmt { features.insert(format!("feature = \"{feature}\"")); } }); - let unavailable = availability.unavailable.clone(); - write!(f, "{unavailable}")?; match features.len() { 0 => {} 1 => { @@ -1292,8 +1290,9 @@ impl fmt::Display for Stmt { protocols, methods, } => { + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "extern_protocol!(")?; - write!(f, "{availability}")?; write!(f, " pub unsafe trait {}", id.name)?; if !protocols.is_empty() { @@ -1344,8 +1343,6 @@ impl fmt::Display for Stmt { } writeln!(f, " }}")?; writeln!(f)?; - let unavailable = availability.unavailable.clone(); - write!(f, "{unavailable}")?; writeln!(f, " unsafe impl ProtocolType for dyn {} {{}}", id.name)?; writeln!(f, ");")?; } @@ -1356,11 +1353,12 @@ impl fmt::Display for Stmt { boxable: _, fields, } => { + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "extern_struct!(")?; if let Some(encoding_name) = encoding_name { writeln!(f, " #[encoding_name({encoding_name:?})]")?; } - write!(f, "{availability}")?; writeln!(f, " pub struct {} {{", id.name)?; for (name, ty) in fields { write!(f, " ")?; @@ -1388,9 +1386,10 @@ impl fmt::Display for Stmt { Some(UnexposedAttr::ErrorEnum) => "ns_error_enum", _ => panic!("invalid enum kind"), }; + let unavailable = availability.unavailable.clone(); + write!(f, "{unavailable}")?; writeln!(f, "{macro_name}!(")?; writeln!(f, " #[underlying({ty})]")?; - write!(f, "{availability}")?; writeln!( f, " pub enum {} {{", diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 4c76705a8..b5b270cad 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 4c76705a8d4e172b3620e3ce9caa8129b03505fe +Subproject commit b5b270cad935a044ecb616bb2ddd9c5f4aef0d94 From 4b34fd4979796fcd59d3109ecd90055fc5875542 Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Mon, 8 May 2023 21:12:52 -0400 Subject: [PATCH 18/23] Remove any when theres only one os --- crates/header-translator/src/availability.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index f0a98e383..24e91f9b8 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -82,8 +82,10 @@ impl fmt::Display for Unavailable { .map(|os| format!("target_os = \"{os}\"")) .collect::>() .join(","); - if !unavailable_oses.is_empty() { + if unavailable_oses.len() > 1 { write!(f, "#[cfg(not(any({unavailable_oses})))]")?; + } if unavailable_oses.len() == 1 { + write!(f, "#[cfg(not({unavailable_oses}))]")?; } Ok(()) } From 677ae87bea2920c7a3c1e14760fdea64465c367c Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 9 May 2023 13:37:49 -0400 Subject: [PATCH 19/23] Move library_unavailability into context --- crates/header-translator/src/availability.rs | 5 ++-- crates/header-translator/src/context.rs | 3 +++ crates/header-translator/src/main.rs | 3 ++- crates/header-translator/src/method.rs | 8 +++--- crates/header-translator/src/stmt.rs | 26 ++++++++------------ 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 24e91f9b8..29da89859 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -114,15 +114,14 @@ pub struct Availability { impl Availability { pub fn parse( entity: &Entity<'_>, - _context: &Context<'_>, - library_unavailablility: &Unavailable, + context: &Context<'_>, ) -> Self { let availabilities = entity .get_platform_availability() .expect("platform availability"); let mut unavailable = Unavailable { - library_unavailablility: Some(Box::new(library_unavailablility.clone())), + library_unavailablility: context.library_unavailability.as_ref().map(|l| Box::new(l.clone())), ..Default::default() }; let mut introduced = Versions::default(); diff --git a/crates/header-translator/src/context.rs b/crates/header-translator/src/context.rs index bbdb06009..fbdc40fc6 100644 --- a/crates/header-translator/src/context.rs +++ b/crates/header-translator/src/context.rs @@ -7,6 +7,7 @@ use clang::source::Location; use clang::Entity; use crate::config::Config; +use crate::availability::Unavailable; pub struct Context<'a> { config: &'a Config, @@ -14,6 +15,7 @@ pub struct Context<'a> { framework_dir: PathBuf, include_dir: PathBuf, system_headers: HashSet<&'static Path>, + pub library_unavailability: Option, } impl<'a> Context<'a> { @@ -29,6 +31,7 @@ impl<'a> Context<'a> { Path::new("objc/NSObject.h"), Path::new("objc/NSObjCRuntime.h"), ]), + library_unavailability: None, } } diff --git a/crates/header-translator/src/main.rs b/crates/header-translator/src/main.rs index 652d79eac..0a19c6166 100644 --- a/crates/header-translator/src/main.rs +++ b/crates/header-translator/src/main.rs @@ -269,7 +269,8 @@ fn parse_sdk(index: &Index<'_>, sdk: &SdkPath, llvm_target: &str, config: &Confi preprocessing = false; // No more includes / macro expansions after this line let file = library.files.get_mut(&file_name).expect("file"); - for stmt in Stmt::parse(&entity, &context, &library.unavailability) { + context.library_unavailability = Some(library.unavailability.clone()); + for stmt in Stmt::parse(&entity, &context) { file.add_stmt(stmt); } } diff --git a/crates/header-translator/src/method.rs b/crates/header-translator/src/method.rs index 0d2043c87..70ff1270c 100644 --- a/crates/header-translator/src/method.rs +++ b/crates/header-translator/src/method.rs @@ -3,7 +3,7 @@ use std::fmt; use clang::{Entity, EntityKind, ObjCAttributes, ObjCQualifiers}; use tracing::span::EnteredSpan; -use crate::availability::{Availability, Unavailable}; +use crate::availability::Availability; use crate::config::MethodData; use crate::context::Context; use crate::id::ItemIdentifier; @@ -328,7 +328,6 @@ impl<'tu> PartialMethod<'tu> { data: MethodData, is_protocol: bool, context: &Context<'_>, - library_unavailablility: &Unavailable, ) -> Option<(bool, Method)> { let Self { entity, @@ -347,7 +346,7 @@ impl<'tu> PartialMethod<'tu> { return None; } - let availability = Availability::parse(&entity, context, library_unavailablility); + let availability = Availability::parse(&entity, context); let modifiers = MethodModifiers::parse(&entity, context); @@ -466,7 +465,6 @@ impl PartialProperty<'_> { setter_data: Option, is_protocol: bool, context: &Context<'_>, - library_unavailablility: &Unavailable, ) -> (Option, Option) { let Self { entity, @@ -485,7 +483,7 @@ impl PartialProperty<'_> { return (None, None); } - let availability = Availability::parse(&entity, context, library_unavailablility); + let availability = Availability::parse(&entity, context); let modifiers = MethodModifiers::parse(&entity, context); diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index cd14527c6..64df7c098 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -99,7 +99,6 @@ fn parse_objc_decl( mut generics: Option<&mut Vec>, get_data: impl Fn(&str) -> MethodData, context: &Context<'_>, - library_unavailablility: &Unavailable, ) -> (BTreeSet, Vec, Vec) { let mut protocols = BTreeSet::new(); let mut methods = Vec::new(); @@ -154,7 +153,7 @@ fn parse_objc_decl( if !properties.remove(&(partial.is_class, partial.fn_name.clone())) { let data = get_data(&partial.fn_name); if let Some((designated_initializer, method)) = - partial.parse(data, generics.is_none(), context, library_unavailablility) + partial.parse(data, generics.is_none(), context) { if designated_initializer { designated_initializers.push(method.fn_name.clone()); @@ -178,7 +177,6 @@ fn parse_objc_decl( setter_data, generics.is_none(), context, - library_unavailablility, ); if let Some(getter) = getter { if !properties.insert((getter.is_class, getter.fn_name.clone())) { @@ -388,7 +386,6 @@ impl Stmt { pub fn parse( entity: &Entity<'_>, context: &Context<'_>, - library_unavailablility: &Unavailable, ) -> Vec { let _span = debug_span!( "stmt", @@ -409,7 +406,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let mut generics = Vec::new(); let (_, methods, designated_initializers) = parse_objc_decl( @@ -418,7 +415,6 @@ impl Stmt { Some(&mut generics), |name| ClassData::get_method_data(data, name), context, - library_unavailablility, ); let mut protocols = Default::default(); @@ -473,7 +469,7 @@ impl Stmt { } EntityKind::ObjCCategoryDecl => { let category = ItemIdentifier::new_optional(entity, context); - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let mut cls = None; entity.visit_children(|entity, _parent| { @@ -516,7 +512,6 @@ impl Stmt { Some(&mut generics), |name| ClassData::get_method_data(data, name), context, - library_unavailablility, ); if !designated_initializers.is_empty() { @@ -562,7 +557,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let (protocols, methods, designated_initializers) = parse_objc_decl( entity, @@ -574,7 +569,6 @@ impl Stmt { .unwrap_or_default() }, context, - library_unavailablility, ); if !designated_initializers.is_empty() { @@ -593,7 +587,7 @@ impl Stmt { } EntityKind::TypedefDecl => { let id = ItemIdentifier::new(entity, context); - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let mut struct_ = None; let mut encoding_name = "?".to_string(); let mut skip_struct = false; @@ -682,7 +676,7 @@ impl Stmt { EntityKind::StructDecl => { if let Some(name) = entity.get_name() { let availability = - Availability::parse(entity, context, library_unavailablility); + Availability::parse(entity, context); let id = ItemIdentifier::with_name(name, entity, context); if context @@ -730,7 +724,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let ty = entity.get_enum_underlying_type().expect("enum type"); let is_signed = ty.is_signed_integer(); @@ -742,7 +736,7 @@ impl Stmt { EntityKind::EnumConstantDecl => { let name = entity.get_name().expect("enum constant name"); let availability = - Availability::parse(&entity, context, library_unavailablility); + Availability::parse(&entity, context); if data .constants @@ -817,7 +811,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let ty = entity.get_type().expect("var type"); let ty = Ty::parse_static(ty, context); let mut value = None; @@ -871,7 +865,7 @@ impl Stmt { return vec![]; } - let availability = Availability::parse(entity, context, library_unavailablility); + let availability = Availability::parse(entity, context); let result_type = entity.get_result_type().expect("function result type"); let result_type = Ty::parse_function_return(result_type, context); let mut arguments = Vec::new(); From 0df1d04f264661e7caef642e9eac73569140348a Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 9 May 2023 13:38:23 -0400 Subject: [PATCH 20/23] cargo clippy --- crates/header-translator/src/availability.rs | 13 +++++++------ crates/header-translator/src/context.rs | 2 +- crates/header-translator/src/stmt.rs | 19 +++++-------------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/crates/header-translator/src/availability.rs b/crates/header-translator/src/availability.rs index 29da89859..ddef2a4b9 100644 --- a/crates/header-translator/src/availability.rs +++ b/crates/header-translator/src/availability.rs @@ -84,7 +84,8 @@ impl fmt::Display for Unavailable { .join(","); if unavailable_oses.len() > 1 { write!(f, "#[cfg(not(any({unavailable_oses})))]")?; - } if unavailable_oses.len() == 1 { + } + if unavailable_oses.len() == 1 { write!(f, "#[cfg(not({unavailable_oses}))]")?; } Ok(()) @@ -112,16 +113,16 @@ pub struct Availability { } impl Availability { - pub fn parse( - entity: &Entity<'_>, - context: &Context<'_>, - ) -> Self { + pub fn parse(entity: &Entity<'_>, context: &Context<'_>) -> Self { let availabilities = entity .get_platform_availability() .expect("platform availability"); let mut unavailable = Unavailable { - library_unavailablility: context.library_unavailability.as_ref().map(|l| Box::new(l.clone())), + library_unavailablility: context + .library_unavailability + .as_ref() + .map(|l| Box::new(l.clone())), ..Default::default() }; let mut introduced = Versions::default(); diff --git a/crates/header-translator/src/context.rs b/crates/header-translator/src/context.rs index fbdc40fc6..a882c3739 100644 --- a/crates/header-translator/src/context.rs +++ b/crates/header-translator/src/context.rs @@ -6,8 +6,8 @@ use apple_sdk::SdkPath; use clang::source::Location; use clang::Entity; -use crate::config::Config; use crate::availability::Unavailable; +use crate::config::Config; pub struct Context<'a> { config: &'a Config, diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 64df7c098..525ef0558 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -172,12 +172,8 @@ fn parse_objc_decl( .as_ref() .map(|setter_name| get_data(setter_name)); - let (getter, setter) = partial.parse( - getter_data, - setter_data, - generics.is_none(), - context, - ); + let (getter, setter) = + partial.parse(getter_data, setter_data, generics.is_none(), context); if let Some(getter) = getter { if !properties.insert((getter.is_class, getter.fn_name.clone())) { error!(?setter, "already exisiting property"); @@ -383,10 +379,7 @@ fn parse_fn_param_children(entity: &Entity<'_>, context: &Context<'_>) { } impl Stmt { - pub fn parse( - entity: &Entity<'_>, - context: &Context<'_>, - ) -> Vec { + pub fn parse(entity: &Entity<'_>, context: &Context<'_>) -> Vec { let _span = debug_span!( "stmt", kind = ?entity.get_kind(), @@ -675,8 +668,7 @@ impl Stmt { } EntityKind::StructDecl => { if let Some(name) = entity.get_name() { - let availability = - Availability::parse(entity, context); + let availability = Availability::parse(entity, context); let id = ItemIdentifier::with_name(name, entity, context); if context @@ -735,8 +727,7 @@ impl Stmt { immediate_children(entity, |entity, _span| match entity.get_kind() { EntityKind::EnumConstantDecl => { let name = entity.get_name().expect("enum constant name"); - let availability = - Availability::parse(&entity, context); + let availability = Availability::parse(&entity, context); if data .constants From 9bd8ab39462104c2162b2e81bc9a0aad7e58bf0a Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 9 May 2023 14:18:53 -0400 Subject: [PATCH 21/23] cargo fmt --- crates/header-translator/src/stmt.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 1ad49b6a1..03094c42b 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1158,7 +1158,12 @@ impl Stmt { pub(crate) fn declared_types(&self) -> impl Iterator { match self { - Stmt::ClassDecl { id, skipped, availability, .. } => { + Stmt::ClassDecl { + id, + skipped, + availability, + .. + } => { if *skipped { None } else { From dbe178265a81185c9a596f0e6f80541b4f64892e Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Tue, 9 May 2023 14:20:38 -0400 Subject: [PATCH 22/23] Update submodule for new header-translator --- crates/icrate/src/generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index b5b270cad..9d4423109 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit b5b270cad935a044ecb616bb2ddd9c5f4aef0d94 +Subproject commit 9d44231090231847bf07c65467c900c7fcfb0f29 From f1791dc990423a91c5d02796d0de1e358dd7436c Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Sun, 21 May 2023 16:49:04 -0400 Subject: [PATCH 23/23] Fix superclass availability --- crates/header-translator/src/stmt.rs | 6 +++++- crates/icrate/src/generated | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 03094c42b..ae39e0080 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -579,7 +579,7 @@ impl Stmt { cls: id.clone(), generics: generics.clone(), category: ItemIdentifier::with_name(None, entity, context), - availability: Availability::parse(entity, context), + availability: availability.clone(), superclasses: superclasses.clone(), methods, description: Some(format!( @@ -1340,6 +1340,7 @@ impl fmt::Display for Stmt { writeln!(f)?; + write!(f, "{availability}")?; if let Some(feature) = &main_feature_gate { writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } @@ -1417,6 +1418,7 @@ impl fmt::Display for Stmt { if let Some(feature) = cls.feature() { writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } + write!(f, "{unavailable}")?; writeln!( f, " unsafe impl{} {}{} {{", @@ -1472,6 +1474,7 @@ impl fmt::Display for Stmt { // Assume new methods require no extra features writeln!(f, " #[cfg(feature = \"{feature}\")]")?; } + write!(f, "{unavailable}")?; writeln!( f, "impl{} DefaultId for {}{} {{", @@ -1601,6 +1604,7 @@ impl fmt::Display for Stmt { )?; } } + write!(f, "{unavailable}")?; writeln!(f, "{method}")?; } writeln!(f, " }}")?; diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 9d4423109..d23e6b749 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 9d44231090231847bf07c65467c900c7fcfb0f29 +Subproject commit d23e6b749470c0dfdf8722ccc6d70d52cca7dc7d