From 0af248649d12c56a844366b09562f6d63350cd5a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 11 Dec 2024 23:07:48 +0100 Subject: [PATCH] Use Clang's -fmodules Clang has something called "modules", which are a mechanism to describe and combine a set of headers into a single cohesive unit: https://clang.llvm.org/docs/Modules.html This is what Swift uses when mapping frameworks, so it makes sense for us to do the same. Objective-C also recently gained the `@import` syntax to do the same. This should unblock our support for umbrella frameworks, makes it easier to use API notes in the future, and is generally more correct. --- Cargo.lock | 3 + crates/header-translator/Cargo.toml | 1 + crates/header-translator/src/config.rs | 18 + crates/header-translator/src/context.rs | 106 +++--- crates/header-translator/src/expr.rs | 9 +- crates/header-translator/src/id.rs | 52 ++- crates/header-translator/src/lib.rs | 2 +- crates/header-translator/src/library.rs | 21 +- crates/header-translator/src/main.rs | 287 +++++++-------- crates/header-translator/src/rust_type.rs | 92 +++-- crates/header-translator/src/thread_safety.rs | 14 +- .../header-translator/src/unexposed_attr.rs | 81 ++++- .../src/topics/about_generated/CHANGELOG.md | 1 + framework-crates/objc2-app-kit/Cargo.toml | 11 +- .../objc2-app-kit/translation-config.toml | 2 + .../Cargo.toml | 6 +- .../Cargo.toml | 39 +- .../objc2-av-kit/translation-config.toml | 4 + .../objc2-contacts-ui/translation-config.toml | 4 + framework-crates/objc2-core-data/Cargo.toml | 25 +- .../objc2-core-foundation/Cargo.toml | 4 +- .../translation-config.toml | 2 + framework-crates/objc2-core-image/Cargo.toml | 27 +- framework-crates/objc2-core-image/src/lib.rs | 1 + .../objc2-core-image/translation-config.toml | 3 + .../translation-config.toml | 2 + .../objc2-event-kit/translation-config.toml | 3 + .../objc2-file-provider/Cargo.toml | 34 +- .../translation-config.toml | 2 + framework-crates/objc2-foundation/Cargo.toml | 2 + .../objc2-foundation/translation-config.toml | 4 + .../objc2-health-kit/translation-config.toml | 2 + framework-crates/objc2-io-surface/Cargo.toml | 14 +- .../objc2-map-kit/translation-config.toml | 2 + .../translation-config.toml | 2 + .../objc2-ml-compute/translation-config.toml | 2 + .../objc2-multipeer-connectivity/Cargo.toml | 2 + .../translation-config.toml | 2 + .../objc2-network-extension/Cargo.toml | 336 +----------------- .../objc2-photos/translation-config.toml | 3 + framework-crates/objc2-quartz-core/Cargo.toml | 4 - .../objc2-social/translation-config.toml | 2 + framework-crates/objc2-ui-kit/Cargo.toml | 2 +- .../objc2-ui-kit/translation-config.toml | 9 + .../translation-config.toml | 2 + framework-crates/objc2-vision/Cargo.toml | 3 +- .../objc2-vision/translation-config.toml | 6 + generated | 2 +- 48 files changed, 569 insertions(+), 688 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d8f05292..2ca10ec6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,7 @@ dependencies = [ "heck", "lenient_semver_parser", "proc-macro2", + "regex", "semver", "serde", "syn", @@ -593,6 +594,7 @@ dependencies = [ "bitflags", "block2", "objc2", + "objc2-cloud-kit", "objc2-foundation", ] @@ -627,6 +629,7 @@ dependencies = [ "objc2", "objc2-core-foundation", "objc2-core-graphics", + "objc2-core-ml", "objc2-core-video", "objc2-foundation", "objc2-io-surface", diff --git a/crates/header-translator/Cargo.toml b/crates/header-translator/Cargo.toml index 8938fac5e..cea2d1863 100644 --- a/crates/header-translator/Cargo.toml +++ b/crates/header-translator/Cargo.toml @@ -23,6 +23,7 @@ heck = "0.5" semver = { version = "1.0", features = ["serde"] } lenient_semver_parser = "0.4" four-char-code = "2.2.0" +regex = "1.6" [package.metadata.release] release = false diff --git a/crates/header-translator/src/config.rs b/crates/header-translator/src/config.rs index 801865d09..00e5744b2 100644 --- a/crates/header-translator/src/config.rs +++ b/crates/header-translator/src/config.rs @@ -92,6 +92,18 @@ fn get_version<'de, D: Deserializer<'de>>(deserializer: D) -> Result, + #[serde(rename = "required-items")] + #[serde(default)] + pub required_items: Vec, +} + #[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct LibraryConfig { @@ -137,6 +149,12 @@ pub struct LibraryConfig { #[serde(default = "link_default")] pub link: bool, + /// Data about an external class or protocol whose header isn't imported. + /// + /// I.e. a bare `@protocol X;` or `@class X;`. + #[serde(default)] + pub external: BTreeMap, + #[serde(rename = "class")] #[serde(default)] pub class_data: HashMap, diff --git a/crates/header-translator/src/context.rs b/crates/header-translator/src/context.rs index 2b92da043..29a1ec6bd 100644 --- a/crates/header-translator/src/context.rs +++ b/crates/header-translator/src/context.rs @@ -1,84 +1,62 @@ -use std::borrow::Cow; use std::collections::HashMap; use std::ops; -use std::path::{Path, PathBuf}; -use apple_sdk::SdkPath; use clang::Entity; use crate::config::Config; -use crate::id::Location; +use crate::ItemIdentifier; -pub struct Context<'a> { - config: &'a Config, - pub macro_invocations: HashMap, Entity<'a>>, - framework_dir: PathBuf, - include_dir: PathBuf, +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MacroLocation { + file_id: Option<(u64, u64, u64)>, + line: u32, + column: u32, + offset: u32, } -impl<'a> Context<'a> { - pub fn new(config: &'a Config, sdk: &SdkPath) -> Self { +impl MacroLocation { + pub fn from_location(location: &clang::source::SourceLocation<'_>) -> Self { + let clang::source::Location { + file, + line, + column, + offset, + } = location.get_expansion_location(); Self { - config, - macro_invocations: Default::default(), - framework_dir: sdk.path.join("System/Library/Frameworks"), - include_dir: sdk.path.join("usr/include"), + file_id: file.map(|f| f.get_id()), + line, + column, + offset, } } +} - pub fn get_location(&self, entity: &Entity<'_>) -> Option { - if let Some(location) = entity.get_location() { - if let Some(file) = location.get_file_location().file { - let path = file.get_path(); - if let Ok(path) = path.strip_prefix(&self.framework_dir) { - let mut components: Vec> = path - .components() - .filter(|component| { - component.as_os_str() != "Headers" - && component.as_os_str() != "Frameworks" - }) - .map(|component| component.as_os_str().to_str().expect("component to_str")) - .map(|component| component.strip_suffix(".framework").unwrap_or(component)) - .map(|component| component.strip_suffix(".h").unwrap_or(component)) - .map(|s| s.to_string().into()) - .collect(); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MacroEntity { + pub(crate) id: ItemIdentifier, + pub(crate) is_function_like: bool, +} - // Put items in umbrella header in `mod.rs` - if let [.., innermost_framework_name, file_name] = &*components { - let umbrella_header = self - .libraries - .get(&**innermost_framework_name) - .and_then(|lib| lib.umbrella_header.as_deref()) - .unwrap_or(innermost_framework_name); +impl MacroEntity { + pub fn from_entity(entity: &Entity<'_>, context: &Context<'_>) -> Self { + Self { + id: ItemIdentifier::new(entity, context), + is_function_like: entity.is_function_like_macro(), + } + } +} - if file_name == umbrella_header { - let _ = components.pop(); - } - } +pub struct Context<'config> { + config: &'config Config, + pub macro_invocations: HashMap, +} - return Some(Location::from_components(components)); - } else if let Ok(path) = path.strip_prefix(&self.include_dir) { - if path.starts_with("objc") { - return Some(Location::from_components(vec!["objc2".into()])); - } - if path == Path::new("MacTypes.h") { - return Some(Location::from_components(vec!["System".into()])); - } - if path.starts_with("sys") { - return Some(Location::from_components(vec!["libc".into()])); - } - if path.starts_with("mach") { - // Will be moved to the `mach` crate in `libc` v1.0 - return Some(Location::from_components(vec!["libc".into()])); - } - if path.starts_with("arm") { - // Temporary - return Some(Location::from_components(vec!["System".into()])); - } - } - } +impl<'config> Context<'config> { + pub fn new(config: &'config Config) -> Self { + Self { + config, + macro_invocations: Default::default(), } - None } } diff --git a/crates/header-translator/src/expr.rs b/crates/header-translator/src/expr.rs index a7183f499..67aa5d0c5 100644 --- a/crates/header-translator/src/expr.rs +++ b/crates/header-translator/src/expr.rs @@ -4,6 +4,7 @@ use std::fmt; use clang::token::TokenKind; use clang::{Entity, EntityKind, EntityVisitResult, EvaluationResult}; +use crate::context::MacroLocation; use crate::rust_type::Ty; use crate::stmt::{enum_constant_name, new_enum_id}; use crate::unexposed_attr::UnexposedAttr; @@ -101,10 +102,10 @@ impl Expr { let location = entity.get_location().expect("expr location"); if let Some(macro_invocation) = context .macro_invocations - .get(&location.get_spelling_location()) + .get(&MacroLocation::from_location(&location)) { return Expr::MacroInvocation { - id: ItemIdentifier::new(macro_invocation, context), + id: macro_invocation.id.clone(), evaluated: Some(Box::new(Self::from_evaluated(entity))), }; } else { @@ -122,10 +123,10 @@ impl Expr { } else { let macro_invocation = context .macro_invocations - .get(&token.get_location().get_spelling_location()) + .get(&MacroLocation::from_location(&token.get_location())) .expect("expr macro invocation"); Expr::MacroInvocation { - id: ItemIdentifier::new(macro_invocation, context), + id: macro_invocation.id.clone(), evaluated: None, } }) diff --git a/crates/header-translator/src/id.rs b/crates/header-translator/src/id.rs index 330fa7f7f..d8d6f50c9 100644 --- a/crates/header-translator/src/id.rs +++ b/crates/header-translator/src/id.rs @@ -4,6 +4,7 @@ use std::borrow::Cow; use std::cmp::Ordering; use std::collections::BTreeSet; +use clang::source::Module; use clang::Entity; use crate::cfgs::PlatformCfg; @@ -122,6 +123,35 @@ impl<'config> LocationLibrary<'_, 'config> { } impl Location { + fn from_module(module: Module<'_>) -> Self { + let full_name = module.get_full_name(); + + Location::from_components(match &*full_name { + // Objective-C + name if name.starts_with("ObjectiveC") => vec!["objc2".into()], + + // Redefined in the framework crate itself. + "Darwin.MacTypes" => vec!["System".into()], + + // Built-in + "DarwinFoundation.types.machine_types" => vec!["System".into()], + + // Libc + name if name.starts_with("sys_types") => vec!["libc".into()], + "DarwinFoundation.types.sys_types" => vec!["libc".into()], + name if name.starts_with("Darwin.POSIX") => vec!["libc".into()], + + // Will be moved to the `mach2` crate in `libc` v1.0 + name if name.starts_with("Darwin.Mach") => vec!["libc".into()], + "_mach_port_t" => vec!["libc".into()], + + full_name => full_name + .split('.') + .map(|component| Cow::Owned(component.to_string())) + .collect(), + }) + } + pub(crate) fn from_components(path_components: Vec>) -> Self { Self { path_components } } @@ -237,13 +267,23 @@ impl ItemIdentifier { } } - pub fn with_name(name: N, entity: &Entity<'_>, context: &Context<'_>) -> Self { - let mut location = context.get_location(entity).unwrap_or_else(|| { - error!(?entity, "ItemIdentifier from unknown header"); - Location::from_components(vec!["__Unknown__".into()]) - }); + pub fn with_name(name: N, entity: &Entity<'_>, _context: &Context<'_>) -> Self { + let file = entity + .get_location() + .expect("entity location") + .get_expansion_location() + .file + .expect("expanded location file"); + + let mut location = if let Some(module) = file.get_module() { + Location::from_module(module) + } else { + // If file module is not available, the item is likely a built-in macro. + Location::from_components(vec!["System".into()]) + }; - if let Some("IOSurfaceRef") = name.to_option() { + // Defined in multiple places for some reason. + if let Some("IOSurfaceRef" | "__IOSurface") = name.to_option() { location = Location::from_components(vec!["IOSurface".into(), "IOSurfaceRef".into()]); } diff --git a/crates/header-translator/src/lib.rs b/crates/header-translator/src/lib.rs index f6cbf5580..3eb7a74d3 100644 --- a/crates/header-translator/src/lib.rs +++ b/crates/header-translator/src/lib.rs @@ -28,7 +28,7 @@ mod thread_safety; mod unexposed_attr; pub use self::config::{Config, LibraryConfig}; -pub use self::context::Context; +pub use self::context::{Context, MacroEntity, MacroLocation}; pub use self::global_analysis::global_analysis; pub use self::id::{ItemIdentifier, Location}; pub use self::library::Library; diff --git a/crates/header-translator/src/library.rs b/crates/header-translator/src/library.rs index ef0cb15d4..b5a84c97c 100644 --- a/crates/header-translator/src/library.rs +++ b/crates/header-translator/src/library.rs @@ -15,7 +15,6 @@ use crate::config::LibraryConfig; use crate::display_helper::FormatterFn; use crate::module::Module; use crate::Config; -use crate::Location; use crate::VERSION; #[derive(Debug, PartialEq)] @@ -36,20 +35,26 @@ impl Library { } } - pub fn add_module(&mut self, path: Vec) { + pub fn add_module(&mut self, components: Vec) { let mut current = &mut self.module; - for p in path { - current = current.submodules.entry(p.clone()).or_default(); + for component in components { + current = current.submodules.entry(component).or_default(); } } - pub fn module_mut(&mut self, location: &Location) -> &mut Module { + pub fn module_mut(&mut self, mut module: clang::source::Module<'_>) -> &mut Module { + let mut components = vec![]; + while let Some(parent) = module.get_parent() { + components.insert(0, module.get_name()); + module = parent; + } + let mut current = &mut self.module; - for p in location.modules() { - current = match current.submodules.entry(p.to_string()) { + for component in components { + current = match current.submodules.entry(component) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { - warn!(?location, "expected module to be available in library"); + error!(?module, "expected module to be available in library"); entry.insert(Default::default()) } }; diff --git a/crates/header-translator/src/main.rs b/crates/header-translator/src/main.rs index 6bb39d4fb..5348360db 100644 --- a/crates/header-translator/src/main.rs +++ b/crates/header-translator/src/main.rs @@ -6,7 +6,7 @@ use std::{fs, io}; use apple_sdk::{AppleSdk, DeveloperDirectory, Platform, SdkPath, SimpleSdk}; use clang::{Clang, EntityKind, EntityVisitResult, Index, TranslationUnit}; use semver::VersionReq; -use tracing::{debug_span, error, info, info_span, trace, trace_span}; +use tracing::{debug_span, error, info, info_span, trace_span}; use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::layer::{Layer, SubscriberExt}; use tracing_subscriber::registry::Registry; @@ -14,7 +14,8 @@ use tracing_subscriber::util::SubscriberInitExt; use tracing_tree::HierarchicalLayer; use header_translator::{ - global_analysis, run_cargo_fmt, Config, Context, Library, LibraryConfig, Stmt, + global_analysis, run_cargo_fmt, Config, Context, Library, LibraryConfig, MacroEntity, + MacroLocation, Stmt, }; type BoxError = Box; @@ -91,30 +92,18 @@ fn main() -> Result<(), BoxError> { // TODO: Compare between SDKs for sdk in sdks { // These are found using the `get_llvm_targets.fish` helper script - let (llvm_targets, platform_header, platform_config_filter): ( - &[_], - _, - fn(&LibraryConfig) -> bool, - ) = match &sdk.platform { - Platform::MacOsX => ( - &[ - // "x86_64-apple-macosx10.12.0", - "arm64-apple-macosx11.0.0", - // "i686-apple-macosx10.12.0", - ], - "macos.h", - |config| config.macos.is_some(), - ), - Platform::IPhoneOs => ( - &[ - "arm64-apple-ios10.0.0", - // "armv7s-apple-ios10.0.0", - // "arm64-apple-ios14.0-macabi", - // "x86_64-apple-ios13.0-macabi", - ], - "ios.h", - |config| config.ios.is_some(), - ), + let llvm_targets: &[_] = match &sdk.platform { + Platform::MacOsX => &[ + // "x86_64-apple-macosx10.12.0", + "arm64-apple-macosx11.0.0", + // "i686-apple-macosx10.12.0", + ], + Platform::IPhoneOs => &[ + "arm64-apple-ios10.0.0", + // "armv7s-apple-ios10.0.0", + // "arm64-apple-ios14.0-macabi", + // "x86_64-apple-ios13.0-macabi", + ], // Platform::IPhoneSimulator => &[ // "arm64-apple-ios10.0.0-simulator", // "x86_64-apple-ios10.0.0-simulator", @@ -131,42 +120,10 @@ fn main() -> Result<(), BoxError> { let mut result: Option> = None; - let includes = tempdir.join(platform_header); - - let mut includes_file = fs::File::create(&includes).unwrap(); - // Make sure that we pick the IOSurfaceRef that IOSurface defines, - // instead of the one that CoreGraphics defines. - if platform_config_filter(&config.libraries["IOSurface"]) { - writeln!(&mut includes_file, "#include ")?; - writeln!(&mut includes_file, "#include ")?; - } - // Part of .modulemap - writeln!(&mut includes_file, "#import ")?; - for lib in config.libraries.values() { - if !platform_config_filter(lib) { - continue; - } - if let Some(umbrella_header) = &lib.umbrella_header { - writeln!( - &mut includes_file, - "#import <{}/{}>", - lib.framework, umbrella_header - )?; - } else { - writeln!( - &mut includes_file, - "#import <{}/{}.h>", - lib.framework, lib.framework, - )?; - } - } - includes_file.flush().unwrap(); - drop(includes_file); - for llvm_target in llvm_targets { let _span = info_span!("parsing", platform = ?sdk.platform, llvm_target).entered(); - let curr_result = parse_sdk(&index, &sdk, llvm_target, &config, &includes); + let curr_result = parse_sdk(&index, &config, &sdk, llvm_target, &tempdir); if let Some(prev_result) = &result { // Ensure that each target produces the same result. @@ -285,114 +242,138 @@ fn load_config(workspace_dir: &Path) -> Result { fn parse_sdk( index: &Index<'_>, + config: &Config, sdk: &SdkPath, llvm_target: &str, - config: &Config, - includes: &Path, + tempdir: &Path, ) -> BTreeMap { - let tu = get_translation_unit(index, sdk, llvm_target, includes); + let mut context = Context::new(config); - let mut preprocessing = true; - let mut libraries: BTreeMap = config + config .libraries .iter() - .map(|(name, data)| (name.into(), Library::new(name, data))) - .collect(); + .filter(|(_, data)| match &sdk.platform { + // TODO: Mac Catalyst + Platform::MacOsX => data.macos.is_some(), + Platform::IPhoneOs | Platform::IPhoneSimulator => data.ios.is_some(), + Platform::AppleTvOs | Platform::AppleTvSimulator => data.tvos.is_some(), + Platform::WatchOs | Platform::WatchSimulator => data.watchos.is_some(), + Platform::XrOs | Platform::XrOsSimulator => data.visionos.is_some(), + _ => unimplemented!("unsupported sdk {sdk:?}"), + }) + .map(|(name, data)| { + let _span = info_span!("framework", ?name).entered(); + let mut library = Library::new(name, data); + let tu = + get_translation_unit(index, sdk, llvm_target, &library.data.framework, tempdir); + parse_framework(tu, &mut context, &mut library); + (name.into(), library) + }) + .collect() +} - let mut library_span: Option<(_, String)> = None; +fn parse_framework(tu: TranslationUnit<'_>, context: &mut Context<'_>, library: &mut Library) { + let mut preprocessing = true; let mut file_span: Option<(_, _)> = None; - let mut context = Context::new(config, sdk); - tu.get_entity().visit_children(|entity, _parent| { + let location = entity.get_location().expect("entity location"); + + let file = location.get_expansion_location().file; + if file_span.as_ref().map(|(_, l)| l) != Some(&file) { + // Drop old span + file_span.take(); + + // Enter new span + let span = if let Some(file) = file { + if let Some(module) = file.get_module() { + debug_span!("module", full_name = module.get_full_name()) + } else { + debug_span!("file", path = ?file.get_path()) + } + } else { + // System-defined entities (like built-in macros, or + // inclusion directives generated from the modulemap). + debug_span!("Clang-defined") + }; + file_span = Some((span.entered(), file)); + } + let _span = trace_span!("entity", ?entity).entered(); - if let Some(location) = context.get_location(&entity) { - let library_name = location.library_name(); - if library_span.as_ref().map(|(_, s)| &**s) != Some(library_name) { - // Drop old entered spans - library_span.take(); - file_span.take(); - // Enter new span - library_span = Some(( - debug_span!("library", name = library_name).entered(), - library_name.to_string(), - )); - } - if file_span.as_ref().map(|(_, l)| l) != Some(&location) { - // Drop old entered span - file_span.take(); - // Enter new span - file_span = Some((debug_span!("file", ?location).entered(), location.clone())); - } - if let Some(library) = libraries.get_mut(library_name) { - match entity.get_kind() { - EntityKind::InclusionDirective if preprocessing => { - let name = entity.get_name().expect("inclusion name"); - let mut iter = name.split('/'); - let framework = iter.next().expect("inclusion name has framework"); - if framework == library_name { - let included = iter - .next() - .expect("inclusion name has file") - .strip_suffix(".h") - .expect("inclusion name file is header") - .to_string(); - if iter.count() != 0 { - panic!("invalid inclusion of {name:?}"); - } - - // If inclusion is not umbrella header - if included != *library_name { - // The file is often included twice, even - // within the same file, so insertion can fail - library.add_module(vec![included]) - } - } - } - EntityKind::MacroExpansion if preprocessing => { - let clang_location = entity.get_location().expect("macro location"); - context - .macro_invocations - .insert(clang_location.get_spelling_location(), entity); - } - EntityKind::MacroDefinition if preprocessing => { - // let name = entity.get_name().expect("macro def name"); - // entity.is_function_like_macro(); - // trace!("macrodef", name); + match entity.get_kind() { + EntityKind::InclusionDirective if preprocessing => { + let file = entity.get_file().expect("inclusion directive has file"); + if let Some(mut module) = file.get_module() { + let mut components = vec![]; + while let Some(parent) = module.get_parent() { + components.insert(0, module.get_name()); + module = parent; } - _ => { - if preprocessing { - info!("done preprocessing"); - } - preprocessing = false; - // No more includes / macro expansions after this line - for stmt in Stmt::parse(&entity, &context) { - let module = library.module_mut(&location); - module.add_stmt(stmt); - } + if module.get_name() == library.data.framework { + library.add_module(components); } } - } else { - trace!("library not found"); + } + EntityKind::MacroExpansion if preprocessing => { + let entity = MacroEntity::from_entity(&entity, context); + context + .macro_invocations + .insert(MacroLocation::from_location(&location), entity); + } + EntityKind::MacroDefinition if preprocessing => { + // let name = entity.get_name().expect("macro def name"); + // entity.is_function_like_macro(); + // trace!("macrodef", name); + } + _ => { + if preprocessing { + info!("done preprocessing"); + } + preprocessing = false; + // No more includes / macro expansions after this line + + let file = location + .get_expansion_location() + .file + .expect("expanded location file"); + + let module = library.module_mut(file.get_module().expect("file module")); + for stmt in Stmt::parse(&entity, context) { + module.add_stmt(stmt); + } } } + EntityVisitResult::Continue }); - - libraries } -fn get_translation_unit<'i: 'tu, 'tu>( - index: &'i Index<'tu>, +fn get_translation_unit<'i: 'c, 'c>( + index: &'i Index<'c>, sdk: &SdkPath, llvm_target: &str, - includes: &Path, -) -> TranslationUnit<'tu> { + framework: &str, + tempdir: &Path, +) -> TranslationUnit<'c> { let _span = info_span!("initializing translation unit").entered(); + // "usr/include/TargetConditionals.modulemap" + // "System/Library/Frameworks/CoreFoundation.framework/Modules/module.modulemap" + // "usr/include/ObjectiveC.modulemap" + let path = sdk.path.join(format!( + "System/Library/Frameworks/{framework}.framework/Modules/module.modulemap" + )); + let modulemap = fs::read_to_string(&path).expect("read module map"); + let re = regex::Regex::new(r"(?m)^framework +module +(\w*)").unwrap(); + + // Find the top-level framework + let mut captures = re.captures_iter(&modulemap); + let module = &captures.next().expect("module name in module map")[1]; + assert_eq!(captures.count(), 0); + let tu = index - .parser(includes) + .parser(path.to_str().unwrap()) .detailed_preprocessing_record(true) .incomplete(true) .skip_function_bodies(true) @@ -414,17 +395,39 @@ fn get_translation_unit<'i: 'tu, 'tu>( "-fobjc-abi-version=2", // 3?? // "-fparse-all-comments", // TODO: "-fretain-comments-from-system-headers" - "-fapinotes", "-isysroot", sdk.path.to_str().unwrap(), // See ClangImporter.cpp and Foundation/NSObjCRuntime.h "-D", "__SWIFT_ATTR_SUPPORTS_SENDABLE_DECLS=1", + // Enable modules. We do this by parsing the `.modulemap` instead + // of a combined file containing includes, as the Clang AST from + // dependent modules does not seem possible to access otherwise. + // + // The magic here is passing `-emit-module` to the frontend. + // + // See: + // https://clang.llvm.org/docs/Modules.html + // https://clang.llvm.org/docs/PCHInternals.html + "-fmodules", + "-fimplicit-module-maps", + // "-Xclang", + // "-fmodule-format=raw", + &format!("-fmodules-cache-path={}", tempdir.to_str().unwrap()), + // "-fsystem-module", + "-Xclang", + "-emit-module", + &format!("-fmodule-name={module}"), + // Explicitly enable API notes (implicitly enabled by -fmodules). + "-fapinotes", + "-fapinotes-modules", + // "-fapi-notes-swift-version=6.0", ]) .parse() .unwrap(); // dbg!(&tu); + // dbg!(tu.get_entity().get_children()); // dbg!(tu.get_target()); // dbg!(tu.get_memory_usage()); // dbg!(tu.get_diagnostics()); diff --git a/crates/header-translator/src/rust_type.rs b/crates/header-translator/src/rust_type.rs index f3806073a..cef3e0c77 100644 --- a/crates/header-translator/src/rust_type.rs +++ b/crates/header-translator/src/rust_type.rs @@ -1,5 +1,6 @@ -use std::fmt; +use std::borrow::Cow; use std::str::FromStr; +use std::{fmt, iter}; use clang::{CallingConvention, Entity, EntityKind, Nullability, Type, TypeKind}; use proc_macro2::{TokenStream, TokenTree}; @@ -339,10 +340,62 @@ impl ItemRef { } fn new(entity: &Entity<'_>, context: &Context<'_>) -> Self { - Self { - id: ItemIdentifier::new(entity, context), - thread_safety: ThreadSafety::from_decl(entity, context), - required_items: items_required_by_decl(entity, context), + let entity = entity + .get_location() + .expect("itemref location") + .get_entity() + .expect("itemref entity"); + + let id = ItemIdentifier::new(&entity, context); + + if let Some(external) = context.library(id.library_name()).external.get(&id.name) { + let id = ItemIdentifier::from_raw( + id.name, + external + .module + .split('.') + .map(|x| x.to_string().into()) + .collect(), + ); + let thread_safety = external + .thread_safety + .as_deref() + .map(ThreadSafety::from_string) + .unwrap_or(ThreadSafety::dummy()); + let required_items = external + .required_items + .iter() + .map(|s| { + let mut components: Vec> = + s.split('.').map(|x| x.to_string().into()).collect(); + let name = components + .pop() + .expect("required items component at least one"); + ItemIdentifier::from_raw(name.to_string(), components) + }) + .chain(iter::once(id.clone())) + .collect(); + Self { + id, + thread_safety, + required_items, + } + } else if matches!( + entity.get_kind(), + EntityKind::ObjCInterfaceDecl | EntityKind::ObjCProtocolDecl + ) { + Self { + id, + thread_safety: ThreadSafety::from_decl(&entity, context), + required_items: items_required_by_decl(&entity, context), + } + } else { + error!(?entity, "could not get declaration. Add appropriate external.{}.module = \"...\" to translation-config.toml", id.name); + Self { + id, + thread_safety: ThreadSafety::dummy(), + required_items: vec![], + } } } } @@ -603,11 +656,10 @@ impl Ty { TypeKind::ObjCClass => { let mut parser = AttributeParser::new(&attributed_name, &name); let lifetime = parser.lifetime(ParsePosition::Suffix); - let nullability = if let Some(nullability) = unexposed_nullability { - nullability - } else { - check_nullability(&attributed_ty, parser.nullability(ParsePosition::Suffix)) - }; + let nullability = unexposed_nullability + .or(parser.nullability(ParsePosition::Suffix)) + .or(ty.get_nullability()) + .unwrap_or(Nullability::Unspecified); Self::Pointer { nullability, @@ -665,10 +717,9 @@ impl Ty { .get_objc_protocol_declarations() .into_iter() .map(|entity| { - let definition = entity - .get_definition() - .expect("objc protocol declaration definition"); - let mut decl = ItemRef::new(&definition, context); + // ItemRef::new will fall back if we can't find it here. + let maybe_definition = entity.get_definition().unwrap_or(entity); + let mut decl = ItemRef::new(&maybe_definition, context); decl.id = context.replace_protocol_name(decl.id); decl }) @@ -1677,8 +1728,8 @@ impl Ty { pub(crate) fn method_argument(&self) -> impl fmt::Display + '_ { FormatterFn(move |f| match self { Self::Primitive(Primitive::C99Bool) => { - error!("C99's bool as Objective-C method argument is unsupported"); - write!(f, "C99Bool") + warn!("C99's bool as Objective-C method argument is ill supported"); + write!(f, "bool") } Self::Primitive(Primitive::ObjcBool) => { write!(f, "bool") @@ -1964,7 +2015,9 @@ impl Ty { pub(crate) fn argument_is_error_out(&self) -> bool { if let Self::Pointer { - nullability, + // We always pass a place to write the error information, + // so doesn't matter whether it's optional or not. + nullability: Nullability::Nullable | Nullability::NonNull, is_const, lifetime: Lifetime::Unspecified, pointee, @@ -1986,11 +2039,6 @@ impl Ty { if !decl.id.is_nserror() { return false; } - assert_eq!( - *nullability, - Nullability::Nullable, - "invalid error nullability {self:?}" - ); assert!(!is_const, "expected error not const {self:?}"); assert_eq!( *inner_nullability, diff --git a/crates/header-translator/src/thread_safety.rs b/crates/header-translator/src/thread_safety.rs index 5e04ebc73..3456758a8 100644 --- a/crates/header-translator/src/thread_safety.rs +++ b/crates/header-translator/src/thread_safety.rs @@ -190,7 +190,6 @@ pub(crate) struct ThreadSafety { } impl ThreadSafety { - #[cfg(test)] pub(crate) fn dummy() -> Self { Self { explicit: None, @@ -198,6 +197,19 @@ impl ThreadSafety { } } + pub(crate) fn from_string(s: &str) -> Self { + let attr = match s { + "MainThreadOnly" => ThreadSafetyAttr::MainThreadOnly, + "Sendable" => ThreadSafetyAttr::Sendable, + "NotSendable" => ThreadSafetyAttr::NotSendable, + _ => panic!("invalid thread safety: {s:?}"), + }; + Self { + explicit: Some(attr), + inferred: attr, + } + } + pub(crate) fn from_decl(entity: &Entity<'_>, context: &Context<'_>) -> Self { let explicit = ThreadSafetyAttr::parse_explicit_decl(entity, context); let inferred = diff --git a/crates/header-translator/src/unexposed_attr.rs b/crates/header-translator/src/unexposed_attr.rs index bc9b7124d..f2dcc846c 100644 --- a/crates/header-translator/src/unexposed_attr.rs +++ b/crates/header-translator/src/unexposed_attr.rs @@ -2,7 +2,7 @@ use clang::source::{SourceLocation, SourceRange}; use clang::token::{Token, TokenKind}; use clang::{Entity, EntityKind}; -use crate::context::Context; +use crate::context::{Context, MacroLocation}; /// Parts of `EntityKind::UnexposedAttr` that we can easily parse. #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -256,6 +256,7 @@ impl UnexposedAttr { error!(?s, "attribute that requires manual handling. Mark it as skipped in translation-config.toml"); None } + "objc_non_runtime_protocol" => None, _ => return Err(()), }) } @@ -264,29 +265,32 @@ impl UnexposedAttr { if let Some(location) = entity.get_location() { if let Some(entity) = context .macro_invocations - .get(&location.get_spelling_location()) + .get(&MacroLocation::from_location(&location)) { - let name = entity.get_name().expect("macro name"); - return Self::from_name(&name, || get_argument_tokens(entity)).unwrap_or_else( - |()| { - error!( - name, - fnlike = entity.is_function_like_macro(), - "unknown unexposed attribute" - ); - None - }, - ); + return Self::from_name(&entity.id.name, || { + if !entity.is_function_like { + error!(?entity, "tried to get tokens from non-function-like macro"); + } + }) + .unwrap_or_else(|()| { + error!( + name = ?entity.id, + fnlike = entity.is_function_like, + "unknown unexposed attribute" + ); + None + }); } - Self::parse_location(location) + Self::parse_location(entity, location) } else { - warn!(?entity, "no unexposed attr location"); + // Certain attributes don't have location info, such as those + // generated by apinotes. None } } - fn parse_location(location: SourceLocation<'_>) -> Option { + fn parse_location(entity: &Entity<'_>, location: SourceLocation<'_>) -> Option { if let Some(parsed) = location.get_entity() { match parsed.get_kind() { EntityKind::MacroExpansion => { @@ -303,7 +307,50 @@ impl UnexposedAttr { _ => None, } } else { - None + // For some reason, `entity.get_range()` doesn't work properly, + // and this is the only way to properly extract the macro name. + let file = location + .get_file_location() + .file + .expect("unexposed attr location file"); + let range = entity + .get_range() + .expect("unexposed attr with location has token range"); + let start = file.get_offset_location(range.get_start().get_file_location().offset); + let end = file.get_offset_location(range.get_end().get_file_location().offset); + let mut tokens = SourceRange::new(start, end).tokenize(); + + // Extract the macro name + if tokens.is_empty() { + error!(?tokens, "no tokens found in attr"); + return None; + }; + let token = tokens.remove(0); + if token.get_kind() != TokenKind::Identifier { + error!(?tokens, "token in attr was not an identifier"); + return None; + } + let macro_name = token.get_spelling(); + + Self::from_name(¯o_name, move || { + if tokens.is_empty() { + error!(?entity, "tried to get tokens from non-function-like macro"); + return vec![]; + } + + let start = tokens.remove(0); + assert_eq!(start.get_kind(), TokenKind::Punctuation); + assert_eq!(start.get_spelling(), "("); + let end = tokens.pop().expect("tokens to have parentheses"); + assert_eq!(end.get_kind(), TokenKind::Punctuation); + assert_eq!(end.get_spelling(), ")"); + + tokens + }) + .unwrap_or_else(|()| { + error!(macro_name, "unknown unexposed attribute"); + None + }) } } } diff --git a/crates/objc2/src/topics/about_generated/CHANGELOG.md b/crates/objc2/src/topics/about_generated/CHANGELOG.md index 1bcc4516a..99ab8378f 100644 --- a/crates/objc2/src/topics/about_generated/CHANGELOG.md +++ b/crates/objc2/src/topics/about_generated/CHANGELOG.md @@ -156,6 +156,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). `NSPasteboard::readObjectsForClasses_options` now takes `&NSArray`, and `UITrait` is now exposed more correctly. * **BREAKING**: Fixed the return type of `NSClassFromString`. +* Use Clang `-fmodules` for more correct header translation. ## 0.2.2 - 2024-05-21 diff --git a/framework-crates/objc2-app-kit/Cargo.toml b/framework-crates/objc2-app-kit/Cargo.toml index 295ea5575..3277f09ac 100644 --- a/framework-crates/objc2-app-kit/Cargo.toml +++ b/framework-crates/objc2-app-kit/Cargo.toml @@ -57,7 +57,7 @@ gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1", "block2?/gnustep-2-1", "objc2 bitflags = ["dep:bitflags", "objc2-cloud-kit?/bitflags", "objc2-core-data?/bitflags", "objc2-core-foundation?/bitflags", "objc2-core-graphics?/bitflags", "objc2-foundation/bitflags", "objc2-quartz-core?/bitflags"] block2 = ["dep:block2", "objc2-cloud-kit?/block2", "objc2-core-data?/block2", "objc2-core-foundation?/block2", "objc2-core-graphics?/block2", "objc2-core-image?/block2", "objc2-foundation/block2", "objc2-quartz-core?/block2", "objc2-uniform-type-identifiers?/block2"] libc = ["dep:libc", "objc2-core-foundation?/libc", "objc2-core-graphics?/libc", "objc2-foundation/libc", "objc2-quartz-core?/libc"] -objc2-cloud-kit = ["dep:objc2-cloud-kit"] +objc2-cloud-kit = ["dep:objc2-cloud-kit", "objc2-core-data?/objc2-cloud-kit"] objc2-core-data = ["dep:objc2-core-data"] objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-core-graphics?/objc2-core-foundation", "objc2-core-image?/objc2-core-foundation", "objc2-foundation/objc2-core-foundation", "objc2-quartz-core?/objc2-core-foundation"] objc2-core-graphics = ["dep:objc2-core-graphics", "objc2-core-image?/objc2-core-graphics", "objc2-quartz-core?/objc2-core-graphics"] @@ -931,8 +931,14 @@ NSNib = [ "objc2-foundation/NSString", "objc2-foundation/NSURL", ] +NSNibConnector = [ + "objc2-foundation/NSObject", + "objc2-foundation/NSString", +] +NSNibControlConnector = ["objc2-foundation/NSObject"] NSNibDeclarations = [] NSNibLoading = [] +NSNibOutletConnector = ["objc2-foundation/NSObject"] NSObjectController = [ "objc2-core-data?/NSFetchRequest", "objc2-core-data?/NSManagedObjectContext", @@ -2148,8 +2154,11 @@ all = [ "NSMenuToolbarItem", "NSMovie", "NSNib", + "NSNibConnector", + "NSNibControlConnector", "NSNibDeclarations", "NSNibLoading", + "NSNibOutletConnector", "NSObjectController", "NSOpenGL", "NSOpenGLLayer", diff --git a/framework-crates/objc2-app-kit/translation-config.toml b/framework-crates/objc2-app-kit/translation-config.toml index 47b16cb12..b03fa815c 100644 --- a/framework-crates/objc2-app-kit/translation-config.toml +++ b/framework-crates/objc2-app-kit/translation-config.toml @@ -6,6 +6,8 @@ macos = "10.0" maccatalyst = "13.0" gnustep = true +external.UTType.module = "UniformTypeIdentifiers.UTType" + # `objc_ownership` in .apinotes class.NSBundle.methods."loadNibNamed:owner:topLevelObjects:".skipped = true class.NSNib.methods."instantiateWithOwner:topLevelObjects:".skipped = true diff --git a/framework-crates/objc2-app-tracking-transparency/Cargo.toml b/framework-crates/objc2-app-tracking-transparency/Cargo.toml index 918af491a..593414f34 100644 --- a/framework-crates/objc2-app-tracking-transparency/Cargo.toml +++ b/framework-crates/objc2-app-tracking-transparency/Cargo.toml @@ -38,8 +38,4 @@ std = ["alloc", "block2?/std", "objc2/std"] alloc = ["block2?/alloc", "objc2/alloc"] block2 = ["dep:block2"] -ATTrackingManager = [] -all = [ - "ATTrackingManager", - "block2", -] +all = ["block2"] diff --git a/framework-crates/objc2-automatic-assessment-configuration/Cargo.toml b/framework-crates/objc2-automatic-assessment-configuration/Cargo.toml index 124923c2a..14964e335 100644 --- a/framework-crates/objc2-automatic-assessment-configuration/Cargo.toml +++ b/framework-crates/objc2-automatic-assessment-configuration/Cargo.toml @@ -16,9 +16,9 @@ license.workspace = true workspace = true [dependencies] -bitflags = { version = "2.5.0", default-features = false, optional = true } +bitflags = { version = "2.5.0", default-features = false } objc2 = { path = "../../crates/objc2", version = "0.5.2", default-features = false } -objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false } +objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false, features = ["NSDictionary", "NSError", "NSObject", "NSString"] } [package.metadata.docs.rs] default-target = "aarch64-apple-darwin" @@ -34,38 +34,7 @@ targets = [ default = ["std"] # Currently not possible to turn off, put here for forwards compatibility. -std = ["alloc", "bitflags?/std", "objc2/std", "objc2-foundation/std"] +std = ["alloc", "bitflags/std", "objc2/std", "objc2-foundation/std"] alloc = ["objc2/alloc", "objc2-foundation/alloc"] -bitflags = ["dep:bitflags", "objc2-foundation/bitflags"] -AEAssessmentApplication = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -AEAssessmentConfiguration = [ - "bitflags", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", -] -AEAssessmentParticipantConfiguration = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -AEAssessmentSession = [] -AEAssessmentSessionDelegate = ["objc2-foundation/NSError"] -AEErrors = [ - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -AEVisibility = [] -all = [ - "AEAssessmentApplication", - "AEAssessmentConfiguration", - "AEAssessmentParticipantConfiguration", - "AEAssessmentSession", - "AEAssessmentSessionDelegate", - "AEErrors", - "AEVisibility", - "bitflags", -] +all = [] diff --git a/framework-crates/objc2-av-kit/translation-config.toml b/framework-crates/objc2-av-kit/translation-config.toml index d6707aba3..3e064482b 100644 --- a/framework-crates/objc2-av-kit/translation-config.toml +++ b/framework-crates/objc2-av-kit/translation-config.toml @@ -8,6 +8,10 @@ tvos = "9.0" watchos = "9.0" visionos = "1.0" +# Has no declaration elsewhere, unknown where these actually come from +external.AVGroupExperienceCoordinator.module = "AVKit.AVPlayerViewController" +external.AVContentProposal.module = "AVKit.AVPlayerViewController" + # Needs AVFoundation class.AVCaptureView.methods.session.skipped = true class.AVCaptureView.methods."setSession:showVideoPreview:showAudioPreview:".skipped = true diff --git a/framework-crates/objc2-contacts-ui/translation-config.toml b/framework-crates/objc2-contacts-ui/translation-config.toml index 6994fcb95..4d62e73e4 100644 --- a/framework-crates/objc2-contacts-ui/translation-config.toml +++ b/framework-crates/objc2-contacts-ui/translation-config.toml @@ -5,3 +5,7 @@ macos = "10.11" maccatalyst = "13.0" ios = "9.0" visionos = "1.0" + +external.CNContact.module = "Contacts.CNContact" +external.CNContactProperty.module = "Contacts.CNContactProperty" +external.CNKeyDescriptor.module = "Contacts.CNContact" diff --git a/framework-crates/objc2-core-data/Cargo.toml b/framework-crates/objc2-core-data/Cargo.toml index 580e8c1f6..f23320175 100644 --- a/framework-crates/objc2-core-data/Cargo.toml +++ b/framework-crates/objc2-core-data/Cargo.toml @@ -19,6 +19,7 @@ workspace = true bitflags = { version = "2.5.0", default-features = false, optional = true } block2 = { path = "../../crates/block2", version = "0.5.1", default-features = false, optional = true } objc2 = { path = "../../crates/objc2", version = "0.5.2", default-features = false } +objc2-cloud-kit = { path = "../objc2-cloud-kit", version = "0.2.2", default-features = false, optional = true } objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false } [package.metadata.docs.rs] @@ -37,17 +38,31 @@ targets = [ default = ["std"] # Currently not possible to turn off, put here for forwards compatibility. -std = ["alloc", "bitflags?/std", "block2?/std", "objc2/std", "objc2-foundation/std"] -alloc = ["block2?/alloc", "objc2/alloc", "objc2-foundation/alloc"] +std = ["alloc", "bitflags?/std", "block2?/std", "objc2/std", "objc2-cloud-kit?/std", "objc2-foundation/std"] +alloc = ["block2?/alloc", "objc2/alloc", "objc2-cloud-kit?/alloc", "objc2-foundation/alloc"] apple = [] gnustep-1-7 = [] gnustep-1-8 = [] gnustep-1-9 = [] gnustep-2-0 = [] gnustep-2-1 = [] -bitflags = ["dep:bitflags", "objc2-foundation/bitflags"] -block2 = ["dep:block2", "objc2-foundation/block2"] +bitflags = ["dep:bitflags", "objc2-cloud-kit?/bitflags", "objc2-foundation/bitflags"] +block2 = ["dep:block2", "objc2-cloud-kit?/block2", "objc2-foundation/block2"] +objc2-cloud-kit = ["dep:objc2-cloud-kit"] +CloudKit = [ + "objc2-cloud-kit?/CKContainer", + "objc2-cloud-kit?/CKRecord", + "objc2-cloud-kit?/CKRecordZoneID", + "objc2-cloud-kit?/CKShare", + "objc2-cloud-kit?/CKShareMetadata", + "objc2-cloud-kit?/CKShareParticipant", + "objc2-cloud-kit?/CKUserIdentityLookupInfo", + "objc2-foundation/NSArray", + "objc2-foundation/NSDictionary", + "objc2-foundation/NSError", + "objc2-foundation/NSSet", +] CoreDataDefines = [] CoreDataErrors = ["objc2-foundation/NSString"] NSAtomicStore = [ @@ -330,6 +345,7 @@ NSSaveChangesRequest = [ ] NSStagedMigrationManager = ["objc2-foundation/NSArray"] all = [ + "CloudKit", "CoreDataDefines", "CoreDataErrors", "NSAtomicStore", @@ -386,4 +402,5 @@ all = [ "NSStagedMigrationManager", "bitflags", "block2", + "objc2-cloud-kit", ] diff --git a/framework-crates/objc2-core-foundation/Cargo.toml b/framework-crates/objc2-core-foundation/Cargo.toml index de363d046..44366207c 100644 --- a/framework-crates/objc2-core-foundation/Cargo.toml +++ b/framework-crates/objc2-core-foundation/Cargo.toml @@ -71,7 +71,7 @@ CFNotificationCenter = [] CFNumber = [] CFNumberFormatter = ["bitflags"] CFPlugIn = [] -CFPluginCOM = [] +CFPlugInCOM = [] CFPreferences = [] CFPropertyList = ["bitflags"] CFRunLoop = ["bitflags"] @@ -118,7 +118,7 @@ all = [ "CFNumber", "CFNumberFormatter", "CFPlugIn", - "CFPluginCOM", + "CFPlugInCOM", "CFPreferences", "CFPropertyList", "CFRunLoop", diff --git a/framework-crates/objc2-core-graphics/translation-config.toml b/framework-crates/objc2-core-graphics/translation-config.toml index 7a308b231..e0c7de70f 100644 --- a/framework-crates/objc2-core-graphics/translation-config.toml +++ b/framework-crates/objc2-core-graphics/translation-config.toml @@ -9,6 +9,8 @@ tvos = "9.0" watchos = "2.0" visionos = "1.0" +external.MTLDevice.module = "Metal.MTLDevice" + # Needs dispatch_queue_t from libdispatch fn.CGDisplayStreamCreateWithDispatchQueue.skipped = true diff --git a/framework-crates/objc2-core-image/Cargo.toml b/framework-crates/objc2-core-image/Cargo.toml index 0a2da16d8..de97b6ceb 100644 --- a/framework-crates/objc2-core-image/Cargo.toml +++ b/framework-crates/objc2-core-image/Cargo.toml @@ -20,6 +20,7 @@ block2 = { path = "../../crates/block2", version = "0.5.1", default-features = f objc2 = { path = "../../crates/objc2", version = "0.5.2", default-features = false } objc2-core-foundation = { path = "../objc2-core-foundation", version = "0.2.2", default-features = false, optional = true } objc2-core-graphics = { path = "../objc2-core-graphics", version = "0.2.2", default-features = false, optional = true } +objc2-core-ml = { path = "../objc2-core-ml", version = "0.2.2", default-features = false, optional = true } objc2-core-video = { path = "../objc2-core-video", version = "0.2.2", default-features = false, optional = true } objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false } objc2-io-surface = { path = "../objc2-io-surface", version = "0.2.2", default-features = false, optional = true } @@ -40,20 +41,21 @@ targets = [ default = ["std"] # Currently not possible to turn off, put here for forwards compatibility. -std = ["alloc", "block2?/std", "objc2/std", "objc2-core-foundation?/std", "objc2-core-graphics?/std", "objc2-core-video?/std", "objc2-foundation/std", "objc2-io-surface?/std", "objc2-metal?/std"] -alloc = ["block2?/alloc", "objc2/alloc", "objc2-core-foundation?/alloc", "objc2-core-graphics?/alloc", "objc2-core-video?/alloc", "objc2-foundation/alloc", "objc2-io-surface?/alloc", "objc2-metal?/alloc"] +std = ["alloc", "block2?/std", "objc2/std", "objc2-core-foundation?/std", "objc2-core-graphics?/std", "objc2-core-ml?/std", "objc2-core-video?/std", "objc2-foundation/std", "objc2-io-surface?/std", "objc2-metal?/std"] +alloc = ["block2?/alloc", "objc2/alloc", "objc2-core-foundation?/alloc", "objc2-core-graphics?/alloc", "objc2-core-ml?/alloc", "objc2-core-video?/alloc", "objc2-foundation/alloc", "objc2-io-surface?/alloc", "objc2-metal?/alloc"] apple = [] gnustep-1-7 = ["objc2/gnustep-1-7", "block2?/gnustep-1-7", "objc2-foundation/gnustep-1-7"] gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8", "block2?/gnustep-1-8", "objc2-foundation/gnustep-1-8"] gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9", "block2?/gnustep-1-9", "objc2-foundation/gnustep-1-9"] gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0", "block2?/gnustep-2-0", "objc2-foundation/gnustep-2-0"] gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1", "block2?/gnustep-2-1", "objc2-foundation/gnustep-2-1"] -block2 = ["dep:block2", "objc2-core-foundation?/block2", "objc2-core-graphics?/block2", "objc2-core-video?/block2", "objc2-foundation/block2", "objc2-metal?/block2"] +block2 = ["dep:block2", "objc2-core-foundation?/block2", "objc2-core-graphics?/block2", "objc2-core-ml?/block2", "objc2-core-video?/block2", "objc2-foundation/block2", "objc2-metal?/block2"] objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-core-graphics?/objc2-core-foundation", "objc2-core-video?/objc2-core-foundation", "objc2-foundation/objc2-core-foundation", "objc2-io-surface?/objc2-core-foundation", "objc2-metal?/objc2-core-foundation"] -objc2-core-graphics = ["dep:objc2-core-graphics", "objc2-core-video?/objc2-core-graphics"] -objc2-core-video = ["dep:objc2-core-video"] +objc2-core-graphics = ["dep:objc2-core-graphics", "objc2-core-ml?/objc2-core-graphics", "objc2-core-video?/objc2-core-graphics"] +objc2-core-ml = ["dep:objc2-core-ml"] +objc2-core-video = ["dep:objc2-core-video", "objc2-core-ml?/objc2-core-video"] objc2-io-surface = ["dep:objc2-io-surface", "objc2-core-graphics?/objc2-io-surface", "objc2-core-video?/objc2-io-surface", "objc2-metal?/objc2-io-surface"] -objc2-metal = ["dep:objc2-metal", "objc2-core-graphics?/objc2-metal", "objc2-core-video?/objc2-metal"] +objc2-metal = ["dep:objc2-metal", "objc2-core-graphics?/objc2-metal", "objc2-core-ml?/objc2-metal", "objc2-core-video?/objc2-metal"] CIBarcodeDescriptor = [ "objc2-foundation/NSData", @@ -107,6 +109,15 @@ CIFilter = [ "objc2-foundation/NSString", "objc2-foundation/NSURL", ] +CIFilterBuiltins = [ + "objc2-core-foundation?/CFCGTypes", + "objc2-core-graphics?/CGColorSpace", + "objc2-core-ml?/MLModel", + "objc2-foundation/NSArray", + "objc2-foundation/NSAttributedString", + "objc2-foundation/NSData", + "objc2-foundation/NSString", +] CIFilterConstructor = ["objc2-foundation/NSString"] CIFilterGenerator = [ "objc2-foundation/NSDictionary", @@ -202,7 +213,7 @@ CIRenderDestination = [ "objc2-core-video?/CVPixelBuffer", "objc2-foundation/NSDate", "objc2-foundation/NSError", - "objc2-io-surface?/IOSurfaceObjC", + "objc2-io-surface?/ObjC", "objc2-metal?/MTLAllocation", "objc2-metal?/MTLCommandBuffer", "objc2-metal?/MTLPixelFormat", @@ -228,6 +239,7 @@ all = [ "CIDetector", "CIFeature", "CIFilter", + "CIFilterBuiltins", "CIFilterConstructor", "CIFilterGenerator", "CIFilterShape", @@ -248,6 +260,7 @@ all = [ "block2", "objc2-core-foundation", "objc2-core-graphics", + "objc2-core-ml", "objc2-core-video", "objc2-io-surface", "objc2-metal", diff --git a/framework-crates/objc2-core-image/src/lib.rs b/framework-crates/objc2-core-image/src/lib.rs index fdb5e09e9..667211afa 100644 --- a/framework-crates/objc2-core-image/src/lib.rs +++ b/framework-crates/objc2-core-image/src/lib.rs @@ -8,6 +8,7 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] // Update in Cargo.toml as well. #![doc(html_root_url = "https://docs.rs/objc2-core-image/0.2.2")] +#![recursion_limit = "256"] #[cfg(feature = "alloc")] extern crate alloc; diff --git a/framework-crates/objc2-core-image/translation-config.toml b/framework-crates/objc2-core-image/translation-config.toml index 818a545be..92b14ca2a 100644 --- a/framework-crates/objc2-core-image/translation-config.toml +++ b/framework-crates/objc2-core-image/translation-config.toml @@ -1,12 +1,15 @@ framework = "CoreImage" crate = "objc2-core-image" required-dependencies = ["objc2-foundation"] +custom-lib-rs = true macos = "10.11" maccatalyst = "13.0" ios = "5.0" tvos = "9.0" visionos = "1.0" +external.MLModel.module = "CoreML.MLModel" + # CF_RETURNS_NOT_RETAINED class.CIColor.methods.colorSpace.skipped = true class.CIImage.methods.colorSpace.skipped = true diff --git a/framework-crates/objc2-core-location/translation-config.toml b/framework-crates/objc2-core-location/translation-config.toml index ef7cb8d15..1179d3891 100644 --- a/framework-crates/objc2-core-location/translation-config.toml +++ b/framework-crates/objc2-core-location/translation-config.toml @@ -9,6 +9,8 @@ tvos = "9.0" watchos = "2.0" visionos = "1.0" +external.CNPostalAddress.module = "Contacts.CNPostalAddress" + # error: translator assertion failure: (left `"CLLocation"`) (right `"const CLLocation"`) class.CLLocation.methods."getDistanceFrom:".skipped = true class.CLLocation.methods."distanceFromLocation:".skipped = true diff --git a/framework-crates/objc2-event-kit/translation-config.toml b/framework-crates/objc2-event-kit/translation-config.toml index 9969b4730..023aa7966 100644 --- a/framework-crates/objc2-event-kit/translation-config.toml +++ b/framework-crates/objc2-event-kit/translation-config.toml @@ -7,6 +7,9 @@ ios = "4.0" watchos = "2.0" visionos = "1.0" +external.NSColor.module = "AppKit.NSColor" +external.MKMapItem.module = "MapKit.MKMapItem" + # CF_RETURNS_NOT_RETAINED class.EKParticipant.methods."ABRecordWithAddressBook:".skipped = true diff --git a/framework-crates/objc2-file-provider/Cargo.toml b/framework-crates/objc2-file-provider/Cargo.toml index f13104122..205b4630f 100644 --- a/framework-crates/objc2-file-provider/Cargo.toml +++ b/framework-crates/objc2-file-provider/Cargo.toml @@ -43,6 +43,19 @@ block2 = ["dep:block2", "objc2-core-foundation?/block2", "objc2-foundation/block objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-foundation/objc2-core-foundation"] objc2-uniform-type-identifiers = ["dep:objc2-uniform-type-identifiers"] +Extension = [ + "bitflags", + "objc2-foundation/NSArray", + "objc2-foundation/NSDate", + "objc2-foundation/NSDictionary", + "objc2-foundation/NSError", + "objc2-foundation/NSNotification", + "objc2-foundation/NSProgress", + "objc2-foundation/NSRange", + "objc2-foundation/NSString", + "objc2-foundation/NSURL", + "objc2-foundation/NSURLSession", +] NSFileProviderActions = [ "objc2-foundation/NSData", "objc2-foundation/NSDate", @@ -73,12 +86,6 @@ NSFileProviderError = [ "objc2-foundation/NSError", "objc2-foundation/NSString", ] -NSFileProviderExtension = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", -] NSFileProviderItem = [ "bitflags", "objc2-foundation/NSData", @@ -98,18 +105,6 @@ NSFileProviderKnownFolders = [ "objc2-foundation/NSError", "objc2-foundation/NSString", ] -NSFileProviderManager = [ - "bitflags", - "objc2-foundation/NSArray", - "objc2-foundation/NSDate", - "objc2-foundation/NSError", - "objc2-foundation/NSNotification", - "objc2-foundation/NSProgress", - "objc2-foundation/NSRange", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", - "objc2-foundation/NSURLSession", -] NSFileProviderModifyItemOptions = ["bitflags"] NSFileProviderReplicatedExtension = [ "bitflags", @@ -146,16 +141,15 @@ NSFileProviderThumbnailing = [ "objc2-foundation/NSString", ] all = [ + "Extension", "NSFileProviderActions", "NSFileProviderDefines", "NSFileProviderDomain", "NSFileProviderEnumerating", "NSFileProviderError", - "NSFileProviderExtension", "NSFileProviderItem", "NSFileProviderItemDecoration", "NSFileProviderKnownFolders", - "NSFileProviderManager", "NSFileProviderModifyItemOptions", "NSFileProviderReplicatedExtension", "NSFileProviderRequest", diff --git a/framework-crates/objc2-file-provider/translation-config.toml b/framework-crates/objc2-file-provider/translation-config.toml index 23295caa2..e4afae5a9 100644 --- a/framework-crates/objc2-file-provider/translation-config.toml +++ b/framework-crates/objc2-file-provider/translation-config.toml @@ -6,5 +6,7 @@ macos = "10.15" ios = "11.0" visionos = "1.0" +external.UTType.module = "UniformTypeIdentifiers.UTType" + # Protocol that has a typedef defined for it for ease of use protocol.NSFileProviderItem.renamed = "NSFileProviderItemProtocol" diff --git a/framework-crates/objc2-foundation/Cargo.toml b/framework-crates/objc2-foundation/Cargo.toml index 390308355..a6c21103c 100644 --- a/framework-crates/objc2-foundation/Cargo.toml +++ b/framework-crates/objc2-foundation/Cargo.toml @@ -86,6 +86,7 @@ NSDateComponentsFormatter = ["bitflags"] NSDateFormatter = [] NSDateInterval = [] NSDateIntervalFormatter = [] +NSDebug = [] NSDecimal = [] NSDecimalNumber = [] NSDictionary = [] @@ -259,6 +260,7 @@ all = [ "NSDateFormatter", "NSDateInterval", "NSDateIntervalFormatter", + "NSDebug", "NSDecimal", "NSDecimalNumber", "NSDictionary", diff --git a/framework-crates/objc2-foundation/translation-config.toml b/framework-crates/objc2-foundation/translation-config.toml index 8dd83da51..cb1f7fb8d 100644 --- a/framework-crates/objc2-foundation/translation-config.toml +++ b/framework-crates/objc2-foundation/translation-config.toml @@ -10,6 +10,10 @@ watchos = "2.0" visionos = "1.0" gnustep = true +# FIXME: Avoid the need for this +external.NSImage.module = "AppKit.NSImage" +external.NSPortMessage.module = "Foundation.NSPortMessage" + # ns_consumed / NS_RELEASES_ARGUMENT / cf_consumed / CF_CONSUMED fn.CFBridgingRelease.skipped = true fn.CFBridgingRetain.skipped = true diff --git a/framework-crates/objc2-health-kit/translation-config.toml b/framework-crates/objc2-health-kit/translation-config.toml index b1aaf0d86..95a06dc3a 100644 --- a/framework-crates/objc2-health-kit/translation-config.toml +++ b/framework-crates/objc2-health-kit/translation-config.toml @@ -6,3 +6,5 @@ maccatalyst = "13.0" ios = "8.0" watchos = "2.0" visionos = "1.0" + +external.CLLocation.module = "CoreLocation.CLLocation" diff --git a/framework-crates/objc2-io-surface/Cargo.toml b/framework-crates/objc2-io-surface/Cargo.toml index 48e2236ca..a764e3ce5 100644 --- a/framework-crates/objc2-io-surface/Cargo.toml +++ b/framework-crates/objc2-io-surface/Cargo.toml @@ -44,25 +44,27 @@ libc = ["dep:libc", "objc2-core-foundation?/libc", "objc2-foundation?/libc"] objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-foundation?/objc2-core-foundation"] objc2-foundation = ["dep:objc2-foundation"] +IOSurface = [] IOSurfaceAPI = [] IOSurfaceBase = [] -IOSurfaceObjC = [ - "objc2-foundation?/NSDictionary", - "objc2-foundation?/NSObject", - "objc2-foundation?/NSString", -] IOSurfaceRef = [ "bitflags", "objc2-core-foundation?/CFBase", "objc2-core-foundation?/CFDictionary", ] IOSurfaceTypes = ["bitflags"] +ObjC = [ + "objc2-foundation?/NSDictionary", + "objc2-foundation?/NSObject", + "objc2-foundation?/NSString", +] all = [ + "IOSurface", "IOSurfaceAPI", "IOSurfaceBase", - "IOSurfaceObjC", "IOSurfaceRef", "IOSurfaceTypes", + "ObjC", "bitflags", "libc", "objc2-core-foundation", diff --git a/framework-crates/objc2-map-kit/translation-config.toml b/framework-crates/objc2-map-kit/translation-config.toml index 8baf45ed3..e637f5c47 100644 --- a/framework-crates/objc2-map-kit/translation-config.toml +++ b/framework-crates/objc2-map-kit/translation-config.toml @@ -9,6 +9,8 @@ tvos = "9.2" watchos = "2.0" visionos = "1.0" +external.CNPostalAddress.module = "Contacts.CNPostalAddress" + # Needs `dispatch_queue_t` class.MKMapSnapshotter.methods."startWithQueue:completionHandler:".skipped = true diff --git a/framework-crates/objc2-media-player/translation-config.toml b/framework-crates/objc2-media-player/translation-config.toml index 4ce5d0850..c60241e35 100644 --- a/framework-crates/objc2-media-player/translation-config.toml +++ b/framework-crates/objc2-media-player/translation-config.toml @@ -8,6 +8,8 @@ tvos = "9.0" watchos = "5.0" visionos = "1.0" +external.NSImage.module = "AppKit.NSImage" + # Needs `AVFoundation` framework class.AVMediaSelectionOption.categories.MPNowPlayingInfoLanguageOptionAdditions.skipped = true class.AVMediaSelectionGroup.categories.MPNowPlayingInfoLanguageOptionAdditions.skipped = true diff --git a/framework-crates/objc2-ml-compute/translation-config.toml b/framework-crates/objc2-ml-compute/translation-config.toml index 5a8168231..a3cd9bb1e 100644 --- a/framework-crates/objc2-ml-compute/translation-config.toml +++ b/framework-crates/objc2-ml-compute/translation-config.toml @@ -5,3 +5,5 @@ macos = "11.0" maccatalyst = "14.0" ios = "14.0" tvos = "14.0" + +external.MLModel.module = "CoreML.MLModel" diff --git a/framework-crates/objc2-multipeer-connectivity/Cargo.toml b/framework-crates/objc2-multipeer-connectivity/Cargo.toml index 3bcf13cf7..7f9e0ac39 100644 --- a/framework-crates/objc2-multipeer-connectivity/Cargo.toml +++ b/framework-crates/objc2-multipeer-connectivity/Cargo.toml @@ -87,6 +87,7 @@ MCSession = [ "objc2-foundation/NSString", "objc2-foundation/NSURL", ] +MultipeerConnectivity = [] all = [ "MCAdvertiserAssistant", "MCBrowserViewController", @@ -95,6 +96,7 @@ all = [ "MCNearbyServiceBrowser", "MCPeerID", "MCSession", + "MultipeerConnectivity", "block2", "objc2-app-kit", ] diff --git a/framework-crates/objc2-natural-language/translation-config.toml b/framework-crates/objc2-natural-language/translation-config.toml index a72f707f6..6ad8c73a0 100644 --- a/framework-crates/objc2-natural-language/translation-config.toml +++ b/framework-crates/objc2-natural-language/translation-config.toml @@ -7,3 +7,5 @@ ios = "12.0" tvos = "12.0" watchos = "5.0" visionos = "1.0" + +external.MLModel.module = "CoreML.MLModel" diff --git a/framework-crates/objc2-network-extension/Cargo.toml b/framework-crates/objc2-network-extension/Cargo.toml index 45a5818c8..3d0bc0573 100644 --- a/framework-crates/objc2-network-extension/Cargo.toml +++ b/framework-crates/objc2-network-extension/Cargo.toml @@ -19,7 +19,7 @@ workspace = true block2 = { path = "../../crates/block2", version = "0.5.1", default-features = false, optional = true } libc = { version = "0.2.80", default-features = false, optional = true } objc2 = { path = "../../crates/objc2", version = "0.5.2", default-features = false } -objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false } +objc2-foundation = { path = "../objc2-foundation", version = "0.2.2", default-features = false, features = ["NSArray", "NSData", "NSDate", "NSDictionary", "NSError", "NSObject", "NSSet", "NSString", "NSURL", "NSURLRequest", "NSURLResponse", "NSUUID", "NSValue"] } [package.metadata.docs.rs] default-target = "aarch64-apple-darwin" @@ -42,341 +42,7 @@ alloc = ["block2?/alloc", "objc2/alloc", "objc2-foundation/alloc"] block2 = ["dep:block2", "objc2-foundation/block2"] libc = ["dep:libc", "objc2-foundation/libc"] -NEAppProxyFlow = [ - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEAppProxyProvider = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEAppProxyProviderManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", -] -NEAppProxyTCPFlow = [ - "objc2-foundation/NSData", - "objc2-foundation/NSError", -] -NEAppProxyUDPFlow = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSError", -] -NEAppPushManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEAppPushProvider = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEAppRule = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEDNSProxyManager = [ - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEDNSProxyProvider = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEDNSProxyProviderProtocol = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEDNSSettings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", -] -NEDNSSettingsManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEEthernetTunnelNetworkSettings = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEEthernetTunnelProvider = [] -NEFilterControlProvider = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSString", -] -NEFilterDataProvider = [ - "objc2-foundation/NSData", - "objc2-foundation/NSError", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEFilterFlow = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", - "objc2-foundation/NSURLRequest", - "objc2-foundation/NSURLResponse", - "objc2-foundation/NSUUID", -] -NEFilterManager = [ - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEFilterPacketProvider = [] -NEFilterProvider = [ - "objc2-foundation/NSError", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEFilterProviderConfiguration = [ - "objc2-foundation/NSData", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEFilterRule = ["objc2-foundation/NSObject"] -NEFilterSettings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", -] -NEFlowMetaData = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSUUID", -] -NEHotspotConfigurationManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSValue", -] -NEHotspotHelper = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSString", - "objc2-foundation/NSURLRequest", -] -NEHotspotNetwork = ["objc2-foundation/NSString"] -NEIPv4Settings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEIPv6Settings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSValue", -] -NENetworkRule = ["objc2-foundation/NSObject"] -NEOnDemandRule = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", -] -NEPacket = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", -] -NEPacketTunnelFlow = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSValue", -] -NEPacketTunnelNetworkSettings = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSValue", -] -NEPacketTunnelProvider = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEProvider = ["objc2-foundation/NSString"] -NEProxySettings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", -] -NERelay = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", - "objc2-foundation/NSURL", -] -NERelayManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSDate", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NETransparentProxyManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", -] -NETransparentProxyNetworkSettings = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NETransparentProxyProvider = [] -NETunnelNetworkSettings = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NETunnelProvider = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NETunnelProviderManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NETunnelProviderProtocol = [ - "objc2-foundation/NSDictionary", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NETunnelProviderSession = [ - "objc2-foundation/NSData", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEVPNConnection = [ - "objc2-foundation/NSDate", - "objc2-foundation/NSDictionary", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEVPNManager = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSError", - "objc2-foundation/NSString", -] -NEVPNProtocol = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEVPNProtocolIKEv2 = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NEVPNProtocolIPSec = [ - "objc2-foundation/NSData", - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NWBonjourServiceEndpoint = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NWEndpoint = ["objc2-foundation/NSObject"] -NWHostEndpoint = [ - "objc2-foundation/NSObject", - "objc2-foundation/NSString", -] -NWPath = [] -NWTCPConnection = [ - "objc2-foundation/NSData", - "objc2-foundation/NSError", -] -NWTLSParameters = [ - "objc2-foundation/NSData", - "objc2-foundation/NSSet", - "objc2-foundation/NSValue", -] -NWUDPSession = [ - "objc2-foundation/NSArray", - "objc2-foundation/NSData", - "objc2-foundation/NSError", -] all = [ - "NEAppProxyFlow", - "NEAppProxyProvider", - "NEAppProxyProviderManager", - "NEAppProxyTCPFlow", - "NEAppProxyUDPFlow", - "NEAppPushManager", - "NEAppPushProvider", - "NEAppRule", - "NEDNSProxyManager", - "NEDNSProxyProvider", - "NEDNSProxyProviderProtocol", - "NEDNSSettings", - "NEDNSSettingsManager", - "NEEthernetTunnelNetworkSettings", - "NEEthernetTunnelProvider", - "NEFilterControlProvider", - "NEFilterDataProvider", - "NEFilterFlow", - "NEFilterManager", - "NEFilterPacketProvider", - "NEFilterProvider", - "NEFilterProviderConfiguration", - "NEFilterRule", - "NEFilterSettings", - "NEFlowMetaData", - "NEHotspotConfigurationManager", - "NEHotspotHelper", - "NEHotspotNetwork", - "NEIPv4Settings", - "NEIPv6Settings", - "NENetworkRule", - "NEOnDemandRule", - "NEPacket", - "NEPacketTunnelFlow", - "NEPacketTunnelNetworkSettings", - "NEPacketTunnelProvider", - "NEProvider", - "NEProxySettings", - "NERelay", - "NERelayManager", - "NETransparentProxyManager", - "NETransparentProxyNetworkSettings", - "NETransparentProxyProvider", - "NETunnelNetworkSettings", - "NETunnelProvider", - "NETunnelProviderManager", - "NETunnelProviderProtocol", - "NETunnelProviderSession", - "NEVPNConnection", - "NEVPNManager", - "NEVPNProtocol", - "NEVPNProtocolIKEv2", - "NEVPNProtocolIPSec", - "NWBonjourServiceEndpoint", - "NWEndpoint", - "NWHostEndpoint", - "NWPath", - "NWTCPConnection", - "NWTLSParameters", - "NWUDPSession", "block2", "libc", ] diff --git a/framework-crates/objc2-photos/translation-config.toml b/framework-crates/objc2-photos/translation-config.toml index ab5b58886..9d76a340d 100644 --- a/framework-crates/objc2-photos/translation-config.toml +++ b/framework-crates/objc2-photos/translation-config.toml @@ -8,6 +8,9 @@ ios = "8.0" tvos = "10.0" visionos = "1.0" +external.NSImage.module = "AppKit.NSImage" +external.UIImage.module = "UIKit.UIImage" + # Needs `CGImagePropertyOrientation` from `ImageIO` class.PHLivePhotoEditingContext.methods.orientation.skipped = true class.PHImageManager.methods."requestImageDataAndOrientationForAsset:options:resultHandler:".skipped = true diff --git a/framework-crates/objc2-quartz-core/Cargo.toml b/framework-crates/objc2-quartz-core/Cargo.toml index cee9e6a8e..8e62984e1 100644 --- a/framework-crates/objc2-quartz-core/Cargo.toml +++ b/framework-crates/objc2-quartz-core/Cargo.toml @@ -207,8 +207,6 @@ CAValueFunction = [ "objc2-foundation/NSString", ] CoreAnimation = [] -CoreImage = [] -CoreVideo = [] all = [ "CAAnimation", "CABase", @@ -238,8 +236,6 @@ all = [ "CATransformLayer", "CAValueFunction", "CoreAnimation", - "CoreImage", - "CoreVideo", "bitflags", "block2", "libc", diff --git a/framework-crates/objc2-social/translation-config.toml b/framework-crates/objc2-social/translation-config.toml index c358b4ede..c44728944 100644 --- a/framework-crates/objc2-social/translation-config.toml +++ b/framework-crates/objc2-social/translation-config.toml @@ -4,3 +4,5 @@ required-dependencies = ["objc2-foundation"] macos = "10.8" maccatalyst = "13.0" ios = "6.0" + +external.ACAccount.module = "Accounts.ACAccount" diff --git a/framework-crates/objc2-ui-kit/Cargo.toml b/framework-crates/objc2-ui-kit/Cargo.toml index ba6216df3..dc53cd585 100644 --- a/framework-crates/objc2-ui-kit/Cargo.toml +++ b/framework-crates/objc2-ui-kit/Cargo.toml @@ -52,7 +52,7 @@ std = ["alloc", "bitflags?/std", "block2?/std", "objc2/std", "objc2-cloud-kit?/s alloc = ["block2?/alloc", "objc2/alloc", "objc2-cloud-kit?/alloc", "objc2-core-data?/alloc", "objc2-core-foundation?/alloc", "objc2-core-graphics?/alloc", "objc2-core-image?/alloc", "objc2-core-location?/alloc", "objc2-foundation/alloc", "objc2-quartz-core?/alloc", "objc2-symbols?/alloc", "objc2-uniform-type-identifiers?/alloc", "objc2-user-notifications?/alloc"] bitflags = ["dep:bitflags", "objc2-cloud-kit?/bitflags", "objc2-core-data?/bitflags", "objc2-core-foundation?/bitflags", "objc2-core-graphics?/bitflags", "objc2-foundation/bitflags", "objc2-quartz-core?/bitflags", "objc2-user-notifications?/bitflags"] block2 = ["dep:block2", "objc2-cloud-kit?/block2", "objc2-core-data?/block2", "objc2-core-foundation?/block2", "objc2-core-graphics?/block2", "objc2-core-image?/block2", "objc2-core-location?/block2", "objc2-foundation/block2", "objc2-quartz-core?/block2", "objc2-uniform-type-identifiers?/block2", "objc2-user-notifications?/block2"] -objc2-cloud-kit = ["dep:objc2-cloud-kit"] +objc2-cloud-kit = ["dep:objc2-cloud-kit", "objc2-core-data?/objc2-cloud-kit"] objc2-core-data = ["dep:objc2-core-data"] objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-core-graphics?/objc2-core-foundation", "objc2-core-image?/objc2-core-foundation", "objc2-foundation/objc2-core-foundation", "objc2-quartz-core?/objc2-core-foundation"] objc2-core-graphics = ["dep:objc2-core-graphics", "objc2-core-image?/objc2-core-graphics", "objc2-quartz-core?/objc2-core-graphics"] diff --git a/framework-crates/objc2-ui-kit/translation-config.toml b/framework-crates/objc2-ui-kit/translation-config.toml index 55e2a32a8..9e6815e75 100644 --- a/framework-crates/objc2-ui-kit/translation-config.toml +++ b/framework-crates/objc2-ui-kit/translation-config.toml @@ -8,6 +8,15 @@ tvos = "9.0" watchos = "2.0" visionos = "1.0" +external.UTType.module = "UniformTypeIdentifiers.UTType" +external.CKContainer.module = "CloudKit.CKContainer" +external.CKShare.module = "CloudKit.CKShare" +external.CKShare.required-items = ["CloudKit.CKRecord.CKRecord"] +external.CKShareMetadata.module = "CloudKit.CKShareMetadata" +external.NSManagedObjectContext.module = "CoreData.NSManagedObjectContext" +external.NSManagedObjectModel.module = "CoreData.NSManagedObjectModel" +external.CLRegion.module = "CoreLocation.CLRegion" + # CF_RETURNS_NOT_RETAINED fn.UIGraphicsGetCurrentContext.skipped = true class.UIGraphicsRenderer.methods."contextWithFormat:".skipped = true diff --git a/framework-crates/objc2-user-notifications/translation-config.toml b/framework-crates/objc2-user-notifications/translation-config.toml index a0bb8c7a3..8c8175a91 100644 --- a/framework-crates/objc2-user-notifications/translation-config.toml +++ b/framework-crates/objc2-user-notifications/translation-config.toml @@ -8,6 +8,8 @@ tvos = "10.0" watchos = "3.0" visionos = "1.0" +external.CLRegion.module = "CoreLocation.CLRegion" + class.UNNotificationContent.counterpart = "MutableSubclass(UserNotifications::UNNotificationContent::UNMutableNotificationContent)" class.UNMutableNotificationContent.counterpart = "ImmutableSuperclass(UserNotifications::UNNotificationContent::UNNotificationContent)" diff --git a/framework-crates/objc2-vision/Cargo.toml b/framework-crates/objc2-vision/Cargo.toml index 924b9e090..e1cc13f81 100644 --- a/framework-crates/objc2-vision/Cargo.toml +++ b/framework-crates/objc2-vision/Cargo.toml @@ -46,7 +46,7 @@ block2 = ["dep:block2", "objc2-core-foundation?/block2", "objc2-core-graphics?/b objc2-core-foundation = ["dep:objc2-core-foundation", "objc2-core-graphics?/objc2-core-foundation", "objc2-core-image?/objc2-core-foundation", "objc2-core-video?/objc2-core-foundation", "objc2-foundation/objc2-core-foundation"] objc2-core-graphics = ["dep:objc2-core-graphics", "objc2-core-image?/objc2-core-graphics", "objc2-core-ml?/objc2-core-graphics", "objc2-core-video?/objc2-core-graphics"] objc2-core-image = ["dep:objc2-core-image"] -objc2-core-ml = ["dep:objc2-core-ml"] +objc2-core-ml = ["dep:objc2-core-ml", "objc2-core-image?/objc2-core-ml"] objc2-core-video = ["dep:objc2-core-video", "objc2-core-image?/objc2-core-video", "objc2-core-ml?/objc2-core-video"] VNCalculateImageAestheticsScoresRequest = [ @@ -255,7 +255,6 @@ VNObservation = [ "objc2-foundation/NSIndexPath", "objc2-foundation/NSIndexSet", "objc2-foundation/NSObject", - "objc2-foundation/NSRange", "objc2-foundation/NSString", "objc2-foundation/NSUUID", "objc2-foundation/NSValue", diff --git a/framework-crates/objc2-vision/translation-config.toml b/framework-crates/objc2-vision/translation-config.toml index 74bda8adb..b80e5cdce 100644 --- a/framework-crates/objc2-vision/translation-config.toml +++ b/framework-crates/objc2-vision/translation-config.toml @@ -8,6 +8,9 @@ ios = "11.0" tvos = "11.0" visionos = "1.0" +external.CIBarcodeDescriptor.module = "CoreImage.CIBarcodeDescriptor" +external.CIImage.module = "CoreImage.CIImage" + # Needs SIMD types, which we cannot yet describe the ABI of in Rust fn.VNNormalizedFaceBoundingBoxPointForLandmarkPoint.skipped = true fn.VNImagePointForFaceLandmarkPoint.skipped = true @@ -24,6 +27,9 @@ class.VNHumanBodyPose3DObservation.methods."getCameraRelativePosition:forJointNa # error: unknown error result type class.VNTrackingRequest.methods."supportedNumberOfTrackersAndReturnError:".skipped = true +# apinotes are being weird here +class.VNRecognizedText.methods."boundingBoxForRange:error:".skipped = true + # Needs CoreMedia class.VNDetectHumanBodyPose3DRequest.methods."initWithFrameAnalysisSpacing:completionHandler:".skipped = true class.VNDetectTrajectoriesRequest.methods."initWithFrameAnalysisSpacing:completionHandler:".skipped = true diff --git a/generated b/generated index 8358a76b7..4d7199680 160000 --- a/generated +++ b/generated @@ -1 +1 @@ -Subproject commit 8358a76b72d7f9d6c0509a10eb3529f1108efaa0 +Subproject commit 4d7199680294c260d78c2795ef661d4e9b5ec322