Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better protocols #293

Merged
merged 27 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
da31918
Change how protocols work
madsmtm Jan 26, 2023
cf2e9a8
Generically implement `P` when something implements `ConformsTo<dyn P>`
madsmtm Nov 23, 2022
f8b0882
Reflectively implement `ConformsTo<P>` for `ProtocolObject<P>`
madsmtm Nov 23, 2022
5474cf6
Allow class methods in protocols
madsmtm Jan 26, 2023
5be63ec
Remove ConformsTo and redo how protocols are implemented
madsmtm Jan 26, 2023
4fbad3f
Add NSObjectProtocol
madsmtm Jan 26, 2023
a8edbee
Implement common traits for ProtocolObject
madsmtm Jan 26, 2023
7c53e48
Change protocol header generation
madsmtm Jan 26, 2023
af6f38d
Add protocol class methods
madsmtm Jan 26, 2023
87cba77
Output protocol implementations
madsmtm Jan 26, 2023
7f5ca18
Remove NSDictionary's NSGenericFastEnumeration
madsmtm Jan 26, 2023
1d4c24d
Add missing protocol implementations
madsmtm Jan 26, 2023
a089e05
Fix calling methods on ProtocolObject
madsmtm Jan 26, 2023
22605a1
Update UI tests
madsmtm Jan 26, 2023
06a1fda
Fix NSLocking test
madsmtm Jan 26, 2023
682d1d4
Fix duplicate class and protocol names
madsmtm Jan 26, 2023
03114fd
Temporarily fix protocols inheriting NSCopying
madsmtm Jan 26, 2023
1d99279
Remove a few protocol implementations that we aren't ready for yet
madsmtm Jan 26, 2023
326d8c9
Fix NSFileProviderItem
madsmtm Jan 26, 2023
46b950c
Fix MKMapItem
madsmtm Jan 26, 2023
0677c61
Appease clippy
madsmtm Jan 26, 2023
8950846
Update protocol documentation
madsmtm Jan 27, 2023
882cdaa
Fix test_object.rs's NSObjectProtocol
madsmtm Jan 27, 2023
cf15592
Add protocol assembly tests
madsmtm Jan 27, 2023
a61b49a
Update iai dev-dependency
madsmtm Jan 27, 2023
6b9179e
Disable benchmark tests under callgrind
madsmtm Jan 27, 2023
46454f2
Support cfg attributes in extern_protocol!
madsmtm Jan 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,8 @@ jobs:
git diff --exit-code

- name: Run benchmarks
# Disabled since it started failing for some reason
if: ${{ false }}
# Difficult to install Valgrind on macOS
# See https://github.com/LouisBrunner/valgrind-macos
run: cargo bench $ARGS
Expand Down
21 changes: 14 additions & 7 deletions Cargo.lock

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

34 changes: 32 additions & 2 deletions crates/header-translator/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::fs;
use std::io::Result;
use std::path::Path;
Expand All @@ -17,7 +17,7 @@ pub struct Config {
pub class_data: HashMap<String, ClassData>,
#[serde(rename = "protocol")]
#[serde(default)]
pub protocol_data: HashMap<String, ClassData>,
pub protocol_data: HashMap<String, ProtocolData>,
#[serde(rename = "struct")]
#[serde(default)]
pub struct_data: HashMap<String, StructData>,
Expand All @@ -39,6 +39,13 @@ pub struct Config {
}

impl Config {
pub fn replace_protocol_name(&self, name: String) -> String {
self.protocol_data
.get(&name)
.and_then(|data| data.renamed.clone())
.unwrap_or(name)
}

pub fn get_library_alias(&self, library_name: String) -> String {
self.libraries
.iter()
Expand Down Expand Up @@ -72,10 +79,15 @@ pub struct ClassData {
#[serde(default)]
pub methods: HashMap<String, MethodData>,
#[serde(default)]
pub categories: HashMap<String, CategoryData>,
#[serde(default)]
pub derives: Derives,
#[serde(rename = "owned")]
#[serde(default)]
pub ownership: Ownership,
#[serde(rename = "skipped-protocols")]
#[serde(default)]
pub skipped_protocols: HashSet<String>,
}

impl ClassData {
Expand All @@ -85,6 +97,24 @@ impl ClassData {
}
}

#[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct CategoryData {
#[serde(default)]
pub skipped: bool,
}

#[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ProtocolData {
#[serde(default)]
pub renamed: Option<String>,
#[serde(default)]
pub skipped: bool,
#[serde(default)]
pub methods: HashMap<String, MethodData>,
}

#[derive(Deserialize, Debug, Default, Clone, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct StructData {
Expand Down
8 changes: 4 additions & 4 deletions crates/header-translator/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<N: ToOptionString> ItemIdentifier<N> {
}
}

