From 4ceb343e7f006972940b6880f974770c02fa6b87 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 26 Feb 2024 17:51:39 +0100 Subject: QtQml: Remove fallback mode for finding singleton enums in metaobject We always have a QQmlType these days and the QQmlType actually knows how to look up enums, in contrast to the code removed here. Pick-to: 6.7 Fixes: QTBUG-116057 Change-Id: Ief4b5c65da2e3c19668d4125b051356cc87bbeb6 Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmltypewrapper.cpp | 22 +++----------- tests/auto/qml/qqmllanguage/data/enumScopes.qml | 13 ++++++++ tests/auto/qml/qqmllanguage/testtypes.cpp | 3 ++ tests/auto/qml/qqmllanguage/testtypes.h | 38 ++++++++++++++++++++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 15 ++++++++++ 5 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/enumScopes.qml diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 0a707d4739..cce30c51c9 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -164,25 +164,11 @@ ReturnedValue QQmlTypeWrapper::create( return w.asReturnedValue(); } -static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qobjectSingleton, - const QQmlType &type, bool *ok) +static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, const QQmlType &type, bool *ok) { Q_ASSERT(ok != nullptr); - int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, ok); - if (*ok) - return value; - - // ### Optimize - QByteArray enumName = name->toQString().toUtf8(); - const QMetaObject *metaObject = qobjectSingleton->metaObject(); - for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { - QMetaEnum e = metaObject->enumerator(ii); - value = e.keyToValue(enumName.constData(), ok); - if (*ok) - return value; - } - *ok = false; - return -1; + const int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, ok); + return *ok ? value : -1; } ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty) @@ -220,7 +206,7 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons const bool includeEnums = w->d()->mode == Heap::QQmlTypeWrapper::IncludeEnums; if (includeEnums && name->startsWithUpper()) { bool ok = false; - int value = enumForSingleton(v4, name, qobjectSingleton, type, &ok); + int value = enumForSingleton(v4, name, type, &ok); if (ok) return QV4::Value::fromInt32(value).asReturnedValue(); diff --git a/tests/auto/qml/qqmllanguage/data/enumScopes.qml b/tests/auto/qml/qqmllanguage/data/enumScopes.qml new file mode 100644 index 0000000000..4e5c7ca1d2 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/enumScopes.qml @@ -0,0 +1,13 @@ +import QtQml 2.15 +import EnumScopeTest 1.0 + +QtObject { + property NonSingleton n: NonSingleton { + id: nonSingleton + } + + property bool singletonUnscoped: Singleton.enumProperty === Singleton.EnumValue2 + property bool singletonScoped: Singleton.enumProperty === Singleton.EnumType.EnumValue2 + property bool nonSingletonUnscoped: nonSingleton.enumProperty === NonSingleton.EnumValue2 + property bool nonSingletonScoped: nonSingleton.enumProperty === NonSingleton.EnumType.EnumValue2 +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index dafebee9b2..33616690a4 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -165,6 +165,9 @@ void registerTypes() qmlRegisterTypesAndRevisions("Test", 1); qmlRegisterTypesAndRevisions("Test", 1); + + qmlRegisterTypesAndRevisions("EnumScopeTest", 1); + qmlRegisterTypesAndRevisions("EnumScopeTest", 1); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 1c0c9d092d..be8ba40be4 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -2770,4 +2770,42 @@ public: } }; + +class Singleton: public QObject +{ + Q_OBJECT + Q_PROPERTY(EnumType enumProperty READ enumProperty CONSTANT) + Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") + QML_ELEMENT + QML_SINGLETON +public: + explicit Singleton(QObject* parent = nullptr) : QObject(parent) {} + enum class EnumType { + EnumValue1, + EnumValue2 + }; + Q_ENUM(EnumType); + EnumType enumProperty() const { + return EnumType::EnumValue2; + } +}; + +class NonSingleton: public QObject +{ + Q_OBJECT + Q_PROPERTY(EnumType enumProperty READ enumProperty CONSTANT) + Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") + QML_ELEMENT +public: + explicit NonSingleton(QObject* parent = nullptr) : QObject(parent) {} + enum class EnumType { + EnumValue1, + EnumValue2 + }; + Q_ENUM(EnumType); + EnumType enumProperty() const { + return EnumType::EnumValue2; + } +}; + #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 5ad3f497df..4f9a3dec68 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -446,6 +446,7 @@ private slots: void badInlineComponentAnnotation(); void manuallyCallSignalHandler(); void overrideDefaultProperty(); + void enumScopes(); private: QQmlEngine engine; @@ -8585,6 +8586,20 @@ void tst_qqmllanguage::overrideDefaultProperty() url.toString() + QLatin1String(":5 Cannot assign object to list property \"data\"\n")); } +void tst_qqmllanguage::enumScopes() +{ + QQmlEngine e; + QQmlComponent c(&e, testFileUrl("enumScopes.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer o(c.create()); + QVERIFY(!o.isNull()); + + QCOMPARE(o->property("singletonUnscoped"), false); + QCOMPARE(o->property("singletonScoped"), true); + QCOMPARE(o->property("nonSingletonUnscoped"), false); + QCOMPARE(o->property("nonSingletonScoped"), true); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" -- cgit v1.2.3