Skip to content

Commit

Permalink
Automatically determine MainThreadOnly ClassType::Mutability
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Sep 3, 2023
1 parent 78f9941 commit a897b42
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 25 deletions.
48 changes: 34 additions & 14 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ pub enum Mutability {
MutableWithImmutableSuperclass(ItemIdentifier),
#[default]
InteriorMutable,
// MainThreadOnly,
MainThreadOnly,
}

impl Mutability {
Expand All @@ -330,6 +330,7 @@ impl fmt::Display for Mutability {
write!(f, "MutableWithImmutableSuperclass<{}>", superclass.path())
}
Self::InteriorMutable => write!(f, "InteriorMutable"),
Self::MainThreadOnly => write!(f, "MainThreadOnly"),
}
}
}
Expand All @@ -349,7 +350,6 @@ pub enum Stmt {
mutability: Mutability,
skipped: bool,
sendable: bool,
mainthreadonly: bool,
},
/// @interface class_name (name) <protocols*>
/// ->
Expand Down Expand Up @@ -565,7 +565,7 @@ impl Stmt {
context,
);

let (sendable, mainthreadonly) = parse_attributes(entity, context);
let (sendable, mut mainthreadonly) = parse_attributes(entity, context);

let mut protocols = Default::default();
parse_protocols(entity, &mut protocols, context);
Expand All @@ -579,7 +579,17 @@ impl Stmt {

let superclasses: Vec<_> = superclasses_full
.iter()
.map(|(id, generics, _)| (id.clone(), generics.clone()))
.map(|(id, generics, entity)| {
// Ignore sendability on superclasses; because it's an auto trait, it's propagated to subclasses anyhow!
let (_sendable, superclass_mainthreadonly) =
parse_attributes(entity, context);

if superclass_mainthreadonly {
mainthreadonly = true;
}

(id.clone(), generics.clone())
})
.collect();

// Used for duplicate checking (sometimes the subclass
Expand All @@ -592,8 +602,6 @@ impl Stmt {
.filter_map(|(superclass_id, _, entity)| {
let superclass_data = context.class_data.get(&superclass_id.name);

// let (sendable, mainthreadonly) = parse_attributes(entity, context);

// Explicitly keep going, even if the class itself is skipped
// if superclass_data.skipped

Expand Down Expand Up @@ -647,10 +655,13 @@ impl Stmt {
superclasses,
designated_initializers,
derives: data.map(|data| data.derives.clone()).unwrap_or_default(),
mutability: data.map(|data| data.mutability.clone()).unwrap_or_default(),
mutability: if mainthreadonly {
Mutability::MainThreadOnly
} else {
data.map(|data| data.mutability.clone()).unwrap_or_default()
},
skipped: data.map(|data| data.definition_skipped).unwrap_or_default(),
sendable: sendable.unwrap_or(false),
mainthreadonly,
})
.chain(protocols.into_iter().map(|protocol| Self::ProtocolImpl {
cls: id.clone(),
Expand Down Expand Up @@ -694,7 +705,7 @@ impl Stmt {
);

let (sendable, mainthreadonly) = parse_attributes(entity, context);
if sendable.is_some() {
if let Some(sendable) = sendable {
error!(?sendable, "sendable on category");
}
if mainthreadonly {
Expand All @@ -710,7 +721,18 @@ impl Stmt {

let superclasses: Vec<_> = parse_superclasses(entity, context)
.into_iter()
.map(|(id, generics, _)| (id, generics))
.map(|(id, generics, entity)| {
let (sendable, mainthreadonly) = parse_attributes(&entity, context);

if let Some(sendable) = sendable {
error!(?sendable, "sendable on category superclass");
}
if mainthreadonly {
error!("@UIActor on category superclass");
}

(id, generics)
})
.collect();

let subclass_methods = if let Mutability::ImmutableWithMutableSubclass(subclass) =
Expand All @@ -719,8 +741,6 @@ impl Stmt {
let subclass_data = context.class_data.get(&subclass.name);
assert!(!subclass_data.map(|data| data.skipped).unwrap_or_default());

// let (sendable, mainthreadonly) = parse_attributes(entity, context);

let (mut methods, _) = parse_methods(
entity,
|name| {
Expand Down Expand Up @@ -1320,7 +1340,6 @@ impl fmt::Display for Stmt {
mutability,
skipped,
sendable,
mainthreadonly: _,
} => {
if *skipped {
return Ok(());
Expand All @@ -1337,7 +1356,8 @@ impl fmt::Display for Stmt {
Mutability::Immutable
| Mutability::Mutable
| Mutability::ImmutableWithMutableSubclass(_)
| Mutability::InteriorMutable => id.feature(),
| Mutability::InteriorMutable
| Mutability::MainThreadOnly => id.feature(),
};

let (superclass, superclasses_rest) = superclasses.split_at(1);
Expand Down
19 changes: 18 additions & 1 deletion crates/icrate/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Moved the `ns_string!` macro to `icrate::Foundation::ns_string`. The old
location in the crate root is deprecated.
* Use SDK from Xcode 14.3.1 (previously Xcode 14.2).
* **BREAKING**: The following two methods on `MTLAccelerationStructureCommandEncoder` now take a nullable scratch buffer:
* **BREAKING**: The following two methods on
`MTLAccelerationStructureCommandEncoder` now take a nullable scratch buffer:
- `refitAccelerationStructure_descriptor_destination_scratchBuffer_scratchBufferOffset`
- `refitAccelerationStructure_descriptor_destination_scratchBuffer_scratchBufferOffset_options`
* **BREAKING**: Marked UI-related types as `MainThreadOnly`. This means that
they can now only be constructed on the main thread, meaning you have to
aquire a `MainThreadMarker` first.

```rust
// Before
let app = unsafe { NSApplication::sharedApplication() };
let view = unsafe { NSView::initWithFrame(NSView::alloc(), frame) };
// Do something with `app` and `view`

// After
let mtm = MainThreadMarker::new().unwrap();
let app = unsafe { NSApplication::sharedApplication(mtm) };
let view = unsafe { NSView::initWithFrame(mtm.alloc(), frame) };
// Do something with `app` and `view`
```

### Removed
* **BREAKING**: Removed the `MainThreadMarker` argument from the closure
Expand Down
5 changes: 2 additions & 3 deletions crates/icrate/examples/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ declare_class!(
mod ivars;

unsafe impl ClassType for AppDelegate {
#[inherits(NSObject)]
type Super = icrate::AppKit::NSResponder;
type Mutability = mutability::InteriorMutable;
type Super = NSObject;
type Mutability = mutability::MainThreadOnly;
const NAME: &'static str = "MyAppDelegate";
}

Expand Down
4 changes: 2 additions & 2 deletions crates/icrate/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub(crate) use std::os::raw::{
pub(crate) use objc2::ffi::{NSInteger, NSIntegerMax, NSUInteger, NSUIntegerMax, IMP};
#[cfg(feature = "objective-c")]
pub(crate) use objc2::mutability::{
Immutable, ImmutableWithMutableSubclass, InteriorMutable, IsIdCloneable, Mutable,
MutableWithImmutableSuperclass,
Immutable, ImmutableWithMutableSubclass, InteriorMutable, IsIdCloneable, MainThreadOnly,
Mutable, MutableWithImmutableSuperclass,
};
#[cfg(feature = "objective-c")]
pub(crate) use objc2::rc::{Allocated, DefaultId, Id};
Expand Down
2 changes: 1 addition & 1 deletion crates/icrate/src/fixes/AppKit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extern_class!(
unsafe impl ClassType for NSPopover {
#[inherits(NSObject)]
type Super = crate::AppKit::NSResponder;
type Mutability = InteriorMutable;
type Mutability = MainThreadOnly;
}
);

Expand Down
6 changes: 3 additions & 3 deletions crates/icrate/src/fixes/AuthenticationServices/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern_class!(
#[cfg(feature = "AuthenticationServices_ASCredentialProviderViewController")]
unsafe impl ClassType for ASCredentialProviderViewController {
type Super = ASViewController;
type Mutability = InteriorMutable;
type Mutability = MainThreadOnly;
}
);

Expand All @@ -31,7 +31,7 @@ extern_class!(
#[cfg(feature = "AuthenticationServices_ASAccountAuthenticationModificationViewController")]
unsafe impl ClassType for ASAccountAuthenticationModificationViewController {
type Super = ASViewController;
type Mutability = InteriorMutable;
type Mutability = MainThreadOnly;
}
);

Expand All @@ -43,6 +43,6 @@ extern_class!(
#[cfg(feature = "AuthenticationServices_ASAuthorizationAppleIDButton")]
unsafe impl ClassType for ASAuthorizationAppleIDButton {
type Super = ASControl;
type Mutability = InteriorMutable;
type Mutability = MainThreadOnly;
}
);
2 changes: 1 addition & 1 deletion crates/icrate/src/generated

0 comments on commit a897b42

Please sign in to comment.