fn map_name<R: ToOptionString>(self, f: impl FnOnce(N) -> R) -> ItemIdentifier<R> {
pub fn map_name<R: ToOptionString>(self, f: impl FnOnce(N) -> R) -> ItemIdentifier<R> {
let Self {
name,
library,
Expand Down Expand Up @@ -91,9 +91,9 @@ impl ItemIdentifier {
self.library == "System"
}

// pub fn is_nsobject(&self) -> bool {
// self.library == "System" && self.name == "NSObject"
// }
pub fn is_nsobject(&self) -> bool {
self.library == "System" && (self.name == "NSObject" || self.name == "NSObjectProtocol")
}

pub fn is_nserror(&self) -> bool {
self.library == "Foundation" && self.name == "NSError"
Expand Down
18 changes: 16 additions & 2 deletions crates/header-translator/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ pub struct Method {
pub result_type: Ty,
safe: bool,
mutating: bool,
is_protocol: bool,
}

impl Method {
Expand Down Expand Up @@ -319,7 +320,12 @@ pub struct PartialMethod<'tu> {
}

impl<'tu> PartialMethod<'tu> {
pub fn parse(self, data: MethodData, context: &Context<'_>) -> Option<(bool, Method)> {
pub fn parse(
self,
data: MethodData,
is_protocol: bool,
context: &Context<'_>,
) -> Option<(bool, Method)> {
let Self {
entity,
selector,
Expand Down Expand Up @@ -432,6 +438,7 @@ impl<'tu> PartialMethod<'tu> {
result_type,
safe: !data.unsafe_,
mutating: data.mutating,
is_protocol,
},
))
}
Expand All @@ -453,6 +460,7 @@ impl PartialProperty<'_> {
self,
getter_data: MethodData,
setter_data: Option<MethodData>,
is_protocol: bool,
context: &Context<'_>,
) -> (Option<Method>, Option<Method>) {
let Self {
Expand Down Expand Up @@ -502,6 +510,7 @@ impl PartialProperty<'_> {
result_type: ty,
safe: !getter_data.unsafe_,
mutating: getter_data.mutating,
is_protocol,
})
} else {
None
Expand All @@ -528,6 +537,7 @@ impl PartialProperty<'_> {
result_type: Ty::VOID_RESULT,
safe: !setter_data.unsafe_,
mutating: setter_data.mutating,
is_protocol,
})
} else {
None
Expand Down Expand Up @@ -587,7 +597,11 @@ impl fmt::Display for Method {
// Signature
//

write!(f, " pub ")?;
write!(f, " ")?;
if !self.is_protocol {
write!(f, "pub ")?;
}

if !self.safe {
write!(f, "unsafe ")?;
}
Expand Down
8 changes: 6 additions & 2 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,10 @@ impl IdType {
let protocols: Vec<_> = ty
.get_objc_protocol_declarations()
.into_iter()
.map(|entity| ItemIdentifier::new(&entity, context))
.map(|entity| {
ItemIdentifier::new(&entity, context)
.map_name(|name| context.replace_protocol_name(name))
})
.collect();

match ty.get_kind() {
Expand Down Expand Up @@ -408,10 +411,11 @@ impl fmt::Display for IdType {
}
Self::AnyObject { protocols } => match &**protocols {
[] => write!(f, "Object"),
[id] if id.is_nsobject() => write!(f, "NSObject"),
[id] if id.name == "NSCopying" || id.name == "NSMutableCopying" => {
write!(f, "Object")
}
[id] => write!(f, "{}", id.path()),
[id] => write!(f, "ProtocolObject<dyn {}>", id.path()),
// TODO: Handle this better
_ => write!(f, "TodoProtocols"),
},
Expand Down
Loading