Enforce complete method types of QML registered classes

For QML, we like to avoid doing string to type lookups at runtime as
much as possible. Therefore, QML registration macros like QML_ELEMENT
now cause moc to require complete types not only for properties, but
also for all methods known to the metatype system.

Change-Id: Ied3d940c102719db4852d3a748d05be1f415b353
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Fabian Kosmale 2020-08-29 12:07:26 +02:00
parent 905d4e4eee
commit 69d239ef00
3 changed files with 16 additions and 3 deletions

View File

@ -572,7 +572,7 @@ void Generator::generateCode()
fprintf(out, " nullptr,\n");
} else {
bool needsComma = false;
if (!requireCompleteTypes) {
if (!(requireCompleteTypes || cdef->requireCompleteMethodTypes)) {
fprintf(out, "qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t\n", qualifiedClassNameIdentifier.constData());
needsComma = true;
} else {

View File

@ -1512,12 +1512,15 @@ void Moc::parseFlag(BaseDef *def)
next(RPAREN);
}
void Moc::parseClassInfo(BaseDef *def)
Moc::EncounteredQmlMacro Moc::parseClassInfo(BaseDef *def)
{
bool encounteredQmlMacro = false;
next(LPAREN);
ClassInfoDef infoDef;
next(STRING_LITERAL);
infoDef.name = symbol().unquotedLexem();
if (infoDef.name.startsWith("QML."))
encounteredQmlMacro = true;
next(COMMA);
if (test(STRING_LITERAL)) {
infoDef.value = symbol().unquotedLexem();
@ -1533,6 +1536,13 @@ void Moc::parseClassInfo(BaseDef *def)
}
next(RPAREN);
def->classInfoList += infoDef;
return encounteredQmlMacro ? EncounteredQmlMacro::Yes : EncounteredQmlMacro::No;
}
void Moc::parseClassInfo(ClassDef *def)
{
if (parseClassInfo(static_cast<BaseDef *>(def)) == EncounteredQmlMacro::Yes)
def->requireCompleteMethodTypes = true;
}
void Moc::parseInterfaces(ClassDef *def)

View File

@ -204,6 +204,7 @@ struct ClassDef : BaseDef {
bool hasQObject = false;
bool hasQGadget = false;
bool hasQNamespace = false;
bool requireCompleteMethodTypes = false;
QJsonObject toJson() const;
};
@ -266,7 +267,9 @@ public:
void parsePropertyAttributes(PropertyDef &propDef);
void parseEnumOrFlag(BaseDef *def, bool isFlag);
void parseFlag(BaseDef *def);
void parseClassInfo(BaseDef *def);
enum class EncounteredQmlMacro {Yes, No};
EncounteredQmlMacro parseClassInfo(BaseDef *def);
void parseClassInfo(ClassDef *def);
void parseInterfaces(ClassDef *def);
void parseDeclareInterface();
void parseDeclareMetatype();