forked from KDAB/cxx-qt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for #[qenum] associated with a QObject
This is the initial support for KDAB#34. It only supports `Q_ENUM` within a given `Q_OBJECT` class. `Q_ENUM_NS` is not (yet) supported. Documentation will be added in a follow-up commit.
- Loading branch information
1 parent
288c079
commit 3edb6e3
Showing
30 changed files
with
686 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> | ||
// SPDX-FileContributor: Leon Matthes <leon.matthes@kdab.com> | ||
// | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
use indoc::formatdoc; | ||
use syn::Result; | ||
|
||
use crate::{ | ||
generator::utils::cpp::Indent, | ||
parser::{mappings::ParsedCxxMappings, qenum::ParsedQEnum}, | ||
}; | ||
|
||
use super::qobject::GeneratedCppQObjectBlocks; | ||
|
||
pub fn generate( | ||
qenums: &[ParsedQEnum], | ||
cxx_mappings: &ParsedCxxMappings, | ||
) -> Result<GeneratedCppQObjectBlocks> { | ||
let mut generated = GeneratedCppQObjectBlocks::default(); | ||
|
||
for qenum in qenums { | ||
let enum_name = &qenum.ident.to_string(); | ||
|
||
let mut qualified_name = cxx_mappings.cxx(enum_name); | ||
// TODO: this is a workaround for cxx_mappings.cxx not always returning a fully-qualified | ||
// identifier. | ||
// Once https://github.com/KDAB/cxx-qt/issues/619 is fixed, this can be removed. | ||
if !qualified_name.starts_with("::") { | ||
qualified_name.insert_str(0, "::"); | ||
} | ||
|
||
let enum_values = qenum | ||
.variants | ||
.iter() | ||
.map(ToString::to_string) | ||
.collect::<Vec<_>>() | ||
.join(",\n"); | ||
|
||
generated.includes.insert("#include <cstdint>".to_string()); | ||
let enum_definition = formatdoc! { r#" | ||
enum class {enum_name} : ::std::int32_t {{ | ||
{enum_values} | ||
}}; | ||
"#, enum_values = enum_values.indented(2) }; | ||
generated.forward_declares.push(enum_definition.clone()); | ||
generated.metaobjects.push(formatdoc! {r#" | ||
#ifdef Q_MOC_RUN | ||
{enum_definition} | ||
Q_ENUM({enum_name}) | ||
#else | ||
using {enum_name} = {qualified_name}; | ||
Q_ENUM({enum_name}) | ||
#endif | ||
"#, enum_definition = enum_definition.indented(2) }); | ||
} | ||
|
||
Ok(generated) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use std::assert_eq; | ||
|
||
use super::*; | ||
use indoc::indoc; | ||
use pretty_assertions::assert_str_eq; | ||
use syn::parse_quote; | ||
|
||
#[test] | ||
fn generates() { | ||
let qenums = [ParsedQEnum::parse(parse_quote! { | ||
enum MyEnum { | ||
A, B, C | ||
} | ||
}) | ||
.unwrap()]; | ||
|
||
let generated = generate(&qenums, &ParsedCxxMappings::default()).unwrap(); | ||
assert_eq!(generated.includes.len(), 1); | ||
assert!(generated.includes.contains("#include <cstdint>")); | ||
assert_eq!(generated.metaobjects.len(), 1); | ||
assert_str_eq!( | ||
indoc! {r#" | ||
#ifdef Q_MOC_RUN | ||
enum class MyEnum : ::std::int32_t { | ||
A, | ||
B, | ||
C | ||
}; | ||
Q_ENUM(MyEnum) | ||
#else | ||
using MyEnum = ::MyEnum; | ||
Q_ENUM(MyEnum) | ||
#endif | ||
"#}, | ||
generated.metaobjects[0], | ||
); | ||
assert_eq!(generated.forward_declares.len(), 1); | ||
assert_str_eq!( | ||
indoc! { r#" | ||
enum class MyEnum : ::std::int32_t { | ||
A, | ||
B, | ||
C | ||
}; | ||
"# }, | ||
generated.forward_declares[0], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> | ||
// SPDX-FileContributor: Leon Matthes <leon.matthes@kdab.com> | ||
// | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
use crate::{generator::rust::qobject::GeneratedRustQObject, parser::qenum::ParsedQEnum}; | ||
use syn::parse_quote; | ||
|
||
pub fn generate(qenums: &[ParsedQEnum]) -> GeneratedRustQObject { | ||
let mut result = GeneratedRustQObject::default(); | ||
for qenum in qenums { | ||
let qenum_item = &qenum.item; | ||
let qenum_ident = &qenum.ident; | ||
result.append(&mut GeneratedRustQObject { | ||
cxx_mod_contents: vec![ | ||
parse_quote! { | ||
#[repr(i32)] | ||
#qenum_item | ||
}, | ||
parse_quote! { | ||
extern "C++" { | ||
type #qenum_ident; | ||
} | ||
}, | ||
], | ||
..Default::default() | ||
}); | ||
} | ||
result | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::tests::assert_tokens_eq; | ||
use quote::quote; | ||
use syn::parse_quote; | ||
|
||
use super::*; | ||
|
||
#[test] | ||
fn generates() { | ||
let qenums = vec![ParsedQEnum::parse(parse_quote! { | ||
/// Doc comment | ||
enum MyEnum { | ||
/// Document Variant1 | ||
Variant1, | ||
/// Document Variant2 | ||
Variant2, | ||
} | ||
}) | ||
.unwrap()]; | ||
|
||
let generated = generate(&qenums); | ||
assert_eq!(generated.cxx_mod_contents.len(), 2); | ||
assert_tokens_eq( | ||
&generated.cxx_mod_contents[0], | ||
quote! { | ||
#[repr(i32)] | ||
#[doc = r" Doc comment"] | ||
enum MyEnum { | ||
#[doc = r" Document Variant1"] | ||
Variant1, | ||
#[doc = r" Document Variant2"] | ||
Variant2, | ||
} | ||
}, | ||
); | ||
assert_tokens_eq( | ||
&generated.cxx_mod_contents[1], | ||
quote! { | ||
extern "C++" { | ||
type MyEnum; | ||
} | ||
}, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.