diff options
-rw-r--r-- | src/qml/qml/qqml.h | 32 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltyperegistrar.cpp | 38 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml | 5 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/qqmllanguage.pro | 5 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.h | 41 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 31 |
7 files changed, 138 insertions, 20 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index ef7fdd1945..a3e3f1c584 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -848,6 +848,38 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor) template<> inline void qmlRegisterTypesAndRevisions<>(const char *, int) {} +inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject, + const char *uri, int versionMajor) +{ + QQmlPrivate::RegisterTypeAndRevisions type = { + 0, + 0, + 0, + 0, + nullptr, + + uri, + versionMajor, + + metaObject, + metaObject, + + nullptr, + nullptr, + + -1, + -1, + -1, + + nullptr, + nullptr, + + &qmlCreateCustomParser<void> + }; + + qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type); +} + int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName); QT_END_NAMESPACE 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);", diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml new file mode 100644 index 0000000000..3b37c29b18 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml @@ -0,0 +1,5 @@ +import StaticTest 1.0 + +MyStaticSecondNamespacedType { + list: [ MyStaticNamespacedType {} ] +} diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml new file mode 100644 index 0000000000..2778baadb9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml @@ -0,0 +1,6 @@ +import StaticTest 1.0 + +MyStaticNamespacedType { + myEnum: MyStaticNamespace.Key5 + property int intProperty: MyStaticNamespace.MyOtherNSEnum.OtherKey2 +} diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro index 724a27320c..6c54525544 100644 --- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro +++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro @@ -1,4 +1,7 @@ -CONFIG += testcase +CONFIG += testcase qmltypes +QML_IMPORT_NAME = StaticTest +QML_IMPORT_VERSION = 1.0 + TARGET = tst_qqmllanguage macx:CONFIG -= app_bundle diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 148179cb9c..8852bf7af9 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -750,6 +750,47 @@ private: bool m_ownRWObj; }; +namespace MyStaticNamespace { + Q_NAMESPACE + QML_ELEMENT + + enum MyNSEnum { + Key1 = 1, + Key2, + Key5 = 5 + }; + Q_ENUM_NS(MyNSEnum); + + enum class MyOtherNSEnum { + OtherKey1 = 1, + OtherKey2 + }; + Q_ENUM_NS(MyOtherNSEnum); + + + class MyNamespacedType : public QObject + { + Q_OBJECT + Q_PROPERTY(MyStaticNamespace::MyNSEnum myEnum MEMBER m_myEnum) + QML_NAMED_ELEMENT(MyStaticNamespacedType) + MyStaticNamespace::MyNSEnum m_myEnum = MyNSEnum::Key1; + }; + + class MySecondNamespacedType : public QObject + { + Q_OBJECT + Q_PROPERTY(QQmlListProperty<MyStaticNamespace::MyNamespacedType> list READ list) + QML_NAMED_ELEMENT(MyStaticSecondNamespacedType) + public: + QQmlListProperty<MyNamespacedType> list() + { + return QQmlListProperty<MyNamespacedType>(this, &m_list); + } + + private: + QList<MyNamespacedType *> m_list; + }; +} namespace MyNamespace { Q_NAMESPACE diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index bd23806e3a..4d4056ba3f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -1858,21 +1858,30 @@ void tst_qqmllanguage::valueTypes() void tst_qqmllanguage::cppnamespace() { - { - QQmlComponent component(&engine, testFileUrl("cppnamespace.qml")); + QScopedPointer<QObject> object; + + auto create = [&](const char *file) { + QQmlComponent component(&engine, testFileUrl(file)); VERIFY_ERRORS(0); - QScopedPointer<QObject> object(component.create()); + object.reset(component.create()); QVERIFY(object != nullptr); + }; - QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2); - } + auto createAndCheck = [&](const char *file) { + create(file); + return !QTest::currentTestFailed(); + }; - { - QQmlComponent component(&engine, testFileUrl("cppnamespace.2.qml")); - VERIFY_ERRORS(0); - QScopedPointer<QObject> object(component.create()); - QVERIFY(object != nullptr); - } + QVERIFY(createAndCheck("cppnamespace.qml")); + QCOMPARE(object->property("intProperty").toInt(), + (int)MyNamespace::MyOtherNSEnum::OtherKey2); + + QVERIFY(createAndCheck("cppstaticnamespace.qml")); + QCOMPARE(object->property("intProperty").toInt(), + (int)MyStaticNamespace::MyOtherNSEnum::OtherKey2); + + QVERIFY(createAndCheck("cppnamespace.2.qml")); + QVERIFY(createAndCheck("cppstaticnamespace.2.qml")); } void tst_qqmllanguage::aliasProperties() |