diff options
Diffstat (limited to 'ir/objc.rs')
-rw-r--r-- | ir/objc.rs | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -253,19 +253,38 @@ impl ObjCMethod { let split_name: Vec<Option<Ident>> = self .name .split(':') - .map(|name| { + .enumerate() + .map(|(idx, name)| { if name.is_empty() { None + } else if idx == 0 { + // Try to parse the method name as an identifier. Having a keyword is ok + // unless it is `crate`, `self`, `super` or `Self`, so we try to add the `_` + // suffix to it and parse it. + if ["crate", "self", "super", "Self"].contains(&name) { + Some(Ident::new( + &format!("{}_", name), + Span::call_site(), + )) + } else { + Some(Ident::new(name, Span::call_site())) + } } else { - // Try to parse the current name as an identifier. This might fail if the - // name is a keyword so we try to prepend "r#" to it and parse again. If - // this also fails, we panic with the first error. + // Try to parse the current joining name as an identifier. This might fail if the name + // is a keyword, so we try to "r#" to it and parse again, this could also fail + // if the name is `crate`, `self`, `super` or `Self`, so we try to add the `_` + // suffix to it and parse again. If this also fails, we panic with the first + // error. Some( syn::parse_str::<Ident>(name) .or_else(|err| { syn::parse_str::<Ident>(&format!("r#{}", name)) .map_err(|_| err) }) + .or_else(|err| { + syn::parse_str::<Ident>(&format!("{}_", name)) + .map_err(|_| err) + }) .expect("Invalid identifier"), ) } |