Skip to content

Commit

Permalink
Merge pull request #629 from madsmtm/xcode-16
Browse files Browse the repository at this point in the history
Update to Xcode 16
  • Loading branch information
madsmtm authored Sep 21, 2024
2 parents b94961a + a8d4434 commit afc0723
Show file tree
Hide file tree
Showing 48 changed files with 634 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ jobs:
- lint

env:
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_16.0.app/Contents/Developer

steps:
- uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/header-translator/src/availability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ impl Availability {
if let Some(m) = availability.message {
if let Some(message) = message.as_deref() {
if m != message {
error!(m, message, "message availability attributes were not equal");
// TODO: Either use `cfg_attr` on the `deprecated`
// attributes, or merge it into a single string.
warn!(m, message, "message availability attributes were not equal");
}
}
message = Some(m);
Expand Down
36 changes: 27 additions & 9 deletions crates/header-translator/src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashSet};
use std::fmt;

use clang::token::TokenKind;
use clang::{Entity, EntityKind, EntityVisitResult, EvaluationResult};

use crate::rust_type::Ty;
use crate::stmt::{enum_constant_name, new_enum_id};
use crate::{Context, ItemIdentifier};
use crate::unexposed_attr::UnexposedAttr;
use crate::{immediate_children, Context, ItemIdentifier};

#[derive(Clone, Debug, PartialEq)]
pub enum Token {
Expand All @@ -27,7 +28,7 @@ pub enum Expr {
Enum {
id: ItemIdentifier,
variant: String,
// TODO: Type
attrs: HashSet<UnexposedAttr>,
},
Const(ItemIdentifier), // TODO: Type
Var {
Expand Down Expand Up @@ -180,9 +181,18 @@ impl Expr {
let parent_id = new_enum_id(&parent, context);
let name = entity.get_name().expect("EnumConstantDecl name");
if parent_id.name.is_some() {
let mut attrs = HashSet::new();
immediate_children(&parent, |entity, _span| {
if let EntityKind::UnexposedAttr = entity.get_kind() {
if let Some(attr) = UnexposedAttr::parse(&entity, context) {
attrs.insert(attr);
}
}
});
Self::Enum {
id: parent_id.map_name(|name| name.unwrap()),
variant: name,
attrs,
}
} else {
Self::Const(parent_id.map_name(|_| name))
Expand Down Expand Up @@ -256,17 +266,25 @@ impl fmt::Display for Expr {
write!(f, "{}", id.path())
}
}
Self::Enum { id, variant } => {
Self::Enum { id, variant, attrs } => {
let pretty_name = enum_constant_name(&id.name, variant);
// Note: Even if we had the enum kind available here, we would
// not be able to avoid the `.0` here, as the expression must
// be `const`.
write!(f, "{}::{pretty_name}.0", id.name)
if attrs.contains(&UnexposedAttr::ClosedEnum) {
// Close enums are actual Rust `enum`s, so to get their
// value, we use an `as` cast.
// Using `usize` here is a hack, we should be using the
// actual enum type.
write!(f, "{}::{pretty_name} as usize", id.name)
} else {
// Note: Even though we have the enum kind available here,
// we cannot avoid the `.0` here, as the expression must
// be `const`.
write!(f, "{}::{pretty_name}.0", id.name)
}
}
Self::Const(id) => write!(f, "{}", id.name),
Self::Var { id, ty } => {
if ty.is_enum_through_typedef() {
write!(f, "{}.0", id.name)
write!(f, "{}.xxx", id.name)
} else {
write!(f, "{}", id.name)
}
Expand Down
8 changes: 7 additions & 1 deletion crates/header-translator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,19 @@ fn parse_sdk(
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(),
));
file_span.take();
}
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()));
}

Expand Down
50 changes: 30 additions & 20 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,29 @@ pub enum Ty {

impl Ty {
fn parse(attributed_ty: Type<'_>, mut lifetime: Lifetime, context: &Context<'_>) -> Self {
let _span = debug_span!("ty", ?attributed_ty, ?lifetime).entered();

let mut ty = attributed_ty;
while let TypeKind::Attributed = ty.get_kind() {
ty = ty
.get_modified_type()
.expect("attributed type to have modified type");
}

let _span = debug_span!("ty2", ?ty).entered();
let _span = debug_span!("ty", ?ty, ?lifetime).entered();

let mut attributed_name = attributed_ty.get_display_name();
let mut name = ty.get_display_name();
let mut unexposed_nullability = None;

while let TypeKind::Unexposed | TypeKind::Attributed = ty.get_kind() {
if let TypeKind::Attributed = ty.get_kind() {
ty = ty
.get_modified_type()
.expect("attributed type to have modified type");
name = ty.get_display_name();
continue;
}

if let Some(nullability) = ty.get_nullability() {
if unexposed_nullability.is_some() {
error!("unexposed nullability already set");
}
unexposed_nullability = Some(nullability);
}

let unexposed_nullability = if let TypeKind::Unexposed = ty.get_kind() {
let nullability = ty.get_nullability();
let (new_attributed_name, attributed_attr) = parse_unexposed_tokens(&attributed_name);
// Also parse the expected name to ensure that the formatting that
// TokenStream does is the same on both.
Expand All @@ -453,7 +460,12 @@ impl Ty {
}

match attr {
Some(UnexposedAttr::NonIsolated | UnexposedAttr::UIActor) => {
Some(
UnexposedAttr::NonIsolated
| UnexposedAttr::UIActor
| UnexposedAttr::Sendable
| UnexposedAttr::NonSendable,
) => {
// Ignored for now; these are usually also emitted on the method/property,
// which is where they will be useful in any case.
}
Expand All @@ -467,22 +479,19 @@ impl Ty {
if let Some(modified) = ty.get_modified_type() {
ty = modified;
} else {
error!("expected unexposed type to have modified type");
error!("expected unexposed / attributed type to have modified type");
}
nullability
} else {
None
};
}

let _span = debug_span!("ty3", ?ty).entered();
let _span = debug_span!("ty after unexposed/attributed", ?ty).entered();

let elaborated_ty = ty;

if let Some(true) = ty.is_elaborated() {
ty = ty.get_elaborated_type().expect("elaborated");
}

let _span = debug_span!("ty4", ?ty).entered();
let _span = debug_span!("ty after elaborated", ?ty).entered();

let get_is_const = |new: bool| {
if new {
Expand Down Expand Up @@ -722,10 +731,11 @@ impl Ty {

let is_const = get_is_const(parser.is_const(ParsePosition::Suffix));
lifetime.update(parser.lifetime(ParsePosition::Suffix));
let nullability = parser.nullability(ParsePosition::Suffix);
let nullability = if let Some(nullability) = unexposed_nullability {
nullability
} else {
check_nullability(&attributed_ty, parser.nullability(ParsePosition::Suffix))
check_nullability(&attributed_ty, nullability)
};

let ty = ty.get_pointee_type().expect("pointer type to have pointee");
Expand Down
27 changes: 22 additions & 5 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,8 @@ impl Stmt {
}
match attr {
// TODO
UnexposedAttr::Sendable => warn!("sendable on typedef"),
UnexposedAttr::Sendable => warn!("sendable typedef"),
UnexposedAttr::UIActor => warn!("main-thread-only typedef"),
_ => kind = Some(attr),
}
}
Expand Down Expand Up @@ -1290,7 +1291,15 @@ impl Stmt {
immediate_children(entity, |entity, _span| match entity.get_kind() {
EntityKind::UnexposedAttr => {
if let Some(attr) = UnexposedAttr::parse(&entity, context) {
error!(?attr, "unknown attribute");
match attr {
// Swift makes some statics associated with a
// certain type, which means it needs this to
// allow accessing them from any thread. We
// don't generally restrict statics in this
// fashion, so it shouldn't matter for us.
UnexposedAttr::NonIsolated => {}
attr => error!(?attr, "unknown attribute"),
}
}
}
EntityKind::VisibilityAttr => {}
Expand Down Expand Up @@ -1344,7 +1353,13 @@ impl Stmt {
immediate_children(entity, |entity, _span| match entity.get_kind() {
EntityKind::UnexposedAttr => {
if let Some(attr) = UnexposedAttr::parse(&entity, context) {
error!(?attr, "unknown attribute");
match attr {
// TODO
UnexposedAttr::UIActor => {
warn!("unhandled UIActor on function declaration")
}
_ => error!(?attr, "unknown attribute"),
}
}
}
EntityKind::ObjCClassRef
Expand Down Expand Up @@ -2443,12 +2458,14 @@ impl Stmt {
write!(f, "{}", self.cfg_gate_ln(config))?;
writeln!(f, "pub type {} = {};", id.name, ty.typedef())?;
}
None | Some(UnexposedAttr::BridgedTypedef) => {
kind => {
if !matches!(kind, None | Some(UnexposedAttr::BridgedTypedef)) {
error!("invalid alias kind {kind:?} for {ty:?}");
}
// "bridged" typedefs should use a normal type alias.
write!(f, "{}", self.cfg_gate_ln(config))?;
writeln!(f, "pub type {} = {};", id.name, ty.typedef())?;
}
kind => panic!("invalid alias kind {kind:?} for {ty:?}"),
}
}
};
Expand Down
4 changes: 3 additions & 1 deletion crates/header-translator/src/unexposed_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl UnexposedAttr {
}
"NS_SWIFT_SENDABLE" | "AS_SWIFT_SENDABLE" => Some(Self::Sendable),
"NS_SWIFT_NONSENDABLE" => Some(Self::NonSendable),
"NS_SWIFT_UI_ACTOR" => Some(Self::UIActor),
"NS_SWIFT_UI_ACTOR" | "WK_SWIFT_UI_ACTOR" => Some(Self::UIActor),
"NS_SWIFT_NONISOLATED" | "UIKIT_SWIFT_ACTOR_INDEPENDENT" => Some(Self::NonIsolated),
// TODO
"NS_FORMAT_FUNCTION" | "NS_FORMAT_ARGUMENT" => {
Expand Down Expand Up @@ -125,11 +125,13 @@ impl UnexposedAttr {
| "CI_GL_DEPRECATED_MAC"
| "CIKL_DEPRECATED"
| "CK_UNAVAILABLE"
| "CK_NEWLY_UNAVAILABLE"
| "FPUI_AVAILABLE"
| "MLCOMPUTE_AVAILABLE_STARTING"
| "MLCOMPUTE_AVAILABLE_STARTING_BUT_DEPRECATED_MACOS14"
| "MLCOMPUTE_CLASS_AVAILABLE_STARTING"
| "MLCOMPUTE_ENUM_AVAILABLE_STARTING"
| "MODELCOLLECTION_SUNSET"
| "MP_API"
| "MP_DEPRECATED"
| "MP_DEPRECATED_WITH_REPLACEMENT"
Expand Down
60 changes: 60 additions & 0 deletions crates/objc2/src/topics/about_generated/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* **BREAKING**: Renamed `from_id_slice` to `from_retained_slice`.
* **BREAKING**: Renamed `NSString::as_str` to `to_str`, and made it `unsafe`,
since we cannot ensure that the given pool is actually the innermost pool.
* Updated SDK from Xcode 15.4 to 16.0.

View the release notes to learn more details:
- [16.0](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes)

Breaking changes are noted elsewhere in this changelog entry.
* **BREAKING**: `NSWindowSharingReadWrite` was deprecated, and moved from
`NSWindowSharingType` to a separate static.
* **BREAKING**: Moved a few methods on AppKit `NSAttributedString` categories.
- `NSAttributedStringKitAdditions` moved to
`NSAttributedStringAppKitAdditions`.
- `NSMutableAttributedStringKitAdditions` moved to
`NSMutableAttributedStringAppKitAdditions`.
- `NSAttributedStringDocumentFormats` moved to
`NSAttributedStringAppKitDocumentFormats`.
- `NSAttributedStringAppKitAttributeFixing` moved to
* **BREAKING**: Make `"MTLResource"` a sub-protocol of the new `MTLAllocation`.
This makes a bunch of things cfg-gated behind `"MTLAllocation"`.
* **BREAKING**: Cfg-gated `LABiometryType` behind `"LABiometryType"` instead
of `"LAContext"`.
* **BREAKING**: Cfg-gated `HKAudiogramSensitivityPoint` behind
`"HKAudiogramSensitivityPoint"` instead of `"HKAudiogramSample"`.

### Deprecated
* Moved `MainThreadMarker` from `objc2-foundation` to `objc2`.
Expand All @@ -66,10 +88,48 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `UIDocumentProperties::initWithMetadata`
- `UIDocumentProperties::metadata`
- `UIDocumentProperties::setMetadata`
* **BREAKING**: Removed a bunch of deprecated methods in CloudKit:
- `CKFetchNotificationChangesOperation::initWithPreviousServerChangeToken`
- `CKFetchNotificationChangesOperation::previousServerChangeToken`
- `CKFetchNotificationChangesOperation::resultsLimit`
- `CKFetchNotificationChangesOperation::moreComing`
- `CKFetchNotificationChangesOperation::notificationChangedBlock`
- `CKMarkNotificationsReadOperation::initWithNotificationIDsToMarkRead`
- `CKMarkNotificationsReadOperation::notificationIDs`
- `CKMarkNotificationsReadOperation::markNotificationsReadCompletionBlock`
- `CKModifyBadgeOperation::initWithBadgeValue`
- `CKModifyBadgeOperation::initWithBadgeValue`
- `CKModifyBadgeOperation::badgeValue`
- `CKModifyBadgeOperation::modifyBadgeCompletionBlock`
- `CKModifyBadgeOperation::initWithBadgeValue`
* **BREAKING**: Removed `SCStreamDelegate::userDidStopStream`.
- **BREAKING**: Removed `BGContinuedProcessingTaskRequest`.

### Fixed
* **BREAKING**: Converted function signatures into using `extern "C-unwind"`.
This allows Rust and Objective-C unwinding to interoperate.
* Removed incorrectly declared `BGTask::new` method.
* **BREAKING**: Marked the following classes and protocols as `MainThreadOnly`:
- `ASAuthorizationControllerPresentationContextProviding`,
- `ASAuthorizationControllerDelegate`
- `ASAuthorizationProviderExtensionAuthorizationRequestHandler`
- `ASAccountAuthenticationModificationControllerPresentationContextProviding`
- `ASWebAuthenticationPresentationContextProviding`
- `EXHostViewControllerDelegate`
- `MKMapViewDelegate`
- `MTKViewDelegate`
- `UIToolTipConfiguration`
- `UIToolTipInteractionDelegate`
- `UITraitListEnvironment`
- `NSOutlineViewDelegate`
- `MEComposeSessionHandler`
- `MEExtension`
- `MEMessageSecurityHandler`
- `PHContentEditingController`
- `PHLivePhotoViewDelegate`
- A bunch of things in `WebKit`.
* **BREAKING**: Marked methods on the `NSObjectUIAccessibility` category as
`MainThreadOnly`.


## 0.2.2 - 2024-05-21
Expand Down
12 changes: 6 additions & 6 deletions crates/objc2/src/topics/about_generated/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ for the [`block2`] crate for how to call such methods using a closure.

## Currently supported versions

- macOS: `10.12-14.5`
- iOS/iPadOS: `10.0-17.5` (WIP)
- tvOS: `10.0-17.5` (WIP)
- watchOS: `5.0-10.5` (WIP)
- visionOS: `1.0-1.2` (WIP)
- macOS: `10.12-15.0`
- iOS/iPadOS: `10.0-18.0` (WIP)
- tvOS: `10.0-18.0` (WIP)
- watchOS: `5.0-11.0` (WIP)
- visionOS: `1.0-2.0` (WIP)

These bindings are currently generated from the SDKs in Xcode 15.4.
These bindings are currently generated from the SDKs in Xcode 16.0.
The Xcode version will be periodically updated.
Loading

0 comments on commit afc0723

Please sign in to comment.