From b1f53bf6eaabc9caa4f1eb523ad605c6719c752c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 24 Mar 2020 19:31:55 +0100 Subject: QML: Avoid cyclic references between ResolvedTypeRefence and CU The compilation unit keeps a list of references to used types. Usually those are references to types in other compilation units. However, in the case of inline components they can be references to the same compilation unit. In that case we should not addref() the compilation unit, as that forms a cyclic reference. Fixes: QTBUG-82768 Change-Id: I29d28f3a4780aad4fabd4aa2ed02ca0d0108987e Reviewed-by: Simon Hausmann --- src/qmltest/quicktest.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/qmltest') diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index 470b3c0f7a..443496c9bc 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -332,8 +332,9 @@ private: } }; - TestCaseEnumerationResult enumerateTestCases(QV4::ExecutableCompilationUnit *compilationUnit, - const Object *object = nullptr) + TestCaseEnumerationResult enumerateTestCases( + const QQmlRefPointer &compilationUnit, + const Object *object = nullptr) { QQmlType testCaseType; for (quint32 i = 0, count = compilationUnit->importCount(); i < count; ++i) { @@ -356,9 +357,8 @@ private: if (!object) // Start at root of compilation unit if not enumerating a specific child object = compilationUnit->objectAt(0); - if (QV4::ExecutableCompilationUnit *superTypeUnit - = compilationUnit->resolvedTypes.value(object->inheritedTypeNameIndex) - ->compilationUnit.data()) { + if (const auto superTypeUnit = compilationUnit->resolvedTypes.value( + object->inheritedTypeNameIndex)->compilationUnit()) { // We have a non-C++ super type, which could indicate we're a subtype of a TestCase if (testCaseType.isValid() && superTypeUnit->url() == testCaseType.sourceUrl()) result.isTestCase = true; -- cgit v1.2.3 From d552cd3f50efb9b67c7be88009392d601d3c6682 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 3 Apr 2020 14:35:11 +0200 Subject: Add qmltypes for Qt.test.qtestroot Somehow this was missed when moving to static type registration. Change-Id: I33f0567449f7bce62b0cb71b9d4f0862ed801e59 Reviewed-by: Fabian Kosmale --- src/qmltest/qmldir | 2 + src/qmltest/qmltest.pro | 14 +++++- src/qmltest/quicktest.cpp | 53 +--------------------- src/qmltest/quicktest_p.h | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 52 deletions(-) create mode 100644 src/qmltest/qmldir create mode 100644 src/qmltest/quicktest_p.h (limited to 'src/qmltest') diff --git a/src/qmltest/qmldir b/src/qmltest/qmldir new file mode 100644 index 0000000000..5e9d5e2c95 --- /dev/null +++ b/src/qmltest/qmldir @@ -0,0 +1,2 @@ +module Qt.test.qtestroot +typeinfo plugins.qmltypes diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro index 6864203ba4..c2e8068fc6 100644 --- a/src/qmltest/qmltest.pro +++ b/src/qmltest/qmltest.pro @@ -22,6 +22,7 @@ SOURCES += \ HEADERS += \ $$PWD/quicktestglobal.h \ $$PWD/quicktest.h \ + $$PWD/quicktest_p.h \ $$PWD/quicktestresult_p.h \ $$PWD/qtestoptions_p.h @@ -29,4 +30,15 @@ qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING load(qt_module) -CONFIG += metatypes install_metatypes +QMLTYPES_FILENAME = plugins.qmltypes +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/Qt/test/qtestroot +QML_IMPORT_NAME = Qt.test.qtestroot +QML_IMPORT_VERSION = 1.0 +CONFIG += qmltypes install_qmltypes install_metatypes + +# Install qmldir +qmldir.files = $$PWD/qmldir +qmldir.path = $$QMLTYPES_INSTALL_DIR + +prefix_build: INSTALLS += qmldir +else: COPIES += qmldir diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index 443496c9bc..cfc9221b20 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "quicktest.h" +#include "quicktest_p.h" #include "quicktestresult_p.h" #include #include "qtestoptions_p.h" @@ -133,53 +133,6 @@ bool QQuickTest::qWaitForItemPolished(const QQuickItem *item, int timeout) return QTest::qWaitFor([&]() { return !QQuickItemPrivate::get(item)->polishScheduled; }, timeout); } -class QTestRootObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) - Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged) - Q_PROPERTY(QObject *defined READ defined) -public: - QTestRootObject(QObject *parent = nullptr) - : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) { - m_defined = new QQmlPropertyMap(this); -#if defined(QT_OPENGL_ES_2_ANGLE) - m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true)); -#endif - } - - static QTestRootObject *instance() { - static QPointer object = new QTestRootObject; - if (!object) { - // QTestRootObject was deleted when previous test ended, create a new one - object = new QTestRootObject; - } - return object; - } - - bool hasQuit:1; - bool hasTestCase() const { return m_hasTestCase; } - void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); } - - bool windowShown() const { return m_windowShown; } - void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); } - QQmlPropertyMap *defined() const { return m_defined; } - - void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; } - -Q_SIGNALS: - void windowShownChanged(); - void hasTestCaseChanged(); - -private Q_SLOTS: - void quit() { hasQuit = true; } - -private: - bool m_windowShown : 1; - bool m_hasTestCase :1; - QQmlPropertyMap *m_defined; -}; - static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine) { Q_UNUSED(engine); @@ -556,7 +509,7 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch qputenv("QT_QTESTLIB_RUNNING", "1"); - // Register the test object + // Register the custom factory function qmlRegisterSingletonType("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject); QSet commandLineTestFunctions(QTest::testFunctions.cbegin(), QTest::testFunctions.cend()); @@ -688,5 +641,3 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch } QT_END_NAMESPACE - -#include "quicktest.moc" diff --git a/src/qmltest/quicktest_p.h b/src/qmltest/quicktest_p.h new file mode 100644 index 0000000000..50fc3be050 --- /dev/null +++ b/src/qmltest/quicktest_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUICKTEST_P_H +#define QUICKTEST_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QTestRootObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) + Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged) + Q_PROPERTY(QObject *defined READ defined) + QML_SINGLETON + QML_ELEMENT + +public: + QTestRootObject(QObject *parent = nullptr) + : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) { + m_defined = new QQmlPropertyMap(this); +#if defined(QT_OPENGL_ES_2_ANGLE) + m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true)); +#endif + } + + static QTestRootObject *instance() { + static QPointer object = new QTestRootObject; + if (!object) { + // QTestRootObject was deleted when previous test ended, create a new one + object = new QTestRootObject; + } + return object; + } + + bool hasQuit:1; + bool hasTestCase() const { return m_hasTestCase; } + void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); } + + bool windowShown() const { return m_windowShown; } + void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); } + QQmlPropertyMap *defined() const { return m_defined; } + + void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; } + +Q_SIGNALS: + void windowShownChanged(); + void hasTestCaseChanged(); + +private Q_SLOTS: + void quit() { hasQuit = true; } + +private: + bool m_windowShown : 1; + bool m_hasTestCase :1; + QQmlPropertyMap *m_defined; +}; + +QT_END_NAMESPACE + +#endif // QUICKTEST_P_H -- cgit v1.2.3