Skip to content

Commit

Permalink
Parse NS_NOESCAPE
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Sep 1, 2023
1 parent 5fa7a76 commit 2af7c9d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 8 deletions.
4 changes: 4 additions & 0 deletions crates/header-translator/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ impl ItemIdentifier {
self.library == "Foundation" && self.name == "NSString"
}

pub fn is_nscomparator(&self) -> bool {
self.library == "Foundation" && self.name == "NSComparator"
}

pub fn feature(&self) -> Option<impl fmt::Display + '_> {
struct ItemIdentifierFeature<'a>(&'a ItemIdentifier);

Expand Down
4 changes: 3 additions & 1 deletion crates/header-translator/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ impl<'tu> PartialMethod<'tu> {
.get_objc_qualifiers()
.map(MethodArgumentQualifier::parse);
let mut sendable = None;
let mut no_escape = false;

immediate_children(&entity, |entity, _span| match entity.get_kind() {
EntityKind::ObjCClassRef
Expand All @@ -417,6 +418,7 @@ impl<'tu> PartialMethod<'tu> {
match attr {
UnexposedAttr::Sendable => sendable = Some(true),
UnexposedAttr::NonSendable => sendable = Some(false),
UnexposedAttr::NoEscape => no_escape = true,
attr => error!(?attr, "unknown attribute"),
}
}
Expand All @@ -427,7 +429,7 @@ impl<'tu> PartialMethod<'tu> {
});

let ty = entity.get_type().expect("argument type");
let ty = Ty::parse_method_argument(ty, qualifier, sendable, context);
let ty = Ty::parse_method_argument(ty, qualifier, sendable, no_escape, context);

(name, ty)
})
Expand Down
57 changes: 52 additions & 5 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,13 @@ enum Inner {
},
Fn {
is_variadic: bool,
no_escape: bool,
arguments: Vec<Inner>,
result_type: Box<Inner>,
},
Block {
sendable: Option<bool>,
no_escape: bool,
arguments: Vec<Inner>,
result_type: Box<Inner>,
},
Expand Down Expand Up @@ -546,7 +549,7 @@ impl Inner {

match attr {
Some(UnexposedAttr::NonIsolated | UnexposedAttr::UIActor) => {
// Ignored for now; these are almost always also emitted on the method/property,
// Ignored for now; these are usually also emitted on the method/property,
// which is where they will be useful in any case.
}
Some(attr) => error!(?attr, "unknown attribute"),
Expand Down Expand Up @@ -681,12 +684,15 @@ impl Inner {
match Self::parse(ty, Lifetime::Unspecified, context) {
Self::Fn {
is_variadic: false,
no_escape,
arguments,
result_type,
} => Self::Pointer {
nullability,
is_const,
pointee: Box::new(Self::Block {
sendable: None,
no_escape,
arguments,
result_type,
}),
Expand Down Expand Up @@ -924,6 +930,7 @@ impl Inner {

Self::Fn {
is_variadic: ty.is_variadic(),
no_escape: false,
arguments,
result_type: Box::new(result_type),
}
Expand Down Expand Up @@ -1008,11 +1015,14 @@ impl Inner {
//
// }
Self::Fn {
is_variadic: _,
no_escape: _,
arguments,
result_type,
..
}
| Self::Block {
sendable: _,
no_escape: _,
arguments,
result_type,
} => {
Expand Down Expand Up @@ -1106,6 +1116,7 @@ impl fmt::Display for Inner {
} => match &**pointee {
Self::Fn {
is_variadic,
no_escape: _,
arguments,
result_type,
} => {
Expand Down Expand Up @@ -1161,6 +1172,8 @@ impl fmt::Display for Inner {
Enum { id } | Struct { id } | TypeDef { id } => write!(f, "{}", id.path()),
Self::Fn { .. } => write!(f, "TodoFunction"),
Self::Block {
sendable: _,
no_escape: _,
arguments,
result_type,
} => {
Expand Down Expand Up @@ -1213,10 +1226,44 @@ impl Ty {
pub fn parse_method_argument(
ty: Type<'_>,
_qualifier: Option<MethodArgumentQualifier>,
_sendable: Option<bool>,
mut arg_sendable: Option<bool>,
mut arg_no_escape: bool,
context: &Context<'_>,
) -> Self {
let ty = Inner::parse(ty, Lifetime::Unspecified, context);
let mut ty = Inner::parse(ty, Lifetime::Unspecified, context);

match &mut ty {
Inner::Pointer { pointee, .. } => match &mut **pointee {
Inner::Block {
sendable,
no_escape,
..
} => {
*sendable = arg_sendable;
*no_escape = arg_no_escape;
arg_sendable = None;
arg_no_escape = false;
}
Inner::Fn { no_escape, .. } => {
*no_escape = arg_no_escape;
arg_no_escape = false;
}
_ => {}
},
// Ignore NSComparator for now
Inner::TypeDef { id } if id.is_nscomparator() => {
arg_no_escape = false;
}
_ => {}
}

if arg_sendable.is_some() {
warn!(?ty, "did not consume sendable in argument");
}

if arg_no_escape {
warn!(?ty, "did not consume no_escape in argument");
}

match &ty {
Inner::Pointer { pointee, .. } => pointee.visit_lifetime(|lifetime| {
Expand Down Expand Up @@ -1274,7 +1321,7 @@ impl Ty {
}

pub fn parse_function_argument(ty: Type<'_>, context: &Context<'_>) -> Self {
let mut this = Self::parse_method_argument(ty, None, None, context);
let mut this = Self::parse_method_argument(ty, None, None, false, context);
this.kind = TyKind::FnArgument;
this
}
Expand Down
5 changes: 3 additions & 2 deletions crates/header-translator/src/unexposed_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub enum UnexposedAttr {
NonSendable,
UIActor,
NonIsolated,

NoEscape,
}

impl UnexposedAttr {
Expand Down Expand Up @@ -77,8 +79,7 @@ impl UnexposedAttr {
let _ = get_arguments();
None
}
// TODO
"NS_NOESCAPE" => None,
"NS_NOESCAPE" => Some(Self::NoEscape),
// TODO: We could potentially automatically elide this argument
// from the method call, though it's rare enough that it's
// probably not really worth the effort.
Expand Down

0 comments on commit 2af7c9d

Please sign in to comment.