diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-02-12 17:49:31 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-02-25 09:58:56 +0100 |
commit | 11ff5c314682258b6eb26e90847210662eb0f533 (patch) | |
tree | 4b0b2f6bed8f25423bec5a64a1458207822662b5 /src/qmltyperegistrar/qmltyperegistrar.cpp | |
parent | 94901065ddd0c0c65e0db7c2151c0eb9eb3f64c5 (diff) |
Provide a way to statically register namespaces
Previously, qmltyperegistrar would stumble over any QML_* macros in
namespaces, as the namespaces could not be used as template arguments.
However, namespaces are intended to be usable by QML as uncreatable
"types".
Now, qmltyperegistrar checks the namespace flag that moc records in the
JSON output, and if that is given, registers an uncreatable metaobject
instead of a type. Therefore you can use QML_ELEMENT and friends to
register namespaces, just like you would register classes (except that
they're implicitly uncreatable, of course).
Task-number: QTBUG-68796
Change-Id: I186d7e9425471c32fb1a1f29c0c0b946afb2a9d2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmltyperegistrar/qmltyperegistrar.cpp')
-rw-r--r-- | src/qmltyperegistrar/qmltyperegistrar.cpp | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 49c9fccb66..6fe5a20092 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -47,14 +47,23 @@ struct ScopedPointerFileCloser static inline void cleanup(FILE *handle) { if (handle) fclose(handle); } }; -static bool acceptClassForQmlTypeRegistration(const QJsonObject &classDef) +enum RegistrationMode { + NoRegistration, + ClassRegistration, + NamespaceRegistration +}; + +static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef) { const QJsonArray classInfos = classDef[QLatin1String("classInfos")].toArray(); for (const QJsonValue &info: classInfos) { - if (info[QLatin1String("name")].toString() == QLatin1String("QML.Element")) - return true; + const QString name = info[QLatin1String("name")].toString(); + if (name == QLatin1String("QML.Element")) { + return classDef[QLatin1String("namespace")].toBool() ? NamespaceRegistration + : ClassRegistration; + } } - return false; + return NoRegistration; } static QVector<QJsonObject> foreignRelatedTypes(const QVector<QJsonObject> &types, @@ -284,7 +293,11 @@ int main(int argc, char **argv) const QJsonArray classes = metaObject[QLatin1String("classes")].toArray(); for (const auto &cls : classes) { QJsonObject classDef = cls.toObject(); - if (acceptClassForQmlTypeRegistration(classDef)) { + switch (qmlTypeRegistrationMode(classDef)) { + case NamespaceRegistration: + classDef.insert(QLatin1String("namespace"), true); + Q_FALLTHROUGH(); + case ClassRegistration: { const QString include = metaObject[QLatin1String("inputFile")].toString(); const bool declaredInHeader = include.endsWith(QLatin1String(".h")); if (declaredInHeader) { @@ -297,8 +310,11 @@ int main(int argc, char **argv) .toString())); } types.append(classDef); - } else { + break; + } + case NoRegistration: foreignTypes.append(classDef); + break; } } }; @@ -360,8 +376,14 @@ int main(int argc, char **argv) continue; const QString className = classDef[QLatin1String("qualifiedClassName")].toString(); - fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", qPrintable(className), - qPrintable(module), qPrintable(majorVersion)); + + if (classDef.value(QLatin1String("namespace")).toBool()) { + fprintf(output, "\n qmlRegisterNamespaceAndRevisions(&%s::staticMetaObject, \"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } else { + fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } } fprintf(output, "\n qmlRegisterModule(\"%s\", %s, %s);", |