summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorBrett Stottlemyer <bstottle@ford.com>2019-12-26 19:40:37 -0500
committerBrett Stottlemyer <bstottle@ford.com>2021-09-07 12:26:30 -0400
commit045cbcbc50d51640142691c8cd78dd868e03ba1b (patch)
treed66f2e9c8b69e5b5b620bb05bc66232a9868e5e2 /tools
parent73c2fe37405aac88664681163560d60a17000863 (diff)
Allow PODs to include enums/flags
The goal is to allow a new syntax: POD myPOD{ ENUM MyEnum {FOO, BAR} MyEnum myEnum, QString myString }, in addition to the current syntax POD myPOD(QString myString) The challenge is that the parsing simplified the detection of parameter types and parameter names by grabbing everything between the parentheses and having a separate chunk of code split that up. The new POD syntax requires the parser to detect and handle parameter types (including templated types) and handle that syntax. This converts the enum parsing to use new symbol and value tokens, rather than the enum_param token, which is necessary to enable a more generic type detection. The pod2 type has comparable syntax to the previous version, but uses brackets ('{' and '}') instead of parentheses for the definition. While this code detects the parameter type and parameter name distinctly, it currently merges all of the parameter content into a single string for processing using the original postprocess method. This ensures the capture is correct and there aren't any regressions. The tests were modified for the new POD syntax. The new code normalizes whitespace, rather than keeping the source formatting. Pick-to: 6.2 Change-Id: I671b23852fc2b515bcaea1ed389cfbde122683bd Reviewed-by: Michael Brasser <michael.brasser@live.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/repc/repcodegenerator.cpp50
1 files changed, 43 insertions, 7 deletions
diff --git a/tools/repc/repcodegenerator.cpp b/tools/repc/repcodegenerator.cpp
index 71be53a..175ac43 100644
--- a/tools/repc/repcodegenerator.cpp
+++ b/tools/repc/repcodegenerator.cpp
@@ -84,6 +84,17 @@ static bool hasScopedEnum(const ASTClass &classContext)
return false;
}
+static bool hasScopedEnum(const POD &pod)
+{
+ for (const ASTEnum &astEnum : pod.enums) {
+ if (astEnum.isScoped) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
static QString fullyQualifiedName(const ASTClass& classContext, const QString &className,
const QString &typeName)
{
@@ -156,10 +167,26 @@ void RepCodeGenerator::generate(Mode mode, QString fileName)
generatePOD(pod);
QSet<QString> metaTypes;
+ QSet<QString> enumTypes;
for (const POD &pod : m_ast.pods) {
metaTypes << pod.name;
- for (const PODAttribute &attribute : pod.attributes)
- metaTypes << attribute.type;
+ // We register from within the code generated for classes, not PODs
+ // Thus, for enums/flags in PODs, we need the to prefix with the POD
+ // name. The enumTypes set is used to make sure we don't try to
+ // register the non-prefixed name if it is used as a member variable
+ // type.
+ for (const ASTEnum &en : pod.enums) {
+ metaTypes << QLatin1String("%1::%2").arg(pod.name, en.name);
+ enumTypes << en.name;
+ }
+ for (const ASTFlag &flag : pod.flags) {
+ metaTypes << QLatin1String("%1::%2").arg(pod.name, flag.name);
+ enumTypes << flag.name;
+ }
+ for (const PODAttribute &attribute : pod.attributes) {
+ if (!enumTypes.contains(attribute.type))
+ metaTypes << attribute.type;
+ }
}
const QString metaTypeRegistrationCode = generateMetaTypeRegistration(metaTypes);
@@ -409,9 +436,16 @@ void RepCodeGenerator::generatePOD(const POD &pod)
"{\n"
" Q_GADGET\n"
<< "\n"
- << formatQPropertyDeclarations(pod)
- << "public:\n"
- << formatConstructors(pod)
+ << formatQPropertyDeclarations(pod);
+ if (hasScopedEnum(pod)) // See https://bugreports.qt.io/browse/QTBUG-73360
+ m_stream << " Q_CLASSINFO(\"RegisterEnumClassesUnscoped\", \"false\")\n";
+ m_stream << "public:\n";
+ generateDeclarationsForEnums(pod.enums);
+ for (auto &flag : pod.flags) {
+ m_stream << " Q_DECLARE_FLAGS(" << flag.name << ", " << flag._enum << ")\n";
+ m_stream << " Q_FLAG(" << flag.name << ")\n";
+ }
+ m_stream << formatConstructors(pod)
<< formatPropertyGettersAndSetters(pod)
<< "private:\n"
<< formatDataMembers(pod)
@@ -427,8 +461,10 @@ void RepCodeGenerator::generatePOD(const POD &pod)
<< "}\n"
<< "\n"
<< formatDebugOperator(pod)
- << formatMarshallingOperators(pod)
- << "\n\n";
+ << formatMarshallingOperators(pod);
+ for (auto &flag : pod.flags)
+ m_stream << "Q_DECLARE_OPERATORS_FOR_FLAGS(" << pod.name << "::" << flag.name << ")\n";
+ m_stream << "\n";
}
QString getEnumType(const ASTEnum &en)