Skip to content

Commit 433a932

Browse files
committed
cxx-qt-gen: syn 2 supports unsafety in ItemForeignMod
We do not need to consider verbatim code paths for parsing unsafe extern "ABI" anymore, this is supportted in syn 2. eg compare ItemForeignMod and notice Option<Unsafe> syn 1 https://docs.rs/syn/1.0.109/syn/struct.ItemForeignMod.html syn 2 https://docs.rs/syn/2.0.0/syn/struct.ItemForeignMod.html
1 parent 4bedcd2 commit 433a932

File tree

4 files changed

+10
-146
lines changed

4 files changed

+10
-146
lines changed

crates/cxx-qt-gen/src/parser/cxxqtdata.rs

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6-
use crate::syntax::foreignmod::{foreign_mod_to_foreign_item_types, verbatim_to_foreign_mod};
6+
use crate::syntax::foreignmod::foreign_mod_to_foreign_item_types;
77
use crate::syntax::{attribute::attribute_find_path, path::path_to_single_ident};
88
use crate::{
99
parser::{
10-
inherit::{InheritMethods, MaybeInheritMethods, ParsedInheritedMethod},
10+
inherit::{InheritMethods, ParsedInheritedMethod},
1111
qobject::ParsedQObject,
12-
signals::{MaybeSignalMethods, ParsedSignal, SignalMethods},
12+
signals::{ParsedSignal, SignalMethods},
1313
},
1414
syntax::expr::expr_to_string,
1515
};
@@ -111,16 +111,8 @@ impl ParsedCxxQtData {
111111
_others => {}
112112
}
113113

