aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqml.h32
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.cpp38
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/qqmllanguage.pro5
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h41
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp31
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()