summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-08-29 12:07:26 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-09-03 09:46:57 +0200
commit69d239ef00c57baf5af5c760bfedd5344d1d0090 (patch)
tree9525d26806f9d19a9fa4b4792344125590666126 /src/tools
parent905d4e4eeef7c740458c628391860b293e2ba136 (diff)
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>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/moc/generator.cpp2
-rw-r--r--src/tools/moc/moc.cpp12
-rw-r--r--src/tools/moc/moc.h5
3 files changed, 16 insertions, 3 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 155a98209d..0df3a43584 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -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 {
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 516b231cd5..228a21e3c2 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -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)
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 7f63402aca..5ce057210f 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -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();