diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-28 10:33:55 +0100 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-29 12:32:27 +0100 |
| commit | 43ef237f99d9f466b0889eaecff49b5898e6e8f3 (patch) | |
| tree | 236d0f0ab111b05298cf76cc78515cc908536fab | |
| parent | 4f8485796dc96af91dadeb9c266451528e6520b7 (diff) | |
qmltyperegistrar: Generate accessSemantics="none" for foreign namespaces
If the local type is a namespace, the resulting type can only be a
namespace, too, no matter what kind of tag the foreign one has.
Furthermore, we can re-use types with other QML_* tags this way.
Task-number: QTBUG-108883
Change-Id: Ib2ae08d5b081b8faa35124314f97d406d7b4f76f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
5 files changed, 40 insertions, 2 deletions
diff --git a/src/qmltyperegistrar/qqmltypesclassdescription.cpp b/src/qmltyperegistrar/qqmltypesclassdescription.cpp index 582a3af754..62800dba73 100644 --- a/src/qmltyperegistrar/qqmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qqmltypesclassdescription.cpp @@ -173,8 +173,18 @@ void QmlTypesClassDescription::collect( } } + // If the local type is a namespace the result can only be a namespace, + // no matter what the foreign type is. + const bool isNamespace = classDef->value(QLatin1String("namespace")).toBool(); + if (!foreignTypeName.isEmpty()) { - if (const QJsonObject *other = findType(foreign, foreignTypeName)) { + const QJsonObject *other = findType(foreign, foreignTypeName); + + // We can re-use a type with own QML_* macros as target of QML_FOREIGN + if (!other) + other = findType(types, foreignTypeName); + + if (other) { classDef = other; // Default properties are always local. @@ -245,6 +255,9 @@ void QmlTypesClassDescription::collect( if (!sequenceValueType.isEmpty()) { isCreatable = false; accessSemantics = QLatin1String("sequence"); + } else if (isNamespace) { + isCreatable = false; + accessSemantics = QLatin1String("none"); } else if (classDef && classDef->value(QLatin1String("object")).toBool()) { accessSemantics = QLatin1String("reference"); } else { diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt index 5bb30f1969..372f38cffe 100644 --- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt +++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt @@ -121,6 +121,7 @@ set(qml_files modulePrefix.qml moveRegVoid.qml multiforeign.qml + namespaceWithEnum.qml noBindingLoop.qml noQQmlData.qml nonNotifyable.qml diff --git a/tests/auto/qml/qmlcppcodegen/data/gadgetwithenum.h b/tests/auto/qml/qmlcppcodegen/data/gadgetwithenum.h index d146b9f654..839e026b77 100644 --- a/tests/auto/qml/qmlcppcodegen/data/gadgetwithenum.h +++ b/tests/auto/qml/qmlcppcodegen/data/gadgetwithenum.h @@ -5,7 +5,7 @@ #define GADGETWITHENUM_H #include <QtCore/qobject.h> -#include <QtQmlIntegration/qqmlintegration.h> +#include <QtQml/qqml.h> class GadgetWithEnum : public QObject { Q_GADGET @@ -20,4 +20,10 @@ public: Q_ENUM(State) }; +namespace GadgetWithEnumWrapper { + Q_NAMESPACE + QML_FOREIGN_NAMESPACE(GadgetWithEnum) + QML_NAMED_ELEMENT(NamespaceWithEnum) +}; + #endif // GADGETWITHENUM_H diff --git a/tests/auto/qml/qmlcppcodegen/data/namespaceWithEnum.qml b/tests/auto/qml/qmlcppcodegen/data/namespaceWithEnum.qml new file mode 100644 index 0000000000..aa73a78441 --- /dev/null +++ b/tests/auto/qml/qmlcppcodegen/data/namespaceWithEnum.qml @@ -0,0 +1,7 @@ +pragma Strict +import QtQml +import TestTypes + +QtObject { + property int i: NamespaceWithEnum.CONNECTED +} diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp index 1dd4c0fcf0..d2868e023a 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -148,6 +148,7 @@ private slots: void nullComparison(); void consoleObject(); void multiForeign(); + void namespaceWithEnum(); }; void tst_QmlCppCodegen::initTestCase() @@ -2870,6 +2871,16 @@ void tst_QmlCppCodegen::multiForeign() QCOMPARE(o->objectName(), u"not here and not there"_s); } +void tst_QmlCppCodegen::namespaceWithEnum() +{ + QQmlEngine engine; + QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/namespaceWithEnum.qml"_s)); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("i").toInt(), 2); +} + QTEST_MAIN(tst_QmlCppCodegen) #include "tst_qmlcppcodegen.moc" |
