aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-03-27 13:23:18 +0100
committerLars Knoll <lars.knoll@qt.io>2019-03-28 06:35:01 +0000
commit28a114cbf7a3c2c18948e8bd582e5b5463443cab (patch)
tree7887a9ec06760047325f9b742ec3e6b64007fe88
parent3507c29e8d9ea42e63fd0c01e27ee9263d939256 (diff)
Allow enums in QQmlType to be set up in two separate passes
The baseMetaObject and the property cache can become available at different points in time. If we have initialized the enums before either of them is available we want to add the additional enums when the other one appears. Fixes: QTBUG-74677 Change-Id: I57276681a50b6c04181c6a29e736f2dc20632a0c Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/qml/qqmlmetatype.cpp23
-rw-r--r--tests/auto/qml/qqmlmetatype/data/Components/App.qml57
-rw-r--r--tests/auto/qml/qqmlmetatype/data/Components/qmldir3
-rw-r--r--tests/auto/qml/qqmlmetatype/data/enumsInRecursiveImport.qml11
-rw-r--r--tests/auto/qml/qqmlmetatype/qqmlmetatype.pro7
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp32
6 files changed, 125 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 8db0bc92b8..f801e9aeba 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -261,7 +261,8 @@ public:
int index;
mutable volatile bool isSetup:1;
- mutable volatile bool isEnumSetup:1;
+ mutable volatile bool isEnumFromCacheSetup:1;
+ mutable volatile bool isEnumFromBaseSetup:1;
mutable bool haveSuperType:1;
mutable QList<QQmlProxyMetaObject::ProxyData> metaObjects;
mutable QStringHash<int> enums;
@@ -367,7 +368,8 @@ QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds;
QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
: refCount(1), regType(type), iid(nullptr), typeId(0), listId(0), revision(0),
containsRevisionedAttributes(false), baseMetaObject(nullptr),
- index(-1), isSetup(false), isEnumSetup(false), haveSuperType(false)
+ index(-1), isSetup(false), isEnumFromCacheSetup(false), isEnumFromBaseSetup(false),
+ haveSuperType(false)
{
switch (type) {
case QQmlType::CppType:
@@ -829,19 +831,24 @@ void QQmlTypePrivate::init() const
void QQmlTypePrivate::initEnums(const QQmlPropertyCache *cache) const
{
- if (isEnumSetup) return;
+ if ((isEnumFromBaseSetup || !baseMetaObject)
+ && (isEnumFromCacheSetup || !cache)) {
+ return;
+ }
init();
QMutexLocker lock(metaTypeDataLock());
- if (isEnumSetup) return;
- if (cache)
+ if (!isEnumFromCacheSetup && cache) {
insertEnumsFromPropertyCache(cache);
- if (baseMetaObject) // could be singleton type without metaobject
- insertEnums(baseMetaObject);
+ isEnumFromCacheSetup = true;
+ }
- isEnumSetup = true;
+ if (!isEnumFromBaseSetup && baseMetaObject) { // could be singleton type without metaobject
+ insertEnums(baseMetaObject);
+ isEnumFromBaseSetup = true;
+ }
}
void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
diff --git a/tests/auto/qml/qqmlmetatype/data/Components/App.qml b/tests/auto/qml/qqmlmetatype/data/Components/App.qml
new file mode 100644
index 0000000000..3792ca665e
--- /dev/null
+++ b/tests/auto/qml/qqmlmetatype/data/Components/App.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+
+import Components 1.0
+
+QtObject {
+ id: mainRect
+
+ property int appState: App.AppState.Blue
+ property string color: "blue"
+
+ enum AppState {
+ Red,
+ Green,
+ Blue
+ }
+
+ onAppStateChanged: {
+ if (appState === App.AppState.Green)
+ mainRect.color = "green"
+ else if (appState === App.AppState.Red)
+ mainRect.color = "red"
+ }
+
+ property Timer timer: Timer {
+ onTriggered: appState = App.AppState.Green
+ running: true
+ interval: 100
+ }
+}
diff --git a/tests/auto/qml/qqmlmetatype/data/Components/qmldir b/tests/auto/qml/qqmlmetatype/data/Components/qmldir
new file mode 100644
index 0000000000..3f6db4ed2d
--- /dev/null
+++ b/tests/auto/qml/qqmlmetatype/data/Components/qmldir
@@ -0,0 +1,3 @@
+module Components
+
+App 1.0 App.qml
diff --git a/tests/auto/qml/qqmlmetatype/data/enumsInRecursiveImport.qml b/tests/auto/qml/qqmlmetatype/data/enumsInRecursiveImport.qml
new file mode 100644
index 0000000000..eef6abc6e5
--- /dev/null
+++ b/tests/auto/qml/qqmlmetatype/data/enumsInRecursiveImport.qml
@@ -0,0 +1,11 @@
+import QtQml 2.0
+
+import Components 1.0
+
+QtObject {
+ property App app: App {
+ appState: 0
+ }
+
+ property string color: app.color
+}
diff --git a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
index 345bc59615..109de7d212 100644
--- a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
+++ b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro
@@ -10,4 +10,11 @@ qmlfiles.files = data/CompositeType.qml
qmlfiles.prefix = /tstqqmlmetatype
RESOURCES += qmlfiles
+qmldirresource.files = \
+ data/Components/App.qml \
+ data/Components/qmldir \
+ data/enumsInRecursiveImport.qml
+qmldirresource.prefix = /
+RESOURCES += qmldirresource
+
QT += core-private gui-private qml-private testlib
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index ce72f40dcc..7f103dc5ed 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -67,6 +67,9 @@ private slots:
void normalizeUrls();
void unregisterAttachedProperties();
void revisionedGroupedProperties();
+
+ void enumsInRecursiveImport_data();
+ void enumsInRecursiveImport();
};
class TestType : public QObject
@@ -629,6 +632,35 @@ void tst_qqmlmetatype::revisionedGroupedProperties()
}
}
+void tst_qqmlmetatype::enumsInRecursiveImport_data()
+{
+ QTest::addColumn<QString>("importPath");
+ QTest::addColumn<QUrl>("componentUrl");
+
+ QTest::addRow("data directory") << dataDirectory()
+ << testFileUrl("enumsInRecursiveImport.qml");
+
+ // The qrc case behaves differently because we failed to detect the recursion in type loading
+ // due to varying numbers of slashes after the "qrc:" in the URLs.
+ QTest::addRow("resources") << QStringLiteral("qrc:/data")
+ << QUrl("qrc:/data/enumsInRecursiveImport.qml");
+}
+
+void tst_qqmlmetatype::enumsInRecursiveImport()
+{
+ QFETCH(QString, importPath);
+ QFETCH(QUrl, componentUrl);
+
+ qmlClearTypeRegistrations();
+ QQmlEngine engine;
+ engine.addImportPath(importPath);
+ QQmlComponent c(&engine, componentUrl);
+ QVERIFY(c.isReady());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(!obj.isNull());
+ QTRY_COMPARE(obj->property("color").toString(), QString("green"));
+}
+
QTEST_MAIN(tst_qqmlmetatype)
#include "tst_qqmlmetatype.moc"