Skip to content

Commit 8812f32

Browse files
committed
Autogenerate NSCopying and NSMutableCopying impls
1 parent 30e9e79 commit 8812f32

File tree

4 files changed

+57
-126
lines changed

4 files changed

+57
-126
lines changed

crates/header-translator/src/stmt.rs

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,21 +1050,37 @@ impl fmt::Display for Stmt {
10501050
}
10511051
}
10521052

1053-
struct GenericParamsHelper<'a>(&'a [String]);
1053+
struct GenericParamsHelper<'a>(&'a [String], &'a str);
10541054

10551055
impl fmt::Display for GenericParamsHelper<'_> {
10561056
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10571057
if !self.0.is_empty() {
10581058
write!(f, "<")?;
10591059
for generic in self.0 {
1060-
write!(f, "{generic}: Message, ")?;
1060+
write!(f, "{generic}: {}, ", self.1)?;
10611061
}
10621062
write!(f, ">")?;
10631063
}
10641064
Ok(())
10651065
}
10661066
}
10671067

1068+
struct WhereBoundHelper<'a>(&'a [String], Option<&'a str>);
1069+
1070+
impl fmt::Display for WhereBoundHelper<'_> {
1071+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1072+
if let Some(bound) = self.1 {
1073+
if !self.0.is_empty() {
1074+
writeln!(f, "where")?;
1075+
for generic in self.0 {
1076+
writeln!(f, "{generic}{bound},")?;
1077+
}
1078+
}
1079+
}
1080+
Ok(())
1081+
}
1082+
}
1083+
10681084
match self {
10691085
Self::ClassDecl {
10701086
id,
@@ -1137,7 +1153,7 @@ impl fmt::Display for Stmt {
11371153
writeln!(
11381154
f,
11391155
" unsafe impl{} ClassType for {}{} {{",
1140-
GenericParamsHelper(generics),
1156+
GenericParamsHelper(generics, "Message"),
11411157
id.name,
11421158
GenericTyHelper(generics),
11431159
)?;
@@ -1209,7 +1225,7 @@ impl fmt::Display for Stmt {
12091225
writeln!(
12101226
f,
12111227
" unsafe impl{} {}{} {{",
1212-
GenericParamsHelper(generics),
1228+
GenericParamsHelper(generics, "Message"),
12131229
cls.path_in_relation_to(category),
12141230
GenericTyHelper(generics),
12151231
)?;
@@ -1256,30 +1272,54 @@ impl fmt::Display for Stmt {
12561272
writeln!(f, " }}")?;
12571273
writeln!(f, ");")?;
12581274
}
1259-
Self::ProtocolImpl {
1260-
cls: _,
1261-
generics: _,
1262-
protocol,
1263-
availability: _,
1264-
} if protocol.name == "NSCopying" || protocol.name == "NSMutableCopying" => {
1265-
// TODO
1266-
}
12671275
Self::ProtocolImpl {
12681276
cls,
12691277
generics,
12701278
protocol,
12711279
availability: _,
12721280
} => {
1281+
let (generic_bound, where_bound) = if !generics.is_empty() {
1282+
match (&*protocol.library, &*protocol.name) {
1283+
// The object inherits from `NSObject` or `NSProxy` no
1284+
// matter what the generic type is, so this must be
1285+
// safe.
1286+
(_, _) if protocol.is_nsobject() => ("Message", None),
1287+
// Encoding and decoding requires that the inner types
1288+
// are codable as well.
1289+
("Foundation", "NSCoding") => ("Message + NSCoding", None),
1290+
("Foundation", "NSSecureCoding") => ("Message + NSSecureCoding", None),
1291+
// Copying generic structs is done as a shallow copy.
1292+
//
1293+
// E.g. it simply does a retain count bump, and hence
1294+
// does not require the inner type to implement
1295+
// `NSCopying`.
1296+
("Foundation", "NSCopying") => ("Message", Some("::Kind: CloneableKind")),
1297+
("Foundation", "NSMutableCopying") => ("Message", Some("::Kind: CloneableKind")),
1298+
// TODO: Do we need further tweaks to this?
1299+
("Foundation", "NSFastEnumeration") => ("Message", None),
1300+
// AppKit fixes
1301+
("AppKit", "NSCollectionViewDataSource") => ("Message", None),
1302+
("AppKit", "NSTableViewDataSource") => ("Message", None),
1303+
_ => {
1304+
error!(?protocol, ?cls, "unknown where bound for generic protocol impl");
1305+
("Message", None)
1306+
}
1307+
}
1308+
} else {
1309+
("Message", None)
1310+
};
1311+
12731312
if let Some(feature) = cls.feature() {
12741313
writeln!(f, "#[cfg(feature = \"{feature}\")]")?;
12751314
}
12761315
writeln!(
12771316
f,
1278-
"unsafe impl{} {} for {}{} {{}}",
1279-
GenericParamsHelper(generics),
1317+
"unsafe impl{} {} for {}{} {}{{}}",
1318+
GenericParamsHelper(generics, generic_bound),
12801319
protocol.path_in_relation_to(cls),
12811320
cls.path(),
12821321
GenericTyHelper(generics),
1322+
WhereBoundHelper(generics, where_bound)
12831323
)?;
12841324
}
12851325
Self::ProtocolDecl {

crates/icrate/src/Foundation/fixes/copy.rs

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,6 @@ use objc2::kind::RetainableKind;
55
use crate::common::*;
66
use crate::Foundation::{self, NSCopying, NSMutableCopying};
77

8-
// Copying collections is done as a shallow copy.
9-
//
10-
// As such, it is only possible when the array's contents are retainable.
11-
//
12-
// TODO: Depending on what we allow on collections, we might be able to relax
13-
// this to `CloneableKind` (and allowing `NSString`).
14-
15-
// Arrays
16-
17-
#[cfg(feature = "Foundation_NSArray")]
18-
unsafe impl<T: Message> NSCopying for Foundation::NSArray<T> where T::Kind: RetainableKind {}
19-
20-
/// This is implemented as a shallow copy.
21-
#[cfg(feature = "Foundation_NSArray")]
22-
#[cfg(feature = "Foundation_NSMutableArray")]
23-
unsafe impl<T: Message> NSMutableCopying for Foundation::NSArray<T> where T::Kind: RetainableKind {}
24-
258
#[cfg(feature = "Foundation_NSArray")]
269
impl<T: Message> ToOwned for Foundation::NSArray<T>
2710
where
@@ -33,17 +16,6 @@ where
3316
}
3417
}
3518

36-
/// This is implemented as a shallow copy.
37-
#[cfg(feature = "Foundation_NSMutableArray")]
38-
unsafe impl<T: Message> NSCopying for Foundation::NSMutableArray<T> where T::Kind: RetainableKind {}
39-
40-
/// This is implemented as a shallow copy.
41-
#[cfg(feature = "Foundation_NSMutableArray")]
42-
unsafe impl<T: Message> NSMutableCopying for Foundation::NSMutableArray<T> where
43-
T::Kind: RetainableKind
44-
{
45-
}
46-
4719
#[cfg(feature = "Foundation_NSMutableArray")]
4820
impl<T: Message> ToOwned for Foundation::NSMutableArray<T>
4921
where
@@ -55,15 +27,6 @@ where
5527
}
5628
}
5729

58-
// Data
59-
60-
#[cfg(feature = "Foundation_NSData")]
61-
unsafe impl NSCopying for Foundation::NSData {}
62-
63-
#[cfg(feature = "Foundation_NSData")]
64-
#[cfg(feature = "Foundation_NSMutableData")]
65-
unsafe impl NSMutableCopying for Foundation::NSData {}
66-
6730
#[cfg(feature = "Foundation_NSData")]
6831
impl ToOwned for Foundation::NSData {
6932
type Owned = Id<Self>;
@@ -72,12 +35,6 @@ impl ToOwned for Foundation::NSData {
7235
}
7336
}
7437

75-
#[cfg(feature = "Foundation_NSMutableData")]
76-
unsafe impl NSCopying for Foundation::NSMutableData {}
77-
78-
#[cfg(feature = "Foundation_NSMutableData")]
79-
unsafe impl NSMutableCopying for Foundation::NSMutableData {}
80-
8138
#[cfg(feature = "Foundation_NSMutableData")]
8239
impl ToOwned for Foundation::NSMutableData {
8340
type Owned = Id<Self>;
@@ -86,14 +43,6 @@ impl ToOwned for Foundation::NSMutableData {
8643
}
8744
}
8845

89-
// Errors
90-
91-
#[cfg(feature = "Foundation_NSError")]
92-
unsafe impl NSCopying for Foundation::NSError {}
93-
94-
#[cfg(feature = "Foundation_NSException")]
95-
unsafe impl NSCopying for Foundation::NSException {}
96-
9746
#[cfg(feature = "Foundation_NSException")]
9847
impl ToOwned for Foundation::NSException {
9948
type Owned = Id<Self>;
@@ -102,15 +51,6 @@ impl ToOwned for Foundation::NSException {
10251
}
10352
}
10453

105-
// Sets
106-
107-
#[cfg(feature = "Foundation_NSSet")]
108-
unsafe impl<T: Message> NSCopying for Foundation::NSSet<T> where T::Kind: RetainableKind {}
109-
110-
#[cfg(feature = "Foundation_NSSet")]
111-
#[cfg(feature = "Foundation_NSMutableSet")]
112-
unsafe impl<T: Message> NSMutableCopying for Foundation::NSSet<T> where T::Kind: RetainableKind {}
113-
11454
#[cfg(feature = "Foundation_NSSet")]
11555
impl<T: Message> ToOwned for Foundation::NSSet<T>
11656
where
@@ -122,15 +62,6 @@ where
12262
}
12363
}
12464

