Skip to content

Commit 402f443

Browse files
Move parser to store some things together based on extern block
- QObjects, and invokables are now 2D Vecs, kept in their original block - Adds some helper methods for iterating like they are still flat
1 parent b9d3aa1 commit 402f443

File tree

6 files changed

+64
-43
lines changed

6 files changed

+64
-43
lines changed

crates/cxx-qt-gen/src/generator/rust/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ impl GeneratedRustBlocks {
103103
// Generate a type declaration for `QObject` if necessary
104104
fn add_qobject_import(cxx_qt_data: &ParsedCxxQtData) -> Option<GeneratedRustFragment> {
105105
let includes = cxx_qt_data
106-
.qobjects
107-
.iter()
106+
.qobjects()
108107
.any(|obj| obj.has_qobject_macro && obj.base_class.is_none());
109108
if includes
110109
|| cxx_qt_data

crates/cxx-qt-gen/src/generator/structuring/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ impl<'a> Structures<'a> {
7979
/// Returns an error, if any references could not be resolved.
8080
pub fn new(cxxqtdata: &'a ParsedCxxQtData) -> Result<Self> {
8181
let mut qobjects: Vec<_> = cxxqtdata
82-
.qobjects
83-
.iter()
82+
.qobjects()
8483
.map(StructuredQObject::from_qobject)
8584
.collect();
8685

@@ -92,19 +91,19 @@ impl<'a> Structures<'a> {
9291
}
9392

9493
// Associate each method parsed with its appropriate qobject
95-
for method in &cxxqtdata.methods {
94+
for method in cxxqtdata.methods() {
9695
let qobject = find_qobject(&mut qobjects, &method.qobject_ident)?;
9796
qobject.methods.push(method);
9897
}
9998

10099
// Associate each inherited method parsed with its appropriate qobject
101-
for inherited_method in &cxxqtdata.inherited_methods {
100+
for inherited_method in cxxqtdata.inherited_methods() {
102101
let qobject = find_qobject(&mut qobjects, &inherited_method.qobject_ident)?;
103102
qobject.inherited_methods.push(inherited_method);
104103
}
105104

106105
// Associate each signal parsed with its appropriate qobject
107-
for signal in &cxxqtdata.signals {
106+
for signal in cxxqtdata.signals() {
108107
let qobject = find_qobject(&mut qobjects, &signal.qobject_ident)?;
109108
qobject.signals.push(signal);
110109
}

crates/cxx-qt-gen/src/naming/name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use syn::{spanned::Spanned, Attribute, Error, Ident, Path, Result};
1717
/// Naming in CXX can be rather complex.
1818
/// The following Rules apply:
1919
/// - If only a cxx_name **or** a rust_name is given, the identifier of the type/function will be
20-
/// used for part that wasn't specified explicitly.
20+
/// used for part that wasn't specified explicitly.
2121
/// - If **both** attributes are present, the identifier itself is not used!
2222
/// - The `rust_name` is always used to refer to the type within the bridge!.
2323
#[derive(Clone, Debug, PartialEq, Eq)]

crates/cxx-qt-gen/src/naming/type_names.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl TypeNames {
161161
module_ident: &Ident,
162162
) -> Result<()> {
163163
// Find and register the QObjects in the bridge
164-
for qobject in cxx_qt_data.qobjects.iter() {
164+
for qobject in cxx_qt_data.qobjects() {
165165
self.populate_qobject(qobject)?;
166166
}
167167

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

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,16 @@ use syn::{
2525
};
2626

2727
pub struct ParsedCxxQtData {
28-
/// Map of the QObjects defined in the module that will be used for code generation
29-
//
30-
// We have to use a BTreeMap here, instead of a HashMap, to keep the order of QObjects stable.
31-
// Otherwise, the output order would be different, depending on the environment, which makes it hard to test/debug.
32-
pub qobjects: Vec<ParsedQObject>,
28+
/// List of QObjects defined in the module, separated by block
29+
pub qobjects: Vec<Vec<ParsedQObject>>,
3330
/// List of QEnums defined in the module, that aren't associated with a QObject
3431
pub qenums: Vec<ParsedQEnum>,
35-
/// List of methods and Q_INVOKABLES found
36-
pub methods: Vec<ParsedMethod>,
37-
/// List of the Q_SIGNALS found
38-
pub signals: Vec<ParsedSignal>,
39-
/// List of the inherited methods found
40-
pub inherited_methods: Vec<ParsedInheritedMethod>,
32+
/// List of methods and Q_INVOKABLES found, separated by block
33+
pub methods: Vec<Vec<ParsedMethod>>,
34+
/// List of the Q_SIGNALS found, separated by block
35+
pub signals: Vec<Vec<ParsedSignal>>,
36+
/// List of the inherited methods found, separated by block
37+
pub inherited_methods: Vec<Vec<ParsedInheritedMethod>>,
4138
/// List of QNamespace declarations
4239
pub qnamespaces: Vec<ParsedQNamespace>,
4340
/// Blocks of extern "C++Qt"
@@ -50,6 +47,11 @@ pub struct ParsedCxxQtData {
5047
pub module_ident: Ident,
5148
}
5249

50+
/// Used to get a flat iterator view into a 2D Vector
51+
fn flat_view<T>(v: &[Vec<T>]) -> impl Iterator<Item = &T> {
52+
v.iter().flat_map(|v| v.iter())
53+
}
54+
5355
impl ParsedCxxQtData {
5456
/// Create a ParsedCxxQtData from a given module and namespace
5557
pub fn new(module_ident: Ident, namespace: Option<String>) -> Self {
@@ -67,6 +69,26 @@ impl ParsedCxxQtData {
6769
}
6870
}
6971

72+
/// Iterator wrapper for methods
73+
pub fn methods(&self) -> impl Iterator<Item = &ParsedMethod> {
74+
flat_view(&self.methods)
75+
}
76+
77+
/// Iterator wrapper for signals
78+
pub fn signals(&self) -> impl Iterator<Item = &ParsedSignal> {
79+
flat_view(&self.signals)
80+
}
81+
82+
/// Iterator wrapper for inherited methods
83+
pub fn inherited_methods(&self) -> impl Iterator<Item = &ParsedInheritedMethod> {
84+
flat_view(&self.inherited_methods)
85+
}
86+
87+
/// Iterator wrapper for QObjects
88+
pub fn qobjects(&self) -> impl Iterator<Item = &ParsedQObject> {
89+
flat_view(&self.qobjects)
90+
}
91+
7092
/// Determine if the given [syn::Item] is a CXX-Qt related item
7193
/// If it is then add the [syn::Item] into qobjects BTreeMap
7294
/// Otherwise return the [syn::Item] to pass through to CXX
@@ -224,10 +246,10 @@ impl ParsedCxxQtData {
224246
try_inline_self_invokables(inline_self, &inline_ident, &mut signals)?;
225247
try_inline_self_invokables(inline_self, &inline_ident, &mut inherited)?;
226248

227-
self.qobjects.extend(qobjects);
228-
self.methods.extend(methods);
229-
self.signals.extend(signals);
230-
self.inherited_methods.extend(inherited);
249+
self.qobjects.push(qobjects);
250+
self.methods.push(methods);
251+
self.signals.push(signals);
252+
self.inherited_methods.push(inherited);
231253

232254
Ok(())
233255
}
@@ -247,8 +269,7 @@ impl ParsedCxxQtData {
247269

248270
#[cfg(test)]
249271
fn find_object(&self, id: &Ident) -> Option<&ParsedQObject> {
250-
self.qobjects
251-
.iter()
272+
self.qobjects()
252273
.find(|obj| obj.name.rust_unqualified() == id)
253274
}
254275
}
@@ -265,8 +286,9 @@ mod tests {
265286
/// Creates a ParsedCxxQtData with a QObject definition already found
266287
pub fn create_parsed_cxx_qt_data() -> ParsedCxxQtData {
267288
let mut cxx_qt_data = ParsedCxxQtData::new(format_ident!("ffi"), None);
268-
cxx_qt_data.qobjects.push(create_parsed_qobject());
269-
cxx_qt_data.qobjects.push(create_parsed_qobject());
289+
cxx_qt_data
290+
.qobjects
291+
.push(vec![create_parsed_qobject(), create_parsed_qobject()]);
270292
cxx_qt_data
271293
}
272294

@@ -376,9 +398,9 @@ mod tests {
376398
let result = cxx_qt_data.parse_cxx_qt_item(item).unwrap();
377399
assert!(result.is_none());
378400

379-
assert_eq!(cxx_qt_data.methods.len(), 2);
380-
assert!(cxx_qt_data.methods[0].is_qinvokable);
381-
assert!(!cxx_qt_data.methods[1].is_qinvokable)
401+
assert_eq!(cxx_qt_data.methods().collect::<Vec<_>>().len(), 2);
402+
assert!(cxx_qt_data.methods[0][0].is_qinvokable);
403+
assert!(!cxx_qt_data.methods[0][1].is_qinvokable)
382404
}
383405

384406
#[test]
@@ -406,7 +428,7 @@ mod tests {
406428
};
407429
cxx_qt_data.parse_cxx_qt_item(item).unwrap();
408430
assert_eq!(cxx_qt_data.methods.len(), 1);
409-
assert_eq!(cxx_qt_data.methods[0].name.cxx_unqualified(), "fooBar");
431+
assert_eq!(cxx_qt_data.methods[0][0].name.cxx_unqualified(), "fooBar");
410432
}
411433

412434
#[test]
@@ -421,9 +443,10 @@ mod tests {
421443
}
422444
};
423445
cxx_qt_data.parse_cxx_qt_item(item).unwrap();
424-
assert_eq!(cxx_qt_data.methods.len(), 1);
425-
assert_eq!(cxx_qt_data.methods[0].name.cxx_unqualified(), "foo_bar");
426-
assert_eq!(cxx_qt_data.methods[0].name.rust_unqualified(), "foo_bar");
446+
let methods = &cxx_qt_data.methods[0];
447+
assert_eq!(methods.len(), 1);
448+
assert_eq!(methods[0].name.cxx_unqualified(), "foo_bar");
449+
assert_eq!(methods[0].name.rust_unqualified(), "foo_bar");
427450
}
428451

429452
#[test]
@@ -438,8 +461,8 @@ mod tests {
438461
}
439462
};
440463
cxx_qt_data.parse_cxx_qt_item(item).unwrap();
441-
assert_eq!(cxx_qt_data.methods.len(), 1);
442-
assert_eq!(cxx_qt_data.methods[0].name.cxx_unqualified(), "renamed");
464+
assert_eq!(cxx_qt_data.methods[0].len(), 1);
465+
assert_eq!(cxx_qt_data.methods[0][0].name.cxx_unqualified(), "renamed");
443466
}
444467

445468
#[test]
@@ -611,7 +634,7 @@ mod tests {
611634
}
612635
};
613636
cxxqtdata.parse_cxx_qt_item(block).unwrap();
614-
let signals = &cxxqtdata.signals;
637+
let signals = &cxxqtdata.signals().collect::<Vec<_>>();
615638
assert_eq!(signals.len(), 2);
616639
assert!(signals[0].mutable);
617640
assert!(signals[1].mutable);
@@ -641,7 +664,7 @@ mod tests {
641664
};
642665
cxxqtdata.parse_cxx_qt_item(block).unwrap();
643666

644-
let signals = &cxxqtdata.signals;
667+
let signals = &cxxqtdata.signals().collect::<Vec<_>>();
645668
assert_eq!(signals.len(), 1);
646669
assert!(signals[0].mutable);
647670
assert!(!signals[0].safe);
@@ -716,7 +739,7 @@ mod tests {
716739
};
717740

718741
parsed_cxxqtdata.parse_cxx_qt_item(extern_rust_qt).unwrap();
719-
assert_eq!(parsed_cxxqtdata.qobjects.len(), 2);
742+
assert_eq!(parsed_cxxqtdata.qobjects().collect::<Vec<_>>().len(), 2);
720743

721744
assert!(parsed_cxxqtdata
722745
.find_object(&format_ident!("MyObject"))
@@ -741,7 +764,7 @@ mod tests {
741764
};
742765

743766
parsed_cxxqtdata.parse_cxx_qt_item(extern_rust_qt).unwrap();
744-
assert_eq!(parsed_cxxqtdata.qobjects.len(), 2);
767+
assert_eq!(parsed_cxxqtdata.qobjects().collect::<Vec<_>>().len(), 2);
745768
assert_eq!(
746769
parsed_cxxqtdata
747770
.find_object(&format_ident!("MyObject"))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ mod tests {
395395
assert_eq!(parser.passthrough_module.module_ident, "ffi");
396396
assert_eq!(parser.passthrough_module.vis, Visibility::Inherited);
397397
assert_eq!(parser.cxx_qt_data.namespace, Some("cxx_qt".to_owned()));
398-
assert_eq!(parser.cxx_qt_data.qobjects.len(), 1);
398+
assert_eq!(parser.cxx_qt_data.qobjects().collect::<Vec<_>>().len(), 1);
399399
assert_eq!(parser.type_names.num_types(), 19);
400400
assert_eq!(
401401
parser
@@ -441,7 +441,7 @@ mod tests {
441441
assert_eq!(parser.passthrough_module.module_ident, "ffi");
442442
assert_eq!(parser.passthrough_module.vis, Visibility::Inherited);
443443
assert_eq!(parser.cxx_qt_data.namespace, None);
444-
assert_eq!(parser.cxx_qt_data.qobjects.len(), 1);
444+
assert_eq!(parser.cxx_qt_data.qobjects().collect::<Vec<_>>().len(), 1);
445445
}
446446

447447
#[test]

0 commit comments

Comments
 (0)