diff options
author | Brett Stottlemyer <bstottle@ford.com> | 2019-12-26 19:40:37 -0500 |
---|---|---|
committer | Brett Stottlemyer <bstottle@ford.com> | 2021-09-07 12:26:30 -0400 |
commit | 045cbcbc50d51640142691c8cd78dd868e03ba1b (patch) | |
tree | d66f2e9c8b69e5b5b620bb05bc66232a9868e5e2 /tools | |
parent | 73c2fe37405aac88664681163560d60a17000863 (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.cpp | 50 |
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) |