125-
#[cfg(feature = "Foundation_NSMutableSet")]
126-
unsafe impl<T: Message> NSCopying for Foundation::NSMutableSet<T> where T::Kind: RetainableKind {}
127-
128-
#[cfg(feature = "Foundation_NSMutableSet")]
129-
unsafe impl<T: Message> NSMutableCopying for Foundation::NSMutableSet<T> where
130-
T::Kind: RetainableKind
131-
{
132-
}
133-
13465
#[cfg(feature = "Foundation_NSMutableSet")]
13566
impl<T: Message> ToOwned for Foundation::NSMutableSet<T>
13667
where
@@ -142,15 +73,6 @@ where
14273
}
14374
}
14475

145-
// Strings
146-
147-
#[cfg(feature = "Foundation_NSString")]
148-
unsafe impl NSCopying for Foundation::NSString {}
149-
150-
#[cfg(feature = "Foundation_NSString")]
151-
#[cfg(feature = "Foundation_NSMutableString")]
152-
unsafe impl NSMutableCopying for Foundation::NSString {}
153-
15476
#[cfg(feature = "Foundation_NSString")]
15577
impl ToOwned for Foundation::NSString {
15678
type Owned = Id<Self>;
@@ -159,12 +81,6 @@ impl ToOwned for Foundation::NSString {
15981
}
16082
}
16183