114-
// Extract the foreign mod (extern "ABI" { ... })
115-
let foreign_mod = match item {
116-
Item::ForeignMod(foreign_mod) => Some(foreign_mod.clone()),
117-
// Could be Verbatim TokenStream when it's an unsafe block, the remainder of the blocks are a normal ForeignMod though
118-
Item::Verbatim(tokens) => verbatim_to_foreign_mod(tokens)?,
119-
_others => None,
120-
};
121-
122114
// If there is a foreign mod then process it
123-
if let Some(foreign_mod) = &foreign_mod {
115+
if let Item::ForeignMod(foreign_mod) = &item {
124116
// Retrieve a namespace from the mod or the bridge
125117
let block_namespace =
126118
if let Some(index) = attribute_find_path(&foreign_mod.attrs, &["namespace"]) {
@@ -187,34 +179,11 @@ impl ParsedCxxQtData {
187179
self.uses.push(item);
188180
Ok(None)
189181
}
190-
Item::Verbatim(tokens) => self.try_parse_verbatim(tokens),
191182
Item::ForeignMod(foreign_mod) => self.parse_foreign_mod(foreign_mod),
192183
_ => Ok(Some(item)),
193184
}
194185
}
195186

196-
fn try_parse_verbatim(&mut self, tokens: TokenStream) -> Result<Option<Item>> {
197-
let try_parse: MaybeInheritMethods = syn::parse2(tokens.clone())?;
198-
199-
match try_parse {
200-
MaybeInheritMethods::Found(inherited) => {
201-
self.add_inherited_methods(inherited)?;
202-
Ok(None)
203-
}
204-
MaybeInheritMethods::PassThrough(_item) => {
205-
let try_parse: MaybeSignalMethods = syn::parse2(tokens)?;
206-
207-
match try_parse {
208-
MaybeSignalMethods::Found(signals) => {
209-
self.add_signal_methods(signals)?;
210-
Ok(None)
211-
}
212-
MaybeSignalMethods::PassThrough(item) => Ok(Some(item)),
213-
}
214-
}
215-
}
216-
}
217-
218187
fn parse_inherit_mod(&mut self, tokens: TokenStream) -> Result<()> {
219188
let inherited: InheritMethods = syn::parse2(tokens)?;
220189

@@ -594,7 +563,7 @@ mod tests {
594563
}
595564

596565
#[test]
597-
fn test_cxx_mappings_cxx_name_verbatim() {
566+
fn test_cxx_mappings_cxx_name_unsafe() {
598567
let mut cxx_qt_data = create_parsed_cxx_qt_data();
599568

600569
let item: Item = parse_quote! {

crates/cxx-qt-gen/src/parser/inherit.rs

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,9 @@ use quote::format_ident;
1414
use syn::{
1515
parse::{Parse, ParseStream},
1616
spanned::Spanned,
17-
Attribute, Error, ForeignItem, ForeignItemFn, Ident, Item, ItemForeignMod, LitStr, Result,
18-
Token,
17+
Attribute, Error, ForeignItem, ForeignItemFn, Ident, ItemForeignMod, LitStr, Result, Token,
1918
};
2019

21-
/// Used when parsing a syn::Item::Verbatim, that we suspect may be a `#[cxx_qt::inherit]` block,
22-
/// but we don't yet know whether this is actually the case.
23-
/// This is the case if `#[cxx_qt::inherit]` is used with `unsafe extern "C++"`.
24-
pub enum MaybeInheritMethods {
25-
/// We found a `#[cxx_qt::inherit]` block
26-
Found(InheritMethods),
27-
/// `#[cxx_qt::inherit]` block not found, pass this Item through to outside code!
28-
PassThrough(Item),
29-
}
30-
31-
impl Parse for MaybeInheritMethods {
32-
fn parse(input: ParseStream) -> Result<Self> {
33-
let lookahead = input.fork();
34-
if let Ok(attribute) = lookahead.call(Attribute::parse_outer) {
35-
if attribute_find_path(attribute.as_slice(), &["cxx_qt", "inherit"]).is_some() {
36-
input.call(Attribute::parse_outer)?;
37-
let methods = input.parse::<InheritMethods>()?;
38-
return Ok(Self::Found(methods));
39-
}
40-
}
41-
42-
Ok(Self::PassThrough(input.parse()?))
43-
}
44-
}
45-
4620
/// This type is used when parsing the `#[cxx_qt::inherit]` macro contents into raw ForeignItemFn items
4721
pub struct InheritMethods {
4822
pub safety: Safety,
@@ -185,22 +159,14 @@ mod tests {
185159
#[test]
186160
fn test_parse_safe_mod() {
187161
let module = quote! {
188-
#[cxx_qt::inherit]
189162
unsafe extern "C++" {
190163
fn test(self: &qobject::T);
191164
unsafe fn test2(self: &qobject::T);
192165
}
193166
};
194-
let parsed: MaybeInheritMethods = syn::parse2(module).unwrap();
195-
match parsed {
196-
MaybeInheritMethods::Found(inherit) => {
197-
assert_eq!(inherit.base_functions.len(), 2);
198-
assert_eq!(inherit.safety, Safety::Safe);
199-
}
200-
MaybeInheritMethods::PassThrough(item) => {
201-
panic!("Expected InheritMethods, got {item:?}");
202-
}
203-
}
167+
let parsed: InheritMethods = syn::parse2(module).unwrap();
168+
assert_eq!(parsed.base_functions.len(), 2);
169+
assert_eq!(parsed.safety, Safety::Safe);
204170
}
205171

206172
#[test]

crates/cxx-qt-gen/src/parser/signals.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,9 @@ use syn::Attribute;
1414
use syn::{
1515
parse::{Parse, ParseStream},
1616
spanned::Spanned,
17-
Error, ForeignItem, ForeignItemFn, Ident, Item, ItemForeignMod, LitStr, Result, Token,
17+
Error, ForeignItem, ForeignItemFn, Ident, ItemForeignMod, LitStr, Result, Token,
1818
};
1919

20-
/// Used when parsing a syn::Item::Verbatim, that we suspect may be a `#[cxx_qt::qsignals]` block,
21-
/// but we don't yet know whether this is actually the case.
22-
/// This is the case if `#[cxx_qt::qsignals]` is used with `unsafe extern "C++"`.
23-
pub enum MaybeSignalMethods {
24-
/// We found a `#[cxx_qt::qsignals]` block
25-
Found(SignalMethods),
26-
/// `#[cxx_qt::qsignals]` block not found, pass this Item through to outside code!
27-
PassThrough(Item),
28-
}
29-
30-
impl Parse for MaybeSignalMethods {
31-
fn parse(input: ParseStream) -> Result<Self> {
32-
let lookahead = input.fork();
33-
if let Ok(attribute) = lookahead.call(Attribute::parse_outer) {
34-
if attribute_find_path(attribute.as_slice(), &["cxx_qt", "qsignals"]).is_some() {
35-
input.call(Attribute::parse_outer)?;
36-
let methods = input.parse::<SignalMethods>()?;
37-
return Ok(Self::Found(methods));
38-
}
39-
}
40-
41-
Ok(Self::PassThrough(input.parse()?))
42-
}
43-
}
44-
4520
/// This type is used when parsing the `#[cxx_qt::qsignals]` macro contents into raw ForeignItemFn items
4621
pub struct SignalMethods {
4722
pub safety: Safety,

crates/cxx-qt-gen/src/syntax/foreignmod.rs

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,6 @@ pub(crate) fn foreign_mod_to_foreign_item_types(
4242
.collect::<Result<Vec<ForeignItemType>>>()
4343
}
4444

45-
/// For a given verbatim [proc_macro2::TokenStream] return a [syn::ItemForegnMod] if there is one
46-
///
47-
/// And ignore any unsafe token before the extern block
48-
pub(crate) fn verbatim_to_foreign_mod(tokens: &TokenStream) -> Result<Option<ItemForeignMod>> {
49-
|input: ParseStream| -> Result<Option<ItemForeignMod>> {
50-
// Parse any namespace attributes on the outside of the unsafe extern block
51-
let mut attrs = input.call(Attribute::parse_outer)?;
52-
53-
// If we are an unsafe then extern block try to parse it
54-
if input.peek(Token![unsafe]) && input.peek2(Token![extern]) {
55-
input.parse::<Token![unsafe]>()?;
56-
let mut foreign_mod = input.parse::<ItemForeignMod>()?;
57-
// Inject the attributes from the outside of the unsafe block into the foreign mod
58-
attrs.append(&mut foreign_mod.attrs);
59-
foreign_mod.attrs = attrs;
60-
Ok(Some(foreign_mod))
61-
} else {
62-
// Move the cursor past all remaining tokens, otherwise parse2 fails
63-
input.step(|cursor| {
64-
let mut rest = *cursor;
65-
while let Some((_, next)) = rest.token_tree() {
66-
rest = next;
67-
}
68-
Ok(((), rest))
69-
})?;
70-
71-
Ok(None)
72-
}
73-
}
74-
.parse2(tokens.clone())
75-
}
76-
7745
/// For a given verbatim [proc_macro2::TokenStream] return the [syn::ForeignItemType] if there is one
7846
///
7947
/// And ignore any extra syntax after the = in type A = ...
@@ -178,20 +146,6 @@ mod tests {
178146
assert_eq!(result[1].ident, "B");
179147
}
180148

181-
#[test]
182-
fn test_verbatim_to_foreign_mod() {
183-
let tokens = quote! {
184-
#[namespace = "a"]
185-
unsafe extern "C++" {
186-
type A;
187-
}
188-
};
189-
let result = verbatim_to_foreign_mod(&tokens).unwrap();
190-
let result = result.unwrap();
191-
assert_eq!(result.attrs.len(), 1);
192-
assert_eq!(result.items.len(), 1);
193-
}
194-
195149
#[test]
196150
fn test_foreign_fn_self() {
197151
let foreign_fn: ForeignItemFn = parse_quote! {

0 commit comments

Comments
 (0)