Skip to content

Commit 11a1d50

Browse files
committed
Enable generation of init and new methods
1 parent 46603d5 commit 11a1d50

25 files changed

+588
-608
lines changed

crates/header-translator/src/data/Foundation.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ data! {
33
// and returning mutable references to those would be unsound - hence
44
// `NSArray` cannot be mutable.
55
class NSArray: ImmutableWithMutableSubclass<Foundation::NSMutableArray> {
6+
unsafe -init;
67
unsafe -count;
78
}
89

910
class NSMutableArray: MutableWithImmutableSuperclass<Foundation::NSArray> {
11+
unsafe -init;
1012
unsafe -removeAllObjects;
1113
}
1214

@@ -28,6 +30,7 @@ data! {
2830
}
2931

3032
class NSMutableString: MutableWithImmutableSuperclass<Foundation::NSString> {
33+
unsafe -init;
3134
unsafe -initWithCapacity;
3235
unsafe +stringWithCapacity;
3336
unsafe -initWithString;
@@ -43,13 +46,15 @@ data! {
4346
class NSConstantString: Immutable {}
4447

4548
class NSAttributedString: ImmutableWithMutableSubclass<Foundation::NSMutableAttributedString> {
49+
unsafe -init;
4650
unsafe -initWithString;
4751
unsafe -initWithAttributedString;
4852
unsafe -string;
4953
unsafe -length;
5054
}
5155

5256
class NSMutableAttributedString: MutableWithImmutableSuperclass<Foundation::NSAttributedString> {
57+
unsafe -init;
5358
unsafe -initWithString;
5459
unsafe -initWithAttributedString;
5560
unsafe -setAttributedString;
@@ -61,13 +66,15 @@ data! {
6166
}
6267

6368
class NSData: ImmutableWithMutableSubclass<Foundation::NSMutableData> {
69+
unsafe -init;
6470
unsafe -initWithData;
6571
unsafe +dataWithData;
6672
unsafe -length;
6773
unsafe -bytes;
6874
}
6975

7076
class NSMutableData: MutableWithImmutableSuperclass<Foundation::NSData> {
77+
unsafe -init;
7178
unsafe +dataWithData;
7279
unsafe -initWithCapacity;
7380
unsafe +dataWithCapacity;
@@ -81,10 +88,12 @@ data! {
8188
class NSPurgeableData: Mutable {}
8289

8390
class NSDictionary: ImmutableWithMutableSubclass<Foundation::NSMutableDictionary> {
91+
unsafe -init;
8492
unsafe -count;
8593
}
8694

8795
class NSMutableDictionary: MutableWithImmutableSuperclass<Foundation::NSDictionary> {
96+
unsafe -init;
8897
unsafe -removeObjectForKey;
8998
unsafe -removeAllObjects;
9099
}
@@ -103,6 +112,7 @@ data! {
103112
}
104113

105114
class NSLock {
115+
unsafe -init;
106116
unsafe -name;
107117
unsafe -setName;
108118
}
@@ -120,6 +130,7 @@ data! {
120130
}
121131

122132
class NSThread {
133+
unsafe -init;
123134
unsafe +currentThread;
124135
unsafe +mainThread;
125136
unsafe -name;
@@ -135,10 +146,12 @@ data! {
135146
}
136147

137148
class NSSet: ImmutableWithMutableSubclass<Foundation::NSMutableSet> {
149+
unsafe -init;
138150
unsafe -count;
139151
}
140152

141153
class NSMutableSet: MutableWithImmutableSuperclass<Foundation::NSSet> {
154+
unsafe -init;
142155
unsafe -removeAllObjects;
143156
}
144157

crates/header-translator/src/data/macros.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,41 @@ macro_rules! __data_methods {
152152
(
153153
@($data:expr)
154154
) => {};
155+
// Mark init (and by extension, `new`) method as safe
156+
(
157+
@($data:expr)
158+
159+
unsafe -init;
160+
161+
$($rest:tt)*
162+
) => {
163+
let mut method_data = $data.methods.entry("init".to_string()).or_default();
164+
method_data.unsafe_ = false;
165+
166+
let mut method_data = $data.methods.entry("new".to_string()).or_default();
167+
method_data.unsafe_ = false;
168+
169+
__data_methods! {
170+
@($data)
171+
$($rest)*
172+
}
173+
};
174+
// Mark new (and by extension, `init`) method as safe
175+
(
176+
@($data:expr)
177+
178+
unsafe +new;
179+
180+
$($rest:tt)*
181+
) => {
182+
__data_methods! {
183+
@($data)
184+
185+
unsafe -init;
186+
187+
$($rest)*
188+
}
189+
};
155190
// Mark method as safe
156191
(
157192
@($data:expr)

crates/header-translator/src/method.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,9 @@ impl Method {
580580
return false;
581581
}
582582
if self.is_class {
583-
!matches!(&*self.selector, "new" | "supportsSecureCoding")
583+
true
584584
} else {
585585
self.memory_management == MemoryManagement::IdInit
586-
&& !matches!(&*self.selector, "init" | "initWithCoder:")
587586
}
588587
}
589588
}

crates/header-translator/translation-config.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,24 @@ derives = "Debug, PartialEq, Hash"
13191319
skipped = true
13201320
[class.NSValue.methods.new]
13211321
skipped = true
1322+
[class.NSNumber.methods.init]
1323+
skipped = true
1324+
[class.NSNumber.methods.new]
1325+
skipped = true
1326+
1327+
# Marked as API_UNAVAILABLE in a category, so we hit the duplicate checking
1328+
[class.NSLocale.methods.init]
1329+
skipped = true
1330+
[class.NSLocale.methods.new]
1331+
skipped = true
1332+
[class.NSNotification.methods.init]
1333+
skipped = true
1334+
[class.NSNotification.methods.new]
1335+
skipped = true
1336+
[class.GKLeaderboard.methods.init]
1337+
skipped = true
1338+
[class.GKLeaderboard.methods.new]
1339+
skipped = true
13221340

13231341
# Manual definitions
13241342
[class.NSException.methods.raise]
@@ -1327,6 +1345,10 @@ skipped = true
13271345
skipped = true
13281346
[class.NSMutableData.methods.length]
13291347
skipped = true
1348+
[class.NSError.methods.new]
1349+
skipped = true
1350+
[class.NSException.methods.new]
1351+
skipped = true
13301352

13311353
# Wrong type on GNUStep
13321354
[class.NSMutableData.methods.mutableBytes]

crates/icrate/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
3030
- `NSDictionary::values_retained`
3131
* Added `MainThreadMarker::alloc` for allocating objects that need to be so on
3232
the main thread.
33+
* Added automatically generated `new`/`init` methods for all types.
3334

3435
### Changed
3536
* **BREAKING**: Renamed the `from_slice` method on `NSArray`, `NSSet`,

crates/icrate/src/Foundation/additions/array.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ use crate::Foundation::{self, NSArray};
1616
extern_methods!(
1717
/// Creation methods.
1818
unsafe impl<T: Message> NSArray<T> {
19-
/// Get an empty array.
20-
#[method_id(new)]
21-
pub fn new() -> Id<Self>;
22-
2319
pub fn from_vec(mut vec: Vec<Id<T>>) -> Id<Self> {
2420
// We intentionally extract the length before we access the
2521
// pointer as mutable, to not invalidate that mutable pointer.

crates/icrate/src/Foundation/additions/attributed_string.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ impl RefUnwindSafe for NSAttributedString {}
1919
extern_methods!(
2020
/// Creating attributed strings.
2121
unsafe impl NSAttributedString {
22-
/// Construct an empty attributed string.
23-
#[method_id(new)]
24-
pub fn new() -> Id<Self>;
25-
2622
/// Creates a new attributed string from the given string and attributes.
2723
///
2824
/// The attributes are associated with every UTF-16 code unit in the

crates/icrate/src/Foundation/additions/data.rs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,60 +19,52 @@ unsafe impl Send for NSData {}
1919
impl UnwindSafe for NSData {}
2020
impl RefUnwindSafe for NSData {}
2121

22-
extern_methods!(
23-
/// Creation methods.
24-
unsafe impl NSData {
25-
#[method_id(new)]
26-
pub fn new() -> Id<Self>;
27-
28-
pub fn with_bytes(bytes: &[u8]) -> Id<Self> {
29-
let bytes_ptr = bytes.as_ptr() as *mut c_void;
30-
unsafe { Self::initWithBytes_length(Self::alloc(), bytes_ptr, bytes.len()) }
31-
}
22+
/// Creation methods.
23+
impl NSData {
24+
pub fn with_bytes(bytes: &[u8]) -> Id<Self> {
25+
let bytes_ptr = bytes.as_ptr() as *mut c_void;
26+
unsafe { Self::initWithBytes_length(Self::alloc(), bytes_ptr, bytes.len()) }
27+
}
3228

33-
#[cfg(feature = "block")]
34-
pub fn from_vec(bytes: Vec<u8>) -> Id<Self> {
35-
// GNUStep's NSData `initWithBytesNoCopy:length:deallocator:` has a
36-
// bug; it forgets to assign the input buffer and length to the
37-
// instance before it swizzles to NSDataWithDeallocatorBlock.
38-
// See https://github.com/gnustep/libs-base/pull/213
39-
// So we just use NSDataWithDeallocatorBlock directly.
40-
//
41-
// NSMutableData does not have this problem.
42-
#[cfg(feature = "gnustep-1-7")]
43-
let cls = objc2::class!(NSDataWithDeallocatorBlock);
44-
#[cfg(not(feature = "gnustep-1-7"))]
45-
let cls = Self::class();
46-
47-
unsafe { Id::cast(with_vec(cls, bytes)) }
48-
}
29+
#[cfg(feature = "block")]
30+
pub fn from_vec(bytes: Vec<u8>) -> Id<Self> {
31+
// GNUStep's NSData `initWithBytesNoCopy:length:deallocator:` has a
32+
// bug; it forgets to assign the input buffer and length to the
33+
// instance before it swizzles to NSDataWithDeallocatorBlock.
34+
// See https://github.com/gnustep/libs-base/pull/213
35+
// So we just use NSDataWithDeallocatorBlock directly.
36+
//
37+
// NSMutableData does not have this problem.
38+
#[cfg(feature = "gnustep-1-7")]
39+
let cls = objc2::class!(NSDataWithDeallocatorBlock);
40+
#[cfg(not(feature = "gnustep-1-7"))]
41+
let cls = Self::class();
42+
43+
unsafe { Id::cast(with_vec(cls, bytes)) }
4944
}
45+
}
5046

51-
/// Accessor methods.
52-
unsafe impl NSData {
53-
pub fn len(&self) -> usize {
54-
self.length()
55-
}
47+
/// Accessor methods.
48+
impl NSData {
49+
pub fn len(&self) -> usize {
50+
self.length()
51+
}
5652

57-
pub fn is_empty(&self) -> bool {
58-
self.len() == 0
59-
}
53+
pub fn is_empty(&self) -> bool {
54+
self.len() == 0
55+
}
6056

61-
#[method(bytes)]
62-
fn bytes_raw(&self) -> *const c_void;
63-
64-
pub fn bytes(&self) -> &[u8] {
65-
let ptr = self.bytes_raw();
66-
let ptr: *const u8 = ptr.cast();
67-
// The bytes pointer may be null for length zero
68-
if ptr.is_null() {
69-
&[]
70-
} else {
71-
unsafe { slice::from_raw_parts(ptr, self.len()) }
72-
}
57+
pub fn bytes(&self) -> &[u8] {
58+
let ptr = self.bytes_raw();
59+
let ptr: *const u8 = ptr.cast();
60+
// The bytes pointer may be null for length zero
61+
if ptr.is_null() {
62+
&[]
63+
} else {
64+
unsafe { slice::from_raw_parts(ptr, self.len()) }
7365
}
7466
}
75-
);
67+
}
7668

7769
impl AsRef<[u8]> for NSData {
7870
fn as_ref(&self) -> &[u8] {

crates/icrate/src/Foundation/additions/dictionary.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ use crate::Foundation::{self, Copyhelper, NSDictionary};
1818

1919
extern_methods!(
2020
unsafe impl<K: Message, V: Message> NSDictionary<K, V> {
21-
#[method_id(new)]
22-
pub fn new() -> Id<Self>;
23-
2421
pub fn from_keys_and_objects<T>(keys: &[&T], mut vals: Vec<Id<V>>) -> Id<Self>
2522
where
2623
T: ClassType + Foundation::NSCopying,

0 commit comments

Comments
 (0)