162-
#[cfg(feature = "Foundation_NSMutableString")]
163-
unsafe impl NSCopying for Foundation::NSMutableString {}
164-
165-
#[cfg(feature = "Foundation_NSMutableString")]
166-
unsafe impl NSMutableCopying for Foundation::NSMutableString {}
167-
16884
#[cfg(feature = "Foundation_NSMutableString")]
16985
impl ToOwned for Foundation::NSMutableString {
17086
type Owned = Id<Self>;
@@ -173,13 +89,6 @@ impl ToOwned for Foundation::NSMutableString {
17389
}
17490
}
17591

176-
#[cfg(feature = "Foundation_NSAttributedString")]
177-
unsafe impl NSCopying for Foundation::NSAttributedString {}
178-
179-
#[cfg(feature = "Foundation_NSAttributedString")]
180-
#[cfg(feature = "Foundation_NSMutableAttributedString")]
181-
unsafe impl NSMutableCopying for Foundation::NSAttributedString {}
182-
18392
#[cfg(feature = "Foundation_NSAttributedString")]
18493
impl ToOwned for Foundation::NSAttributedString {
18594
type Owned = Id<Self>;
@@ -188,12 +97,6 @@ impl ToOwned for Foundation::NSAttributedString {
18897
}
18998
}
19099

191-
#[cfg(feature = "Foundation_NSMutableAttributedString")]
192-
unsafe impl NSCopying for Foundation::NSMutableAttributedString {}
193-
194-
#[cfg(feature = "Foundation_NSMutableAttributedString")]
195-
unsafe impl NSMutableCopying for Foundation::NSMutableAttributedString {}
196-
197100
#[cfg(feature = "Foundation_NSMutableAttributedString")]
198101
impl ToOwned for Foundation::NSMutableAttributedString {
199102
type Owned = Id<Self>;
@@ -202,11 +105,6 @@ impl ToOwned for Foundation::NSMutableAttributedString {
202105
}
203106
}
204107

205-
// UUID
206-
207-
#[cfg(feature = "Foundation_NSUUID")]
208-
unsafe impl NSCopying for Foundation::NSUUID {}
209-
210108
#[cfg(feature = "Foundation_NSUUID")]
211109
impl ToOwned for Foundation::NSUUID {
212110
type Owned = Id<Self>;
@@ -215,11 +113,6 @@ impl ToOwned for Foundation::NSUUID {
215113
}
216114
}
217115

218-
// Value
219-
220-
#[cfg(feature = "Foundation_NSValue")]
221-
unsafe impl NSCopying for Foundation::NSValue {}
222-
223116
#[cfg(feature = "Foundation_NSValue")]
224117
impl ToOwned for Foundation::NSValue {
225118
type Owned = Id<Self>;
@@ -228,9 +121,6 @@ impl ToOwned for Foundation::NSValue {
228121
}
229122
}
230123

231-
#[cfg(feature = "Foundation_NSNumber")]
232-
unsafe impl NSCopying for Foundation::NSNumber {}
233-
234124
#[cfg(feature = "Foundation_NSNumber")]
235125
impl ToOwned for Foundation::NSNumber {
236126
type Owned = Id<Self>;

crates/icrate/src/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ pub(crate) use std::os::raw::{
1616
pub(crate) use objc2::ffi::{NSInteger, NSIntegerMax, NSUInteger, NSUIntegerMax, IMP};
1717
#[cfg(feature = "objective-c")]
1818
pub(crate) use objc2::kind::{
19-
ImmutableWithMutableSubclass, InteriorMutable, Mutable, MutableWithImmutableSuperclass,
19+
CloneableKind, ImmutableWithMutableSubclass, InteriorMutable, Mutable,
20+
MutableWithImmutableSuperclass,
2021
};
2122
#[cfg(feature = "objective-c")]
2223
pub(crate) use objc2::rc::{Allocated, Id};

crates/icrate/src/generated

0 commit comments

Comments
 (0)