diff options
141 files changed, 3694 insertions, 1885 deletions
diff --git a/.qmake.conf b/.qmake.conf index 81caa27c53..7b49e2c3f9 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += warning_clean -MODULE_VERSION = 5.12.0 +MODULE_VERSION = 5.13.0 diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h index c79b0663c8..4dfd051797 100644 --- a/src/3rdparty/masm/assembler/LinkBuffer.h +++ b/src/3rdparty/masm/assembler/LinkBuffer.h @@ -228,6 +228,8 @@ public: return m_size; } + inline void makeExecutable(); + private: template <typename T> T applyOffset(T src) { @@ -353,6 +355,11 @@ inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performF ASSERT(m_size <= INT_MAX); MacroAssembler::cacheFlush(code(), m_size); +} + +template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator> +inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable() +{ ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size)); } @@ -389,6 +396,7 @@ public: } inline void performFinalization(); + inline void makeExecutable(); inline void linkCode(void* ownerUID, JITCompilationEffort); @@ -421,6 +429,11 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization() #endif MacroAssembler::cacheFlush(code(), m_size); +} + +template <typename MacroAssembler> +inline void BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable() +{ ExecutableAllocator::makeExecutable(code(), m_initialSize); } diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h index 156b24b4e8..a439c53827 100644 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h @@ -82,6 +82,7 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> { inline bool isManaged() const { return true; } + void *exceptionHandler() { return m_allocation->exceptionHandler(); } void *start() { return m_allocation->start(); } size_t sizeInBytes() { return m_size; } diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp index 9a9ab581e8..73c919dd90 100644 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp @@ -33,6 +33,8 @@ #include "Yarr.h" #include "YarrCanonicalize.h" +#include <private/qv4functiontable_p.h> + #if ENABLE(YARR_JIT) using namespace WTF; @@ -3529,17 +3531,30 @@ public: m_backtrackingState.linkDataLabels(linkBuffer); + CodeRef codeRef; if (compileMode == MatchOnly) { - if (m_charSize == Char8) - codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 8-bit regular expression")); - else - codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 16-bit regular expression")); + if (m_charSize == Char8) { + codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", + "Match-only 8-bit regular expression"); + codeBlock.set8BitCodeMatchOnly(codeRef); + } else { + codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", + "Match-only 16-bit regular expression"); + codeBlock.set16BitCodeMatchOnly(codeRef); + } } else { - if (m_charSize == Char8) - codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression")); - else - codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression")); + if (m_charSize == Char8) { + codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression"); + codeBlock.set8BitCode(codeRef); + } else { + codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression"); + codeBlock.set16BitCode(codeRef); + } } + QV4::generateFunctionTable(nullptr, &codeRef); + + linkBuffer.makeExecutable(); + if (m_failureReason) codeBlock.setFallBackWithFailureReason(*m_failureReason); } @@ -3587,6 +3602,15 @@ private: BacktrackingState m_backtrackingState; }; +void YarrCodeBlock::replaceCodeRef(MacroAssemblerCodeRef &target, + const MacroAssemblerCodeRef &source) +{ + if (!!target && target.code().executableAddress() != source.code().executableAddress()) + QV4::destroyFunctionTable(nullptr, &target); + + target = source; +} + static void dumpCompileFailure(JITFailureReason failure) { switch (failure) { diff --git a/src/3rdparty/masm/yarr/YarrJIT.h b/src/3rdparty/masm/yarr/YarrJIT.h index 8b6b3a7577..35a0690f6e 100644 --- a/src/3rdparty/masm/yarr/YarrJIT.h +++ b/src/3rdparty/masm/yarr/YarrJIT.h @@ -82,19 +82,28 @@ class YarrCodeBlock { public: YarrCodeBlock() = default; + ~YarrCodeBlock() { clear(); } + + static void replaceCodeRef(MacroAssemblerCodeRef &target, const MacroAssemblerCodeRef &source); void setFallBackWithFailureReason(JITFailureReason failureReason) { m_failureReason = failureReason; } std::optional<JITFailureReason> failureReason() { return m_failureReason; } bool has8BitCode() { return m_ref8.size(); } bool has16BitCode() { return m_ref16.size(); } - void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; } - void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; } + void set8BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref8, ref); } + void set16BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref16, ref); } bool has8BitCodeMatchOnly() { return m_matchOnly8.size(); } bool has16BitCodeMatchOnly() { return m_matchOnly16.size(); } - void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; } - void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; } + void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) + { + replaceCodeRef(m_matchOnly8, matchOnly); + } + void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) + { + replaceCodeRef(m_matchOnly16, matchOnly); + } #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; } @@ -190,10 +199,10 @@ public: void clear() { - m_ref8 = MacroAssemblerCodeRef(); - m_ref16 = MacroAssemblerCodeRef(); - m_matchOnly8 = MacroAssemblerCodeRef(); - m_matchOnly16 = MacroAssemblerCodeRef(); + replaceCodeRef(m_ref8, MacroAssemblerCodeRef()); + replaceCodeRef(m_ref16, MacroAssemblerCodeRef()); + replaceCodeRef(m_matchOnly8, MacroAssemblerCodeRef()); + replaceCodeRef(m_matchOnly16, MacroAssemblerCodeRef()); m_failureReason = std::nullopt; } diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index e7e8d130bb..3c34d8e45a 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -399,23 +399,23 @@ static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const if (from_version != *r->d()->version) V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(*r->d()->version)); - Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine)); - ScopedObject p(scope, databaseData(scope.engine)->queryProto.value()); - w->setPrototypeUnchecked(p.getPointer()); - w->d()->type = Heap::QQmlSqlDatabaseWrapper::Query; - *w->d()->database = db; - *w->d()->version = *r->d()->version; - bool ok = true; if (!!callback) { + Scoped<QQmlSqlDatabaseWrapper> query(scope, QQmlSqlDatabaseWrapper::create(scope.engine)); + ScopedObject p(scope, databaseData(scope.engine)->queryProto.value()); + query->setPrototypeUnchecked(p.getPointer()); + query->d()->type = Heap::QQmlSqlDatabaseWrapper::Query; + *query->d()->database = db; + *query->d()->version = *r->d()->version; + ok = false; db.transaction(); JSCallData jsCall(scope, 1); *jsCall->thisObject = scope.engine->globalObject; - jsCall->args[0] = w; + jsCall->args[0] = query; - TransactionRollback rollbackOnException(&db, &w->d()->inTransaction); + TransactionRollback rollbackOnException(&db, &query->d()->inTransaction); callback->call(jsCall); rollbackOnException.clear(); if (!db.commit()) { @@ -427,12 +427,18 @@ static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const } if (ok) { + Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine)); + ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value()); + w->setPrototypeUnchecked(p.getPointer()); + w->d()->type = Heap::QQmlSqlDatabaseWrapper::Database; + *w->d()->database = db; *w->d()->version = to_version; #if QT_CONFIG(settings) const QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(scope.engine->qmlEngine()); QSettings ini(enginePrivate->offlineStorageDatabaseDirectory() + db.connectionName() + QLatin1String(".ini"), QSettings::IniFormat); ini.setValue(QLatin1String("Version"), to_version); #endif + RETURN_RESULT(w.asReturnedValue()); } RETURN_UNDEFINED(); @@ -599,7 +605,8 @@ This data can be used by application tools. \section3 db.changeVersion(from, to, callback(tx)) -This method allows you to perform a \e{Scheme Upgrade}. +This method allows you to perform a \e{Scheme Upgrade}. If it succeeds it returns a new +database object of version \e to. Otherwise it returns \e undefined. If the current version of \e db is not \e from, then an exception is thrown. diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 266e3111bb..fd61c042ca 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -521,6 +521,75 @@ Item { } /*! + \since 5.13 + \qmlmethod bool TestCase::isPolishScheduled(object item) + + Returns \c true if \l {QQuickItem::}{updatePolish()} has not been called + on \a item since the last call to \l {QQuickItem::}{polish()}, + otherwise returns \c false. + + When assigning values to properties in QML, any layouting the item + must do as a result of the assignment might not take effect immediately, + but can instead be postponed until the item is polished. For these cases, + you can use this function to ensure that the item has been polished + before the execution of the test continues. For example: + + \code + verify(isPolishScheduled(item)) + verify(waitForItemPolished(item)) + \endcode + + Without the call to \c isPolishScheduled() above, the + call to \c waitForItemPolished() might see that no polish + was scheduled and therefore pass instantly, assuming that + the item had already been polished. This function + makes it obvious why an item wasn't polished and allows tests to + fail early under such circumstances. + + \sa waitForItemPolished(), QQuickItem::polish(), QQuickItem::updatePolish() + */ + function isPolishScheduled(item) { + if (!item || typeof item !== "object") { + qtest_results.fail("Argument must be a valid Item; actual type is " + typeof item, + util.callerFile(), util.callerLine()) + throw new Error("QtQuickTest::fail") + } + + return qtest_results.isPolishScheduled(item) + } + + /*! + \since 5.13 + \qmlmethod bool waitForItemPolished(object item, int timeout = 5000) + + Waits for \a timeout milliseconds or until + \l {QQuickItem::}{updatePolish()} has been called on \a item. + + Returns \c true if \c updatePolish() was called on \a item within + \a timeout milliseconds, otherwise returns \c false. + + \sa isPolishScheduled(), QQuickItem::polish(), QQuickItem::updatePolish() + */ + function waitForItemPolished(item, timeout) { + if (!item || typeof item !== "object") { + qtest_results.fail("First argument must be a valid Item; actual type is " + typeof item, + util.callerFile(), util.callerLine()) + throw new Error("QtQuickTest::fail") + } + + if (timeout !== undefined && typeof(timeout) != "number") { + qtest_results.fail("Second argument must be a number; actual type is " + typeof timeout, + util.callerFile(), util.callerLine()) + throw new Error("QtQuickTest::fail") + } + + if (!timeout) + timeout = 5000 + + return qtest_results.waitForItemPolished(item, timeout) + } + + /*! \since 5.9 \qmlmethod object TestCase::createTemporaryQmlObject(string qml, object parent, string filePath) diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 2421e8c1ea..84fd66b114 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -2510,8 +2510,6 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO f->location = compiledFunction->location; f->nameIndex = compiledFunction->nameIndex; - const QString name = unit->stringAtInternal(compiledFunction->nameIndex); - f->formals.allocate(pool, int(compiledFunction->nFormals)); const quint32_le *formalNameIdx = compiledFunction->formalsTable(); for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx) diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index f570af4819..cdba21604d 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2563,9 +2563,6 @@ bool Codegen::visit(ObjectPattern *ast) TailCallBlocker blockTailCalls(this); - QVector<QPair<Reference, ObjectPropertyValue>> computedProperties; - QMap<QString, ObjectPropertyValue> valueMap; - RegisterScope scope(this); QStringList members; diff --git a/src/qml/configure.json b/src/qml/configure.json index 878ec0119b..c7b145f46f 100644 --- a/src/qml/configure.json +++ b/src/qml/configure.json @@ -8,6 +8,7 @@ "commandline": { "options": { "qml-network": "boolean", + "qml-tracing": "boolean", "qml-debug": "boolean" } }, @@ -38,6 +39,13 @@ "condition": "features.network", "output": [ "publicFeature" ] }, + "qml-tracing": { + "label": "QML tracing JIT support", + "purpose": "Provides a JIT that uses trace information generated by the interpreter.", + "section": "QML", + "output": [ "publicFeature" ], + "autoDetect": false + }, "qml-debug": { "label": "QML debugging and profiling support", "purpose": "Provides infrastructure and plugins for debugging and profiling.", @@ -131,6 +139,7 @@ "entries": [ "qml-network", "qml-debug", + "qml-tracing", "qml-sequence-object", "qml-list-model", "qml-xml-http-request", diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 8ebbd28737..171b2b6a11 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -284,6 +284,9 @@ In particular, QML currently supports: \li \c {std::vector<bool>} \endlist +and all registered QList, QVector, QQueue, QStack, QSet, QLinkedList, std::list, +std::vector that contain a type marked with \l Q_DECLARE_METATYPE. + These sequence types are implemented directly in terms of the underlying C++ sequence. There are two ways in which such sequences can be exposed to QML: as a Q_PROPERTY of the given sequence type; or as the return type of a diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index 2bb1fcac61..15e8e4c52c 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc @@ -540,6 +540,58 @@ Internally, however, the rectangle can correctly set its \c color property and refer to the actual defined property rather than the alias. +\section4 Property Aliases and Types + +Property aliases cannot have explicit type specifications. The type of a +property alias is the \e declared type of the property or object it refers to. +Therefore, if you create an alias to an object referenced via id with extra +properties declared inline, the extra properties won't be accessible through +the alias: + +\code +// MyItem.qml +Item { + property alias inner: innerItem + + Item { + id: innerItem + property int extraProperty + } +} +\code + +You cannot initialize \a inner.extraProperty from outside of this component, as +inner is only an \a Item: + +\code +// main.qml +MyItem { + inner.extraProperty: 5 // fails +} +\code + +However, if you extract the inner object into a separate component with a +dedicated .qml file, you can instantiate that component instead and have all +its properties available through the alias: + +\code +// MainItem.qml +Item { + // Now you can access inner.extraProperty, as inner is now an ExtraItem + property alias inner: innerItem + + ExtraItem { + id: innerItem + } +} + +// ExtraItem.qml +Item { + property int extraProperty +} +\code + + \section3 Default Properties An object definition can have a single \e default property. A default property diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp index b302ac6403..bc17be229d 100644 --- a/src/qml/jit/qv4assemblercommon.cpp +++ b/src/qml/jit/qv4assemblercommon.cpp @@ -43,6 +43,7 @@ #include "qv4engine_p.h" #include "qv4assemblercommon_p.h" #include <private/qv4function_p.h> +#include <private/qv4functiontable_p.h> #include <private/qv4runtime_p.h> #include <assembler/MacroAssemblerCodeRef.h> @@ -112,17 +113,6 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput, qDebug("%s", processedOutput.constData()); } -static QByteArray functionName(Function *function) -{ - QByteArray name = function->name()->toQString().toUtf8(); - if (name.isEmpty()) { - name = QByteArray::number(reinterpret_cast<quintptr>(function), 16); - name.prepend("QV4::Function(0x"); - name.append(')'); - } - return name; -} - JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon() {} @@ -147,7 +137,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind) buf.open(QIODevice::WriteOnly); WTF::setDataFile(new QIODevicePrintStream(&buf)); - QByteArray name = functionName(function); + // We use debugAddress here because it's actually for debugging and hidden behind an + // environment variable. + const QByteArray name = Function::prettyName(function, linkBuffer.debugAddress()).toUtf8(); codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, "function %s", name.constData()); WTF::setDataFile(stderr); @@ -159,31 +151,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind) function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef); function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress()); - // This implements writing of JIT'd addresses so that perf can find the - // symbol names. - // - // Perf expects the mapping to be in a certain place and have certain - // content, for more information, see: - // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt - static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP"); - if (Q_UNLIKELY(doProfile)) { - static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map") - .arg(QCoreApplication::applicationPid())); - static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly); - if (!isOpen) { - qWarning("QV4::JIT::Assembler: Cannot write perf map file."); - doProfile = false; - } else { - perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>( - codeRef.code().executableAddress()), 16)); - perfMapFile.putChar(' '); - perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16)); - perfMapFile.putChar(' '); - perfMapFile.write(functionName(function)); - perfMapFile.putChar('\n'); - perfMapFile.flush(); - } - } + generateFunctionTable(function, &codeRef); + + linkBuffer.makeExecutable(); } void PlatformAssemblerCommon::prepareCallWithArgCount(int argc) diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index 5ec55b960b..a24ee0a188 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -147,7 +147,8 @@ HEADERS += \ $$PWD/qv4value_p.h \ $$PWD/qv4string_p.h \ $$PWD/qv4util_p.h \ - $$PWD/qv4value_p.h + $$PWD/qv4value_p.h \ + $$PWD/qv4functiontable_p.h SOURCES += \ $$PWD/qv4engine.cpp \ @@ -156,6 +157,23 @@ SOURCES += \ $$PWD/qv4value.cpp \ $$PWD/qv4executableallocator.cpp +qmldevtools_build { + SOURCES += \ + $$PWD/qv4functiontable_noop.cpp +} else:win32 { + !winrt:equals(QT_ARCH, x86_64) { + SOURCES += \ + $$PWD/qv4functiontable_win64.cpp + } else { + SOURCES += \ + $$PWD/qv4functiontable_noop.cpp + } +} else { + SOURCES += \ + $$PWD/qv4functiontable_unix.cpp +} + + valgrind { DEFINES += V4_USE_VALGRIND } diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index a13fb37a52..21c6a5d06b 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -670,17 +670,17 @@ static inline QString ToTimeString(double t) static inline QString ToLocaleString(double t) { - return ToDateTime(t, Qt::LocalTime).toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).toString(Qt::DefaultLocaleShortDate); } static inline QString ToLocaleDateString(double t) { - return ToDateTime(t, Qt::LocalTime).date().toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).date().toString(Qt::DefaultLocaleShortDate); } static inline QString ToLocaleTimeString(double t) { - return ToDateTime(t, Qt::LocalTime).time().toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).time().toString(Qt::DefaultLocaleShortDate); } static double getLocalTZA() diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 57a364b205..ff7bcb63fa 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1597,6 +1597,22 @@ static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVaria return a.asReturnedValue(); } +// Converts a QSequentialIterable to JS. +// The result is a new Array object with length equal to the length +// of the QSequentialIterable, and the elements being the QSequentialIterable's +// elements converted to JS, recursively. +static QV4::ReturnedValue sequentialIterableToJS(QV4::ExecutionEngine *v4, const QSequentialIterable &lst) +{ + QV4::Scope scope(v4); + QV4::ScopedArrayObject a(scope, v4->newArrayObject()); + a->arrayReserve(lst.size()); + QV4::ScopedValue v(scope); + for (int i = 0; i < lst.size(); i++) + a->arrayPut(i, (v = variantToJS(v4, lst.at(i)))); + a->setArrayLengthUnchecked(lst.size()); + return a.asReturnedValue(); +} + // Converts a QVariantMap to JS. // The result is a new Object object with property names being // the keys of the QVariantMap, and values being the values of @@ -1701,9 +1717,18 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return QV4::Encode::null(); } QMetaType mt(type); - if (mt.flags() & QMetaType::IsGadget) { - Q_ASSERT(mt.metaObject()); - return QV4::QQmlValueTypeWrapper::create(this, QVariant(type, data), mt.metaObject(), type); + if (auto metaObject = mt.metaObject()) { + auto flags = mt.flags(); + if (flags & QMetaType::IsGadget) { + return QV4::QQmlValueTypeWrapper::create(this, QVariant(type, data), metaObject, type); + } else if (flags & QMetaType::PointerToQObject) { + return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(data)); + } + } + if (QMetaType::hasRegisteredConverterFunction(type, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) { + auto v = QVariant(type, data); + QSequentialIterable lst = v.value<QSequentialIterable>(); + return sequentialIterableToJS(this, lst); } // Fall back to wrapping in a QVariant. return QV4::Encode(newVariantObject(QVariant(type, data))); diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp index 6f04a712e6..c836d121e3 100644 --- a/src/qml/jsruntime/qv4executableallocator.cpp +++ b/src/qml/jsruntime/qv4executableallocator.cpp @@ -38,17 +38,23 @@ ****************************************************************************/ #include "qv4executableallocator_p.h" +#include "qv4functiontable_p.h" #include <wtf/StdLibExtras.h> #include <wtf/PageAllocation.h> using namespace QV4; -void *ExecutableAllocator::Allocation::start() const +void *ExecutableAllocator::Allocation::exceptionHandler() const { return reinterpret_cast<void*>(addr); } +void *ExecutableAllocator::Allocation::start() const +{ + return reinterpret_cast<void*>(addr + exceptionHandlerSize()); +} + void ExecutableAllocator::Allocation::deallocate(ExecutableAllocator *allocator) { if (isValid()) @@ -162,7 +168,7 @@ ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size) Allocation *allocation = nullptr; // Code is best aligned to 16-byte boundaries. - size = WTF::roundUpToMultipleOf(16, size); + size = WTF::roundUpToMultipleOf(16, size + exceptionHandlerSize()); QMultiMap<size_t, Allocation*>::Iterator it = freeAllocations.lowerBound(size); if (it != freeAllocations.end()) { diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h index 375c9a365f..013c6d7120 100644 --- a/src/qml/jsruntime/qv4executableallocator_p.h +++ b/src/qml/jsruntime/qv4executableallocator_p.h @@ -86,6 +86,7 @@ public: , free(true) {} + void *exceptionHandler() const; void *start() const; void invalidate() { addr = 0; } bool isValid() const { return addr != 0; } diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 941c37de5b..2a82d96f1d 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -46,6 +46,7 @@ #include "qv4lookup_p.h" #include <private/qv4mm_p.h> #include <private/qv4identifiertable_p.h> +#include <private/qv4functiontable_p.h> #include <assembler/MacroAssemblerCodeRef.h> #include <private/qv4vme_moth_p.h> #include <private/qqmlglobal_p.h> @@ -98,7 +99,10 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, Function::~Function() { - delete codeRef; + if (codeRef) { + destroyFunctionTable(this, codeRef); + delete codeRef; + } } void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters) @@ -145,6 +149,17 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr nFormals = parameters.size(); } +QString Function::prettyName(const Function *function, const void *code) +{ + QString prettyName = function ? function->name()->toQString() : QString(); + if (prettyName.isEmpty()) { + prettyName = QString::number(reinterpret_cast<quintptr>(code), 16); + prettyName.prepend(QLatin1String("QV4::Function(0x")); + prettyName.append(QLatin1Char(')')); + } + return prettyName; +} + QQmlSourceLocation Function::sourceLocation() const { return QQmlSourceLocation(sourceFile(), compiledFunction->location.line, compiledFunction->location.column); diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 029dd7786b..86343ea061 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -89,9 +89,12 @@ struct Q_QML_EXPORT Function { // used when dynamically assigning signal handlers (QQmlConnection) void updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters); - inline Heap::String *name() { + inline Heap::String *name() const { return compilationUnit->runtimeStrings[compiledFunction->nameIndex]; } + + static QString prettyName(const Function *function, const void *address); + inline QString sourceFile() const { return compilationUnit->fileName(); } inline QUrl finalUrl() const { return compilationUnit->finalUrl(); } diff --git a/src/qml/jsruntime/qv4functiontable_noop.cpp b/src/qml/jsruntime/qv4functiontable_noop.cpp new file mode 100644 index 0000000000..31c198eb00 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_noop.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); +} + +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); +} + +size_t exceptionHandlerSize() +{ + return 0; +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4functiontable_p.h b/src/qml/jsruntime/qv4functiontable_p.h new file mode 100644 index 0000000000..69e3d2bdd5 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QV4FUNCTIONTABLE_P_H +#define QV4FUNCTIONTABLE_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 "qv4global_p.h" + +namespace JSC { +class MacroAssemblerCodeRef; +} + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +struct Function; + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef); +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef); + +size_t exceptionHandlerSize(); + +} + +QT_END_NAMESPACE + +#endif // QV4FUNCTIONTABLE_P_H diff --git a/src/qml/jsruntime/qv4functiontable_unix.cpp b/src/qml/jsruntime/qv4functiontable_unix.cpp new file mode 100644 index 0000000000..25b5c27161 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_unix.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" +#include "qv4function_p.h" + +#include <assembler/MacroAssemblerCodeRef.h> + +#include <QtCore/qfile.h> +#include <QtCore/qcoreapplication.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + // This implements writing of JIT'd addresses so that perf can find the + // symbol names. + // + // Perf expects the mapping to be in a certain place and have certain + // content, for more information, see: + // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt + static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP"); + if (Q_UNLIKELY(doProfile)) { + static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map") + .arg(QCoreApplication::applicationPid())); + static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly); + if (!isOpen) { + qWarning("QV4::JIT::Assembler: Cannot write perf map file."); + doProfile = false; + } else { + const void *address = codeRef->code().executableAddress(); + perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(address), 16)); + perfMapFile.putChar(' '); + perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef->size()), 16)); + perfMapFile.putChar(' '); + perfMapFile.write(Function::prettyName(function, address).toUtf8()); + perfMapFile.putChar('\n'); + perfMapFile.flush(); + } + } +} + +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); + + // It's not advisable to remove things from the perf map file, as it's primarily used to analyze + // a trace after the application has terminated. We want to know about all functions that were + // ever jitted then. If the memory ranges overlap, we will have a problem when analyzing the + // trace. The JIT should try to avoid this. +} + +size_t exceptionHandlerSize() +{ + return 0; +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4functiontable_win64.cpp b/src/qml/jsruntime/qv4functiontable_win64.cpp new file mode 100644 index 0000000000..bc5b24f6cd --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_win64.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" + +#include <assembler/MacroAssemblerCodeRef.h> + +#include <QtCore/qdebug.h> + +#include <Windows.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +enum UnwindOpcode: UINT8 +{ + UWOP_PUSH_NONVOL = 0, /* info == register number */ + UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */ + UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */ + UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */ + UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */ + UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */ + UWOP_SAVE_XMM128 = 8, /* info == XMM reg number, offset in next slot */ + UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */ + UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */ +}; + +enum Register : UINT8 +{ + RAX = 0, + RCX, + RDX, + RBX, + RSP, + RBP, + RSI, + RDI, + NONE = 15 +}; + +struct UnwindCode +{ + UnwindCode(UINT8 offset, UnwindOpcode operation, Register info) + : offset(offset), operation(operation), info(info) + {} + + UINT8 offset; + UINT8 operation: 4; + UINT8 info: 4; +}; + +struct UnwindInfo +{ + UINT8 Version : 3; + UINT8 Flags : 5; + UINT8 SizeOfProlog; + UINT8 CountOfUnwindCodes; + UINT8 FrameRegister : 4; + UINT8 FrameRegisterOffset : 4; + UnwindCode UnwindCodes[2]; +}; + +struct ExceptionHandlerRecord +{ + RUNTIME_FUNCTION handler; + UnwindInfo info; +}; + +void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef) +{ + ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>( + codeRef->executableMemory()->exceptionHandler()); + + record->info.Version = 1; + record->info.Flags = 0; + record->info.SizeOfProlog = 4; + record->info.CountOfUnwindCodes = 2; + record->info.FrameRegister = RBP; + record->info.FrameRegisterOffset = 0; + + // Push frame pointer + record->info.UnwindCodes[1] = UnwindCode(1, UWOP_PUSH_NONVOL, RBP); + // Set frame pointer from stack pointer + record->info.UnwindCodes[0] = UnwindCode(4, UWOP_SET_FPREG, NONE); + + const quintptr codeStart = quintptr(codeRef->code().executableAddress()); + const quintptr codeSize = codeRef->size(); + + record->handler.BeginAddress = DWORD(codeStart - quintptr(record)); + record->handler.EndAddress = DWORD(codeStart + codeSize - quintptr(record)); + record->handler.UnwindData = offsetof(ExceptionHandlerRecord, info); + + if (!RtlAddFunctionTable(&record->handler, 1, DWORD64(record))) { + const unsigned int errorCode = GetLastError(); + qWarning() << "Failed to install win64 unwind hook. Error code:" << errorCode; + } +} + +void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef) +{ + ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>( + codeRef->executableMemory()->exceptionHandler()); + if (!RtlDeleteFunctionTable(&record->handler)) { + const unsigned int errorCode = GetLastError(); + qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode; + } +} + +size_t exceptionHandlerSize() +{ + return sizeof(ExceptionHandlerRecord); +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index ef0877dbd0..e4d8bcaafc 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -138,11 +138,14 @@ ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const V const VariantObject *o = thisObject->as<QV4::VariantObject>(); if (!o) RETURN_UNDEFINED(); - QString result = o->d()->data().toString(); - if (result.isEmpty() && !o->d()->data().canConvert(QVariant::String)) { - result = QLatin1String("QVariant(") - + QLatin1String(o->d()->data().typeName()) - + QLatin1Char(')'); + const QVariant variant = o->d()->data(); + QString result = variant.toString(); + if (result.isEmpty() && !variant.canConvert(QVariant::String)) { + QDebug dbg(&result); + dbg << variant; + // QDebug appends a space, we're not interested in continuing the stream so we chop it off. + // Can't use nospace() because it would affect the debug-stream operator of the variant. + result.chop(1); } return Encode(v4->newString(result)); } diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri index adab4ef9a2..2c0175c94b 100644 --- a/src/qml/parser/parser.pri +++ b/src/qml/parser/parser.pri @@ -8,7 +8,8 @@ HEADERS += \ $$PWD/qqmljsglobal_p.h \ $$PWD/qqmljskeywords_p.h \ $$PWD/qqmljsengine_p.h \ - $$PWD/qqmljsglobal_p.h + $$PWD/qqmljsglobal_p.h \ + $$PWD/qqmljssourcelocation_p.h SOURCES += \ $$PWD/qqmljsast.cpp \ diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h index 996264db59..7795e0ce71 100644 --- a/src/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/parser/qqmljsastfwd_p.h @@ -41,6 +41,7 @@ #define QQMLJSAST_FWD_P_H #include "qqmljsglobal_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qglobal.h> @@ -59,27 +60,6 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { namespace AST { -class SourceLocation -{ -public: - explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) - : offset(offset), length(length), - startLine(line), startColumn(column) - { } - - bool isValid() const { return length != 0; } - - quint32 begin() const { return offset; } - quint32 end() const { return offset + length; } - -// attributes - // ### encode - quint32 offset; - quint32 length; - quint32 startLine; - quint32 startColumn; -}; - class Visitor; class Node; class ExpressionNode; diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h index 1de907d296..07b5026eb9 100644 --- a/src/qml/parser/qqmljsengine_p.h +++ b/src/qml/parser/qqmljsengine_p.h @@ -52,8 +52,8 @@ // #include "qqmljsglobal_p.h" -#include "qqmljsastfwd_p.h" #include "qqmljsmemorypool_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qstring.h> #include <QtCore/qset.h> @@ -95,7 +95,7 @@ public: class QML_PARSER_EXPORT DiagnosticMessage { public: - enum Kind { Warning, Error }; + enum Kind { Hint, Warning, Error }; DiagnosticMessage() {} diff --git a/src/qml/parser/qqmljssourcelocation_p.h b/src/qml/parser/qqmljssourcelocation_p.h new file mode 100644 index 0000000000..dc307ba168 --- /dev/null +++ b/src/qml/parser/qqmljssourcelocation_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLJSSOURCELOCATION_P_H +#define QQMLJSSOURCELOCATION_P_H + +#include "qqmljsglobal_p.h" + +#include <QtCore/qglobal.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. +// + +QT_QML_BEGIN_NAMESPACE + +namespace QQmlJS { namespace AST { + +class SourceLocation +{ +public: + explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + : offset(offset), length(length), + startLine(line), startColumn(column) + { } + + bool isValid() const { return length != 0; } + + quint32 begin() const { return offset; } + quint32 end() const { return offset + length; } + +// attributes + // ### encode + quint32 offset; + quint32 length; + quint32 startLine; + quint32 startColumn; +}; + +} } // namespace AST + +QT_QML_END_NAMESPACE + +#endif diff --git a/src/qml/qml.pro b/src/qml/qml.pro index db59140f06..94717a8f43 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -73,6 +73,7 @@ include(jsruntime/jsruntime.pri) include(jit/jit.pri) include(qml/qml.pri) include(debugger/debugger.pri) +include(qmldirparser/qmldirparser.pri) qtConfig(qml-animation) { include(animations/animations.pri) } diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index 6d69294c17..ca13ce9211 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -18,7 +18,6 @@ SOURCES += \ $$PWD/qqmlparserstatus.cpp \ $$PWD/qqmltypeloader.cpp \ $$PWD/qqmlinfo.cpp \ - $$PWD/qqmlerror.cpp \ $$PWD/qqmlvaluetype.cpp \ $$PWD/qqmlcleanup.cpp \ $$PWD/qqmlpropertycache.cpp \ @@ -44,7 +43,6 @@ SOURCES += \ $$PWD/qqmltypewrapper.cpp \ $$PWD/qqmlfileselector.cpp \ $$PWD/qqmlobjectcreator.cpp \ - $$PWD/qqmldirparser.cpp \ $$PWD/qqmldelayedcallqueue.cpp \ $$PWD/qqmlloggingcategory.cpp @@ -81,7 +79,6 @@ HEADERS += \ $$PWD/qqmllist.h \ $$PWD/qqmllist_p.h \ $$PWD/qqmldata_p.h \ - $$PWD/qqmlerror.h \ $$PWD/qqmlvaluetype_p.h \ $$PWD/qqmlcleanup_p.h \ $$PWD/qqmlpropertycache_p.h \ @@ -112,7 +109,6 @@ HEADERS += \ $$PWD/qqmlfileselector_p.h \ $$PWD/qqmlfileselector.h \ $$PWD/qqmlobjectcreator_p.h \ - $$PWD/qqmldirparser_p.h \ $$PWD/qqmldelayedcallqueue_p.h \ $$PWD/qqmlloggingcategory_p.h diff --git a/src/qml/qml/qqmlabstracturlinterceptor.h b/src/qml/qml/qqmlabstracturlinterceptor.h index 665b37fb3a..af231f51b2 100644 --- a/src/qml/qml/qqmlabstracturlinterceptor.h +++ b/src/qml/qml/qqmlabstracturlinterceptor.h @@ -55,8 +55,8 @@ public: UrlString = 0x1000 }; - QQmlAbstractUrlInterceptor() {} - virtual ~QQmlAbstractUrlInterceptor() {} + QQmlAbstractUrlInterceptor() = default; + virtual ~QQmlAbstractUrlInterceptor() = default; virtual QUrl intercept(const QUrl &path, DataType type) = 0; }; diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index e38f379eb0..024ec29a56 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -316,7 +316,7 @@ protected: break; default: if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) { - if (vtw->d()->valueType->typeId == pd->propType()) { + if (vtw->d()->valueType->metaType.id() == pd->propType()) { return vtw->write(m_target.data(), pd->coreIndex()); } } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 3caa6ec138..70e188dc1c 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -64,7 +64,6 @@ #include "qqmlproperty_p.h" #include "qqmlpropertycache_p.h" #include "qqmlmetatype_p.h" -#include "qqmldirparser_p.h" #include <private/qintrusivelist_p.h> #include <private/qrecyclepool_p.h> #include <private/qfieldlist_p.h> @@ -80,6 +79,7 @@ #include <private/qv8engine_p.h> #include <private/qjsengine_p.h> +#include <private/qqmldirparser_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index 0c1ffbf3a0..ac2629979f 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -46,6 +46,7 @@ #include "qqmlscriptstring_p.h" #include "qqmlbinding_p.h" #include <private/qv8engine_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtCore/qdebug.h> diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h index c2d20ef0a3..d2eb79c5c9 100644 --- a/src/qml/qml/qqmlextensioninterface.h +++ b/src/qml/qml/qqmlextensioninterface.h @@ -51,14 +51,14 @@ class QQmlEngine; class Q_QML_EXPORT QQmlTypesExtensionInterface { public: - virtual ~QQmlTypesExtensionInterface() {} + virtual ~QQmlTypesExtensionInterface() = default; virtual void registerTypes(const char *uri) = 0; }; class Q_QML_EXPORT QQmlExtensionInterface : public QQmlTypesExtensionInterface { public: - ~QQmlExtensionInterface() override {} + ~QQmlExtensionInterface() override = default; virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0; }; diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 302fdd56c4..818537560c 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -174,16 +174,6 @@ T qmlobject_cast(QObject *object) return 0; } -inline quint16 qmlSourceCoordinate(int n) -{ - return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0; -} - -inline int qmlSourceCoordinate(quint16 n) -{ - return (n == 0) ? -1 : static_cast<int>(n); -} - #define IS_SIGNAL_CONNECTED(Sender, SenderType, Name, Arguments) \ do { \ QObject *sender = (Sender); \ diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 11806a89a0..083917d20f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1087,13 +1087,6 @@ QString QQmlType::noCreationReason() const return d->extraData.cd->noCreationReason; } -int QQmlType::createSize() const -{ - if (!d || d->regType != CppType) - return 0; - return d->extraData.cd->allocationSize; -} - bool QQmlType::isCreatable() const { return d && d->regType == CppType && d->extraData.cd->newFunc; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index b3ca6acd64..2a45ddb4bb 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -196,8 +196,6 @@ public: typedef void (*CreateFunc)(void *); CreateFunc createFunction() const; - int createSize() const; - QQmlCustomParser *customParser() const; bool isCreatable() const; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 9df502f778..fc48957bcb 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1891,8 +1891,6 @@ bool QQmlTypeLoader::fileExists(const QString &path, const QString &file) if (!fileSet) return false; - QString absoluteFilePath; - bool *value = fileSet->object(file); if (value) { return *value; diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 2b21591017..e92488f9f6 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -191,7 +191,6 @@ void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject) : gadgetPtr(QMetaType::create(typeId)) - , typeId(typeId) , metaType(typeId) { QObjectPrivate *op = QObjectPrivate::get(this); @@ -230,12 +229,12 @@ void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags fl QVariant QQmlValueType::value() { Q_ASSERT(gadgetPtr); - return QVariant(typeId, gadgetPtr); + return QVariant(metaType.id(), gadgetPtr); } void QQmlValueType::setValue(const QVariant &value) { - Q_ASSERT(typeId == value.userType()); + Q_ASSERT(metaType.id() == value.userType()); metaType.destruct(gadgetPtr); metaType.construct(gadgetPtr, value.constData()); } diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 4ea71e8955..89f1b71d61 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -84,7 +84,6 @@ private: void *gadgetPtr; public: - int typeId; QMetaType metaType; }; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index b503d75a47..9ce1c82f09 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -105,7 +105,7 @@ void Heap::QQmlValueTypeWrapper::destroy() void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const { - Q_ASSERT(valueType->typeId == value.userType()); + Q_ASSERT(valueType->metaType.id() == value.userType()); if (gadgetPtr) valueType->metaType.destruct(gadgetPtr); if (!gadgetPtr) @@ -116,7 +116,7 @@ void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const QVariant Heap::QQmlValueTypeWrapper::toVariant() const { Q_ASSERT(gadgetPtr); - return QVariant(valueType->typeId, gadgetPtr); + return QVariant(valueType->metaType.id(), gadgetPtr); } @@ -221,7 +221,7 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) if (!ref->readReferenceValue()) return false; - const int typeId = d()->valueType->typeId; + const int typeId = d()->valueType->metaType.id(); QMetaType::destruct(typeId, data); QMetaType::construct(typeId, data, d()->gadgetPtr); return true; @@ -305,7 +305,7 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value) const int QQmlValueTypeWrapper::typeId() const { - return d()->valueType->typeId; + return d()->valueType->metaType.id(); } bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const @@ -352,10 +352,10 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, con // Prepare a buffer to pass to QMetaType::convert() QString convertResult; convertResult.~QString(); - if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->typeId, &convertResult, QMetaType::QString)) { + if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->metaType.id(), &convertResult, QMetaType::QString)) { result = convertResult; } else { - result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->metaType.id())) + QLatin1Char('('); const QMetaObject *mo = w->d()->propertyCache()->metaObject(); const int propCount = mo->propertyCount(); diff --git a/src/qml/qmldirparser/qmldirparser.pri b/src/qml/qmldirparser/qmldirparser.pri new file mode 100644 index 0000000000..660e7b395a --- /dev/null +++ b/src/qml/qmldirparser/qmldirparser.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD +INCLUDEPATH += $$OUT_PWD + +HEADERS += \ + $$PWD/qqmldirparser_p.h \ + $$PWD/qqmlerror.h \ + $$PWD/qqmlsourcecoordinate_p.h + +SOURCES += \ + $$PWD/qqmldirparser.cpp \ + $$PWD/qqmlerror.cpp diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index d87bf433b8..e944b52e47 100644 --- a/src/qml/qml/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -367,12 +367,10 @@ QList<QQmlDirParser::Script> QQmlDirParser::scripts() const return _scripts; } -#ifdef QT_CREATOR QList<QQmlDirParser::TypeInfo> QQmlDirParser::typeInfos() const { return _typeInfos; } -#endif bool QQmlDirParser::designerSupported() const { diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index d7e29813d1..cff9cb11a4 100644 --- a/src/qml/qml/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -122,7 +122,6 @@ public: QList<Plugin> plugins() const; bool designerSupported() const; -#ifdef QT_CREATOR struct TypeInfo { TypeInfo() {} @@ -133,7 +132,6 @@ public: }; QList<TypeInfo> typeInfos() const; -#endif QString className() const; @@ -149,9 +147,7 @@ private: QList<Script> _scripts; QList<Plugin> _plugins; bool _designerSupported; -#ifdef QT_CREATOR QList<TypeInfo> _typeInfos; -#endif QString _className; }; diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qmldirparser/qqmlerror.cpp index 61e9a3f37e..5e181f7e27 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qmldirparser/qqmlerror.cpp @@ -38,15 +38,17 @@ ****************************************************************************/ #include "qqmlerror.h" -#include "qqmlglobal_p.h" +#include "qqmlsourcecoordinate_p.h" #include <QtCore/qdebug.h> #include <QtCore/qfile.h> #include <QtCore/qstringlist.h> #include <QtCore/qvector.h> -#include <QtCore/qpointer.h> -#include <private/qv4errorobject_p.h> +#ifndef QT_NO_QOBJECT +#include <QtCore/qobject.h> +#include <QtCore/qpointer.h> +#endif QT_BEGIN_NAMESPACE @@ -85,11 +87,13 @@ public: quint16 line; quint16 column; QtMsgType messageType; +#ifndef QT_NO_QOBJECT QPointer<QObject> object; +#endif }; QQmlErrorPrivate::QQmlErrorPrivate() -: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object() +: line(0), column(0), messageType(QtMsgType::QtWarningMsg) { } @@ -125,7 +129,9 @@ QQmlError &QQmlError::operator=(const QQmlError &other) d->description = other.d->description; d->line = other.d->line; d->column = other.d->column; +#ifndef QT_NO_QOBJECT d->object = other.d->object; +#endif d->messageType = other.d->messageType; } return *this; @@ -227,6 +233,7 @@ void QQmlError::setColumn(int column) d->column = qmlSourceCoordinate(column); } +#ifndef QT_NO_QOBJECT /*! Returns the nearest object where this error occurred. Exceptions in bound property expressions set this to the object @@ -249,6 +256,7 @@ void QQmlError::setObject(QObject *object) d = new QQmlErrorPrivate; d->object = object; } +#endif // QT_NO_QOBJECT /*! \since 5.9 diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qmldirparser/qqmlerror.h index ef529e3828..f4221358e9 100644 --- a/src/qml/qml/qqmlerror.h +++ b/src/qml/qmldirparser/qqmlerror.h @@ -68,8 +68,12 @@ public: void setLine(int); int column() const; void setColumn(int); + +#ifndef QT_NO_QOBJECT QObject *object() const; void setObject(QObject *); +#endif + QtMsgType messageType() const; void setMessageType(QtMsgType messageType); diff --git a/src/qml/qmldirparser/qqmlsourcecoordinate_p.h b/src/qml/qmldirparser/qqmlsourcecoordinate_p.h new file mode 100644 index 0000000000..76ac741ae8 --- /dev/null +++ b/src/qml/qmldirparser/qqmlsourcecoordinate_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLSOURCECOORDINATE_P_H +#define QQMLSOURCECOORDINATE_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 <QtCore/qglobal.h> + +#include <climits> + +QT_BEGIN_NAMESPACE + +inline quint16 qmlSourceCoordinate(int n) +{ + return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0; +} + +inline int qmlSourceCoordinate(quint16 n) +{ + return (n == 0) ? -1 : static_cast<int>(n); +} + +QT_END_NAMESPACE + +#endif // QQMLSOURCECOORDINATE_P_H diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro index 0807482d23..94d300b765 100644 --- a/src/qmldebug/qmldebug.pro +++ b/src/qmldebug/qmldebug.pro @@ -9,20 +9,27 @@ SOURCES += \ qqmldebugconnection.cpp \ qqmldebugmessageclient.cpp \ qqmlenginecontrolclient.cpp \ + qqmlenginedebugclient.cpp \ + qqmlinspectorclient.cpp \ qqmlpreviewclient.cpp \ qqmlprofilerclient.cpp \ qqmlprofilerevent.cpp \ qqmlprofilereventlocation.cpp \ qqmlprofilereventtype.cpp \ - qqmlprofilertypedevent.cpp + qqmlprofilertypedevent.cpp \ + qv4debugclient.cpp HEADERS += \ qqmldebugclient_p.h \ qqmldebugclient_p_p.h \ qqmldebugconnection_p.h \ qqmldebugmessageclient_p.h \ + qqmlenginedebugclient_p.h \ + qqmlenginedebugclient_p_p.h \ qqmlenginecontrolclient_p.h \ qqmlenginecontrolclient_p_p.h \ + qqmlinspectorclient_p.h \ + qqmlinspectorclient_p_p.h \ qqmlpreviewclient_p.h \ qqmlpreviewclient_p_p.h \ qqmlprofilerclient_p.h \ @@ -32,4 +39,6 @@ HEADERS += \ qqmlprofilereventreceiver_p.h \ qqmlprofilereventtype_p.h \ qqmlprofilertypedevent_p.h \ - qqmlprofilerclientdefinitions_p.h + qqmlprofilerclientdefinitions_p.h \ + qv4debugclient_p.h \ + qv4debugclient_p_p.h diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/src/qmldebug/qqmlenginedebugclient.cpp index 7e736ec400..ec45ec33bc 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp +++ b/src/qmldebug/qqmlenginedebugclient.cpp @@ -26,22 +26,24 @@ ** ****************************************************************************/ -#include "qqmlenginedebugclient.h" +#include "qqmlenginedebugclient_p_p.h" #include <private/qqmldebugconnection_p.h> -struct QmlObjectData { +QT_BEGIN_NAMESPACE + +struct QQmlObjectData { QUrl url; - int lineNumber; - int columnNumber; + int lineNumber = -1; + int columnNumber = -1; QString idString; QString objectName; QString objectType; - int objectId; - int contextId; - int parentId; + int objectId = -1; + int contextId = -1; + int parentId = -1; }; -QPacket &operator>>(QPacket &ds, QmlObjectData &data) +QPacket &operator>>(QPacket &ds, QQmlObjectData &data) { ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString >> data.objectName >> data.objectType >> data.objectId >> data.contextId @@ -49,35 +51,38 @@ QPacket &operator>>(QPacket &ds, QmlObjectData &data) return ds; } -struct QmlObjectProperty { +struct QQmlObjectProperty { enum Type { Unknown, Basic, Object, List, SignalProperty }; - Type type; + Type type = Unknown; QString name; QVariant value; QString valueTypeName; QString binding; - bool hasNotifySignal; + bool hasNotifySignal = false; }; -QPacket &operator>>(QPacket &ds, QmlObjectProperty &data) +QPacket &operator>>(QPacket &ds, QQmlObjectProperty &data) { int type; ds >> type >> data.name >> data.value >> data.valueTypeName >> data.binding >> data.hasNotifySignal; - data.type = (QmlObjectProperty::Type)type; + data.type = (QQmlObjectProperty::Type)type; return ds; } -QQmlEngineDebugClient::QQmlEngineDebugClient( - QQmlDebugConnection *connection) - : QQmlDebugClient(QLatin1String("QmlDebugger"), connection), - m_nextId(0), - m_valid(false) +QQmlEngineDebugClient::QQmlEngineDebugClient(QQmlDebugConnection *connection) : + QQmlDebugClient(*new QQmlEngineDebugClientPrivate(connection)) +{ +} + +QQmlEngineDebugClientPrivate::QQmlEngineDebugClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate (QLatin1String("QmlDebugger"), connection) { } + quint32 QQmlEngineDebugClient::addWatch( - const QmlDebugPropertyReference &property, bool *success) + const QQmlEngineDebugPropertyReference &property, bool *success) { quint32 id = -1; *success = false; @@ -93,7 +98,7 @@ quint32 QQmlEngineDebugClient::addWatch( } quint32 QQmlEngineDebugClient::addWatch( - const QmlDebugContextReference &, const QString &, bool *success) + const QQmlEngineDebugContextReference &, const QString &, bool *success) { *success = false; qWarning("QQmlEngineDebugClient::addWatch(): Not implemented"); @@ -101,7 +106,7 @@ quint32 QQmlEngineDebugClient::addWatch( } quint32 QQmlEngineDebugClient::addWatch( - const QmlDebugObjectReference &object, const QString &expr, + const QQmlEngineDebugObjectReference &object, const QString &expr, bool *success) { quint32 id = -1; @@ -117,7 +122,7 @@ quint32 QQmlEngineDebugClient::addWatch( } quint32 QQmlEngineDebugClient::addWatch( - const QmlDebugObjectReference &object, bool *success) + const QQmlEngineDebugObjectReference &object, bool *success) { quint32 id = -1; *success = false; @@ -132,7 +137,7 @@ quint32 QQmlEngineDebugClient::addWatch( } quint32 QQmlEngineDebugClient::addWatch( - const QmlDebugFileReference &, bool *success) + const QQmlEngineDebugFileReference &, bool *success) { *success = false; qWarning("QQmlEngineDebugClient::addWatch(): Not implemented"); @@ -152,7 +157,8 @@ void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success) quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success) { - m_engines.clear(); + Q_D(QQmlEngineDebugClient); + d->engines.clear(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled) { @@ -166,9 +172,10 @@ quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success) } quint32 QQmlEngineDebugClient::queryRootContexts( - const QmlDebugEngineReference &engine, bool *success) + const QQmlEngineDebugEngineReference &engine, bool *success) { - m_rootContext = QmlDebugContextReference(); + Q_D(QQmlEngineDebugClient); + d->rootContext = QQmlEngineDebugContextReference(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) { @@ -182,9 +189,10 @@ quint32 QQmlEngineDebugClient::queryRootContexts( } quint32 QQmlEngineDebugClient::queryObject( - const QmlDebugObjectReference &object, bool *success) + const QQmlEngineDebugObjectReference &object, bool *success) { - m_object = QmlDebugObjectReference(); + Q_D(QQmlEngineDebugClient); + d->object = QQmlEngineDebugObjectReference(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { @@ -200,7 +208,8 @@ quint32 QQmlEngineDebugClient::queryObject( quint32 QQmlEngineDebugClient::queryObjectsForLocation( const QString &file, int lineNumber, int columnNumber, bool *success) { - m_objects.clear(); + Q_D(QQmlEngineDebugClient); + d->objects.clear(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled) { @@ -215,9 +224,10 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocation( } quint32 QQmlEngineDebugClient::queryObjectRecursive( - const QmlDebugObjectReference &object, bool *success) + const QQmlEngineDebugObjectReference &object, bool *success) { - m_object = QmlDebugObjectReference(); + Q_D(QQmlEngineDebugClient); + d->object = QQmlEngineDebugObjectReference(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { @@ -233,7 +243,8 @@ quint32 QQmlEngineDebugClient::queryObjectRecursive( quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &file, int lineNumber, int columnNumber, bool *success) { - m_objects.clear(); + Q_D(QQmlEngineDebugClient); + d->objects.clear(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled) { @@ -250,7 +261,8 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &f quint32 QQmlEngineDebugClient::queryExpressionResult( int objectDebugId, const QString &expr, bool *success) { - m_exprResult = QVariant(); + Q_D(QQmlEngineDebugClient); + d->exprResult = QVariant(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled) { @@ -267,7 +279,8 @@ quint32 QQmlEngineDebugClient::queryExpressionResult( quint32 QQmlEngineDebugClient::queryExpressionResultBC( int objectDebugId, const QString &expr, bool *success) { - m_exprResult = QVariant(); + Q_D(QQmlEngineDebugClient); + d->exprResult = QVariant(); quint32 id = -1; *success = false; if (state() == QQmlDebugClient::Enabled) { @@ -285,7 +298,7 @@ quint32 QQmlEngineDebugClient::setBindingForObject( const QString &propertyName, const QVariant &bindingExpression, bool isLiteralValue, - QString source, int line, + const QString &source, int line, bool *success) { quint32 id = -1; @@ -336,10 +349,10 @@ quint32 QQmlEngineDebugClient::setMethodBody( } void QQmlEngineDebugClient::decode(QPacket &ds, - QmlDebugObjectReference &o, + QQmlEngineDebugObjectReference &o, bool simple) { - QmlObjectData data; + QQmlObjectData data; ds >> data; o.debugId = data.objectId; o.className = data.objectType; @@ -358,7 +371,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds, ds >> childCount >> recur; for (int ii = 0; ii < childCount; ++ii) { - o.children.append(QmlDebugObjectReference()); + o.children.append(QQmlEngineDebugObjectReference()); decode(ds, o.children.last(), !recur); } @@ -366,31 +379,31 @@ void QQmlEngineDebugClient::decode(QPacket &ds, ds >> propCount; for (int ii = 0; ii < propCount; ++ii) { - QmlObjectProperty data; + QQmlObjectProperty data; ds >> data; - QmlDebugPropertyReference prop; + QQmlEngineDebugPropertyReference prop; prop.objectDebugId = o.debugId; prop.name = data.name; prop.binding = data.binding; prop.hasNotifySignal = data.hasNotifySignal; prop.valueTypeName = data.valueTypeName; switch (data.type) { - case QmlObjectProperty::Basic: - case QmlObjectProperty::List: - case QmlObjectProperty::SignalProperty: + case QQmlObjectProperty::Basic: + case QQmlObjectProperty::List: + case QQmlObjectProperty::SignalProperty: { prop.value = data.value; break; } - case QmlObjectProperty::Object: + case QQmlObjectProperty::Object: { - QmlDebugObjectReference obj; + QQmlEngineDebugObjectReference obj; obj.name = data.value.toString(); obj.className = prop.valueTypeName; prop.value = qVariantFromValue(obj); break; } - case QmlObjectProperty::Unknown: + case QQmlObjectProperty::Unknown: break; } o.properties << prop; @@ -398,20 +411,56 @@ void QQmlEngineDebugClient::decode(QPacket &ds, } void QQmlEngineDebugClient::decode(QPacket &ds, - QList<QmlDebugObjectReference> &o, + QList<QQmlEngineDebugObjectReference> &o, bool simple) { int count; ds >> count; for (int i = 0; i < count; i++) { - QmlDebugObjectReference obj; + QQmlEngineDebugObjectReference obj; decode(ds, obj, simple); o << obj; } } +QList<QQmlEngineDebugEngineReference> QQmlEngineDebugClient::engines() const +{ + Q_D(const QQmlEngineDebugClient); + return d->engines; +} + +QQmlEngineDebugContextReference QQmlEngineDebugClient::rootContext() const +{ + Q_D(const QQmlEngineDebugClient); + return d->rootContext; +} + +QQmlEngineDebugObjectReference QQmlEngineDebugClient::object() const +{ + Q_D(const QQmlEngineDebugClient); + return d->object; +} + +QList<QQmlEngineDebugObjectReference> QQmlEngineDebugClient::objects() const +{ + Q_D(const QQmlEngineDebugClient); + return d->objects; +} + +QVariant QQmlEngineDebugClient::resultExpr() const +{ + Q_D(const QQmlEngineDebugClient); + return d->exprResult; +} + +bool QQmlEngineDebugClient::valid() const +{ + Q_D(const QQmlEngineDebugClient); + return d->valid; +} + void QQmlEngineDebugClient::decode(QPacket &ds, - QmlDebugContextReference &c) + QQmlEngineDebugContextReference &c) { ds >> c.name >> c.debugId; @@ -419,7 +468,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds, ds >> contextCount; for (int ii = 0; ii < contextCount; ++ii) { - c.contexts.append(QmlDebugContextReference()); + c.contexts.append(QQmlEngineDebugContextReference()); decode(ds, c.contexts.last()); } @@ -427,7 +476,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds, ds >> objectCount; for (int ii = 0; ii < objectCount; ++ii) { - QmlDebugObjectReference obj; + QQmlEngineDebugObjectReference obj; decode(ds, obj, true); obj.contextDebugId = c.debugId; @@ -437,7 +486,8 @@ void QQmlEngineDebugClient::decode(QPacket &ds, void QQmlEngineDebugClient::messageReceived(const QByteArray &data) { - m_valid = false; + Q_D(QQmlEngineDebugClient); + d->valid = false; QPacket ds(connection()->currentDataStreamVersion(), data); int queryId; @@ -450,36 +500,36 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data) int count; ds >> count; - m_engines.clear(); + d->engines.clear(); for (int ii = 0; ii < count; ++ii) { - QmlDebugEngineReference eng; + QQmlEngineDebugEngineReference eng; ds >> eng.name; ds >> eng.debugId; - m_engines << eng; + d->engines << eng; } } else if (type == "LIST_OBJECTS_R") { if (!ds.atEnd()) - decode(ds, m_rootContext); + decode(ds, d->rootContext); } else if (type == "FETCH_OBJECT_R") { if (!ds.atEnd()) - decode(ds, m_object, false); + decode(ds, d->object, false); } else if (type == "FETCH_OBJECTS_FOR_LOCATION_R") { if (!ds.atEnd()) - decode(ds, m_objects, false); + decode(ds, d->objects, false); } else if (type == "EVAL_EXPRESSION_R") {; - ds >> m_exprResult; + ds >> d->exprResult; } else if (type == "WATCH_PROPERTY_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "WATCH_OBJECT_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "WATCH_EXPR_OBJECT_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "UPDATE_WATCH") { int debugId; @@ -495,14 +545,22 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data) emit newObject(objectId); return; } else if (type == "SET_BINDING_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "RESET_BINDING_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "SET_METHOD_BODY_R") { - ds >> m_valid; + ds >> d->valid; } else if (type == "NO_WATCH_R") { - ds >> m_valid; + ds >> d->valid; } emit result(); } + +quint32 QQmlEngineDebugClient::getId() +{ + Q_D(QQmlEngineDebugClient); + return d->nextId++; +} + +QT_END_NAMESPACE diff --git a/src/qmldebug/qqmlenginedebugclient_p.h b/src/qmldebug/qqmlenginedebugclient_p.h new file mode 100644 index 0000000000..4a9cc3a020 --- /dev/null +++ b/src/qmldebug/qqmlenginedebugclient_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#ifndef QQMLENGINEDEBUGCLIENT_H +#define QQMLENGINEDEBUGCLIENT_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 <private/qqmldebugclient_p.h> +#include <private/qpacket_p.h> + +#include <QtCore/qurl.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + +struct QQmlEngineDebugPropertyReference +{ + int objectDebugId = -1; + QString name; + QVariant value; + QString valueTypeName; + QString binding; + bool hasNotifySignal = false; +}; + +struct QQmlEngineDebugFileReference +{ + QUrl url; + int lineNumber = -1; + int columnNumber = -1; +}; + +struct QQmlEngineDebugObjectReference +{ + int debugId = -1; + QString className; + QString idString; + QString name; + QQmlEngineDebugFileReference source; + int contextDebugId = -1; + QList<QQmlEngineDebugPropertyReference> properties; + QList<QQmlEngineDebugObjectReference> children; +}; + +struct QQmlEngineDebugContextReference +{ + int debugId = -1; + QString name; + QList<QQmlEngineDebugObjectReference> objects; + QList<QQmlEngineDebugContextReference> contexts; +}; + +struct QQmlEngineDebugEngineReference +{ + int debugId = -1; + QString name; +}; + +class QQmlEngineDebugClientPrivate; +class QQmlEngineDebugClient : public QQmlDebugClient +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQmlEngineDebugClient) + +public: + explicit QQmlEngineDebugClient(QQmlDebugConnection *conn); + + quint32 addWatch(const QQmlEngineDebugPropertyReference &, + bool *success); + quint32 addWatch(const QQmlEngineDebugContextReference &, const QString &, + bool *success); + quint32 addWatch(const QQmlEngineDebugObjectReference &, const QString &, + bool *success); + quint32 addWatch(const QQmlEngineDebugObjectReference &, + bool *success); + quint32 addWatch(const QQmlEngineDebugFileReference &, + bool *success); + + void removeWatch(quint32 watch, bool *success); + + quint32 queryAvailableEngines(bool *success); + quint32 queryRootContexts(const QQmlEngineDebugEngineReference &, + bool *success); + quint32 queryObject(const QQmlEngineDebugObjectReference &, + bool *success); + quint32 queryObjectsForLocation(const QString &file, + int lineNumber, int columnNumber, bool *success); + quint32 queryObjectRecursive(const QQmlEngineDebugObjectReference &, + bool *success); + quint32 queryObjectsForLocationRecursive(const QString &file, + int lineNumber, int columnNumber, bool *success); + quint32 queryExpressionResult(int objectDebugId, + const QString &expr, + bool *success); + quint32 queryExpressionResultBC(int objectDebugId, + const QString &expr, + bool *success); + quint32 setBindingForObject(int objectDebugId, const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + const QString &source, int line, bool *success); + quint32 resetBindingForObject(int objectDebugId, + const QString &propertyName, bool *success); + quint32 setMethodBody(int objectDebugId, const QString &methodName, + const QString &methodBody, bool *success); + + quint32 getId(); + + void decode(QPacket &ds, QQmlEngineDebugContextReference &); + void decode(QPacket &ds, QQmlEngineDebugObjectReference &, bool simple); + void decode(QPacket &ds, QList<QQmlEngineDebugObjectReference> &o, bool simple); + + QList<QQmlEngineDebugEngineReference> engines() const; + QQmlEngineDebugContextReference rootContext() const; + QQmlEngineDebugObjectReference object() const; + QList<QQmlEngineDebugObjectReference> objects() const; + QVariant resultExpr() const; + bool valid() const; + +signals: + void newObject(int objectId); + void valueChanged(QByteArray,QVariant); + void result(); + +protected: + void messageReceived(const QByteArray &) override; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QQmlEngineDebugObjectReference) + +#endif // QQMLENGINEDEBUGCLIENT_H diff --git a/src/qmldebug/qqmlenginedebugclient_p_p.h b/src/qmldebug/qqmlenginedebugclient_p_p.h new file mode 100644 index 0000000000..7c992ad3ab --- /dev/null +++ b/src/qmldebug/qqmlenginedebugclient_p_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLENGINEDEBUGCLIENT_P_P_H +#define QQMLENGINEDEBUGCLIENT_P_P_H + +#include "qqmlenginedebugclient_p.h" +#include "qqmldebugclient_p_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. +// + +QT_BEGIN_NAMESPACE + +class QQmlEngineDebugClientPrivate : public QQmlDebugClientPrivate +{ + Q_DECLARE_PUBLIC(QQmlEngineDebugClient) +public: + QQmlEngineDebugClientPrivate(QQmlDebugConnection *connection); + + quint32 nextId = 0; + bool valid = false; + QList<QQmlEngineDebugEngineReference> engines; + QQmlEngineDebugContextReference rootContext; + QQmlEngineDebugObjectReference object; + QList<QQmlEngineDebugObjectReference> objects; + QVariant exprResult; +}; + +QT_END_NAMESPACE + +#endif // QQMLENGINEDEBUGCLIENT_P_P_H diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp b/src/qmldebug/qqmlinspectorclient.cpp index 20faef177e..1de52bd0c1 100644 --- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp +++ b/src/qmldebug/qqmlinspectorclient.cpp @@ -1,11 +1,11 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the QtQml module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** $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 @@ -14,96 +14,120 @@ ** 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 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "qqmlinspectorclient.h" +#include "qqmlinspectorclient_p_p.h" #include <private/qpacket_p.h> #include <private/qqmldebugconnection_p.h> #include <QtCore/qdebug.h> +QT_BEGIN_NAMESPACE + QQmlInspectorClient::QQmlInspectorClient(QQmlDebugConnection *connection) : - QQmlDebugClient(QLatin1String("QmlInspector"), connection), - m_lastRequestId(-1) + QQmlDebugClient(*new QQmlInspectorClientPrivate(connection)) +{ +} + +QQmlInspectorClientPrivate::QQmlInspectorClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate(QLatin1String("QmlInspector"), connection) { } int QQmlInspectorClient::setInspectToolEnabled(bool enabled) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray(enabled ? "enable" : "disable"); sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::setShowAppOnTop(bool showOnTop) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("showAppOnTop") << showOnTop; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::setAnimationSpeed(qreal speed) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("setAnimationSpeed") << speed; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::select(const QList<int> &objectIds) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("select") << objectIds; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::createObject(const QString &qml, int parentId, const QStringList &imports, const QString &filename) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("createObject") << qml << parentId << imports << filename; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::moveObject(int childId, int newParentId) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("moveObject") << childId << newParentId; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } int QQmlInspectorClient::destroyObject(int objectId) { + Q_D(QQmlInspectorClient); QPacket ds(connection()->currentDataStreamVersion()); - ds << QByteArray("request") << ++m_lastRequestId + ds << QByteArray("request") << ++(d->m_lastRequestId) << QByteArray("destroyObject") << objectId; sendMessage(ds.data()); - return m_lastRequestId; + return d->m_lastRequestId; } void QQmlInspectorClient::messageReceived(const QByteArray &message) @@ -122,3 +146,5 @@ void QQmlInspectorClient::messageReceived(const QByteArray &message) ds >> responseId >> result; emit responseReceived(responseId, result); } + +QT_END_NAMESPACE diff --git a/src/qmldebug/qqmlinspectorclient_p.h b/src/qmldebug/qqmlinspectorclient_p.h new file mode 100644 index 0000000000..3e502f4f45 --- /dev/null +++ b/src/qmldebug/qqmlinspectorclient_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLINSPECTORCLIENT_P_H +#define QQMLINSPECTORCLIENT_P_H + +#include <private/qqmldebugclient_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlInspectorClientPrivate; +class QQmlInspectorClient : public QQmlDebugClient +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQmlInspectorClient) + +public: + QQmlInspectorClient(QQmlDebugConnection *connection); + + int setInspectToolEnabled(bool enabled); + int setShowAppOnTop(bool showOnTop); + int setAnimationSpeed(qreal speed); + int select(const QList<int> &objectIds); + int createObject(const QString &qml, int parentId, const QStringList &imports, + const QString &filename); + int moveObject(int childId, int newParentId); + int destroyObject(int objectId); + +signals: + void responseReceived(int requestId, bool result); + +protected: + void messageReceived(const QByteArray &message) override; +}; + +QT_END_NAMESPACE + +#endif // QQMLINSPECTORCLIENT_P_H diff --git a/src/qmldebug/qqmlinspectorclient_p_p.h b/src/qmldebug/qqmlinspectorclient_p_p.h new file mode 100644 index 0000000000..91537dd994 --- /dev/null +++ b/src/qmldebug/qqmlinspectorclient_p_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLINSPECTORCLIENT_P_P_H +#define QQMLINSPECTORCLIENT_P_P_H + +#include "qqmlinspectorclient_p.h" +#include "qqmldebugclient_p_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. +// + +QT_BEGIN_NAMESPACE + +class QQmlInspectorClientPrivate : public QQmlDebugClientPrivate +{ + Q_DECLARE_PUBLIC(QQmlInspectorClient) +public: + QQmlInspectorClientPrivate(QQmlDebugConnection *connection); + int m_lastRequestId = -1; +}; + +QT_END_NAMESPACE + +#endif // QQMLINSPECTORCLIENT_P_P_H diff --git a/src/qmldebug/qv4debugclient.cpp b/src/qmldebug/qv4debugclient.cpp new file mode 100644 index 0000000000..76c2f1ebea --- /dev/null +++ b/src/qmldebug/qv4debugclient.cpp @@ -0,0 +1,578 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#include "qv4debugclient_p.h" +#include "qv4debugclient_p_p.h" +#include "qqmldebugconnection_p.h" + +#include <private/qpacket_p.h> + +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonValue> +#include <QJsonArray> + +QT_BEGIN_NAMESPACE + +const char *V8REQUEST = "v8request"; +const char *V8MESSAGE = "v8message"; +const char *SEQ = "seq"; +const char *TYPE = "type"; +const char *COMMAND = "command"; +const char *ARGUMENTS = "arguments"; +const char *STEPACTION = "stepaction"; +const char *STEPCOUNT = "stepcount"; +const char *EXPRESSION = "expression"; +const char *FRAME = "frame"; +const char *CONTEXT = "context"; +const char *GLOBAL = "global"; +const char *DISABLEBREAK = "disable_break"; +const char *HANDLES = "handles"; +const char *INCLUDESOURCE = "includeSource"; +const char *FROMFRAME = "fromFrame"; +const char *TOFRAME = "toFrame"; +const char *BOTTOM = "bottom"; +const char *NUMBER = "number"; +const char *FRAMENUMBER = "frameNumber"; +const char *TYPES = "types"; +const char *IDS = "ids"; +const char *FILTER = "filter"; +const char *FROMLINE = "fromLine"; +const char *TOLINE = "toLine"; +const char *TARGET = "target"; +const char *LINE = "line"; +const char *COLUMN = "column"; +const char *ENABLED = "enabled"; +const char *CONDITION = "condition"; +const char *IGNORECOUNT = "ignoreCount"; +const char *BREAKPOINT = "breakpoint"; +const char *FLAGS = "flags"; + +const char *CONTINEDEBUGGING = "continue"; +const char *EVALUATE = "evaluate"; +const char *LOOKUP = "lookup"; +const char *BACKTRACE = "backtrace"; +const char *SCOPE = "scope"; +const char *SCOPES = "scopes"; +const char *SCRIPTS = "scripts"; +const char *SOURCE = "source"; +const char *SETBREAKPOINT = "setbreakpoint"; +const char *CLEARBREAKPOINT = "clearbreakpoint"; +const char *CHANGEBREAKPOINT = "changebreakpoint"; +const char *SETEXCEPTIONBREAK = "setexceptionbreak"; +const char *VERSION = "version"; +const char *DISCONNECT = "disconnect"; +const char *GARBAGECOLLECTOR = "gc"; + +const char *CONNECT = "connect"; +const char *INTERRUPT = "interrupt"; + +const char *REQUEST = "request"; +const char *IN = "in"; +const char *NEXT = "next"; +const char *OUT = "out"; + +const char *SCRIPT = "script"; +const char *SCRIPTREGEXP = "scriptRegExp"; +const char *EVENT = "event"; + +const char *ALL = "all"; +const char *UNCAUGHT = "uncaught"; + +#define VARIANTMAPINIT \ + Q_D(QV4DebugClient); \ + QJsonObject jsonVal; \ + jsonVal.insert(QLatin1String(SEQ), d->seq++); \ + jsonVal.insert(QLatin1String(TYPE), QLatin1String(REQUEST)); + +QV4DebugClient::QV4DebugClient(QQmlDebugConnection *connection) + : QQmlDebugClient(*new QV4DebugClientPrivate(connection)) +{ + QObject::connect(this, &QQmlDebugClient::stateChanged, + this, [this](State state) { d_func()->onStateChanged(state); }); +} + +QV4DebugClientPrivate::QV4DebugClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate(QLatin1String("V8Debugger"), connection) +{ +} + +void QV4DebugClient::connect() +{ + Q_D(QV4DebugClient); + d->sendMessage(CONNECT); +} + +void QV4DebugClient::interrupt() +{ + Q_D(QV4DebugClient); + d->sendMessage(INTERRUPT); +} + +void QV4DebugClient::continueDebugging(StepAction action) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "continue", + // "arguments" : { "stepaction" : <"in", "next" or "out">, + // "stepcount" : <number of steps (default 1)> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CONTINEDEBUGGING)); + + if (action != Continue) { + QJsonObject args; + switch (action) { + case In: + args.insert(QLatin1String(STEPACTION), QLatin1String(IN)); + break; + case Out: + args.insert(QLatin1String(STEPACTION), QLatin1String(OUT)); + break; + case Next: + args.insert(QLatin1String(STEPACTION), QLatin1String(NEXT)); + break; + default: + break; + } + jsonVal.insert(QLatin1String(ARGUMENTS), args); + } + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::evaluate(const QString &expr, int frame, int context) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "evaluate", + // "arguments" : { "expression" : <expression to evaluate>, + // "frame" : <number>, + // "context" : <object ID> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(EVALUATE)); + + QJsonObject args; + args.insert(QLatin1String(EXPRESSION), expr); + + if (frame != -1) + args.insert(QLatin1String(FRAME), frame); + + if (context != -1) + args.insert(QLatin1String(CONTEXT), context); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::lookup(const QList<int> &handles, bool includeSource) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "lookup", + // "arguments" : { "handles" : <array of handles>, + // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>, + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND),(QLatin1String(LOOKUP))); + + QJsonObject args; + QJsonArray array; + + for (int handle : handles) + array.append(handle); + + args.insert(QLatin1String(HANDLES), array); + + if (includeSource) + args.insert(QLatin1String(INCLUDESOURCE), includeSource); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::backtrace(int fromFrame, int toFrame, bool bottom) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "backtrace", + // "arguments" : { "fromFrame" : <number> + // "toFrame" : <number> + // "bottom" : <boolean, set to true if the bottom of the stack is requested> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(BACKTRACE)); + + QJsonObject args; + + if (fromFrame != -1) + args.insert(QLatin1String(FROMFRAME), fromFrame); + + if (toFrame != -1) + args.insert(QLatin1String(TOFRAME), toFrame); + + if (bottom) + args.insert(QLatin1String(BOTTOM), bottom); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::frame(int number) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "frame", + // "arguments" : { "number" : <frame number> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(FRAME)); + + if (number != -1) { + QJsonObject args; + args.insert(QLatin1String(NUMBER), number); + jsonVal.insert(QLatin1String(ARGUMENTS), args); + } + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::scope(int number, int frameNumber) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "scope", + // "arguments" : { "number" : <scope number> + // "frameNumber" : <frame number, optional uses selected frame if missing> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SCOPE)); + + if (number != -1) { + QJsonObject args; + args.insert(QLatin1String(NUMBER), number); + + if (frameNumber != -1) + args.insert(QLatin1String(FRAMENUMBER), frameNumber); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + } + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::scripts(int types, const QList<int> &ids, bool includeSource) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "scripts", + // "arguments" : { "types" : <types of scripts to retrieve + // set bit 0 for native scripts + // set bit 1 for extension scripts + // set bit 2 for normal scripts + // (default is 4 for normal scripts)> + // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned> + // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned> + // "filter" : <string or number: filter string or script id. + // If a number is specified, then only the script with the same number as its script id will be retrieved. + // If a string is specified, then only scripts whose names contain the filter string will be retrieved.> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SCRIPTS)); + + QJsonObject args; + args.insert(QLatin1String(TYPES), types); + + if (ids.count()) { + QJsonArray array; + for (int id : ids) + array.append(id); + + args.insert(QLatin1String(IDS), array); + } + + if (includeSource) + args.insert(QLatin1String(INCLUDESOURCE), includeSource); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::setBreakpoint(const QString &target, int line, int column, bool enabled, + const QString &condition, int ignoreCount) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "setbreakpoint", + // "arguments" : { "type" : "scriptRegExp" + // "target" : <function expression or script identification> + // "line" : <line in script or function> + // "column" : <character position within the line> + // "enabled" : <initial enabled state. True or false, default is true> + // "condition" : <string with break point condition> + // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0> + // } + // } + + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SETBREAKPOINT)); + + QJsonObject args; + + args.insert(QLatin1String(TYPE), QLatin1String(SCRIPTREGEXP)); + args.insert(QLatin1String(TARGET), target); + + if (line != -1) + args.insert(QLatin1String(LINE), line); + + if (column != -1) + args.insert(QLatin1String(COLUMN), column); + + args.insert(QLatin1String(ENABLED), enabled); + + if (!condition.isEmpty()) + args.insert(QLatin1String(CONDITION), condition); + + if (ignoreCount != -1) + args.insert(QLatin1String(IGNORECOUNT), ignoreCount); + + jsonVal.insert(QLatin1String(ARGUMENTS),args); + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::clearBreakpoint(int breakpoint) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "clearbreakpoint", + // "arguments" : { "breakpoint" : <number of the break point to clear> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CLEARBREAKPOINT)); + + QJsonObject args; + args.insert(QLatin1String(BREAKPOINT), breakpoint); + jsonVal.insert(QLatin1String(ARGUMENTS),args); + + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::changeBreakpoint(int breakpoint, bool enabled) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "changebreakpoint", + // "arguments" : { "breakpoint" : <number of the break point to change> + // "enabled" : <bool: enables the break type if true, disables if false> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CHANGEBREAKPOINT)); + + QJsonObject args; + args.insert(QLatin1String(BREAKPOINT), breakpoint); + args.insert(QLatin1String(ENABLED), enabled); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::setExceptionBreak(Exception type, bool enabled) +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "setexceptionbreak", + // "arguments" : { "type" : <string: "all", or "uncaught">, + // "enabled" : <optional bool: enables the break type if true> + // } + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SETEXCEPTIONBREAK)); + + QJsonObject args; + + if (type == All) + args.insert(QLatin1String(TYPE), QLatin1String(ALL)); + else if (type == Uncaught) + args.insert(QLatin1String(TYPE), QLatin1String(UNCAUGHT)); + + if (enabled) + args.insert(QLatin1String(ENABLED), enabled); + + jsonVal.insert(QLatin1String(ARGUMENTS), args); + d->sendMessage(V8REQUEST, jsonVal); +} + +void QV4DebugClient::version() +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "version", + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(VERSION)); + d->sendMessage(V8REQUEST, jsonVal); +} + +QV4DebugClient::Response QV4DebugClient::response() const +{ + Q_D(const QV4DebugClient); + const QJsonObject value = QJsonDocument::fromJson(d->response).object(); + return { + value.value(QLatin1String(COMMAND)).toString(), + value.value(QLatin1String("body")) + }; +} + +void QV4DebugClient::disconnect() +{ + // { "seq" : <number>, + // "type" : "request", + // "command" : "disconnect", + // } + VARIANTMAPINIT; + jsonVal.insert(QLatin1String(COMMAND), QLatin1String(DISCONNECT)); + d->sendMessage(DISCONNECT, jsonVal); +} + +void QV4DebugClientPrivate::onStateChanged(QQmlDebugClient::State state) +{ + if (state == QQmlDebugClient::Enabled) + flushSendBuffer(); +} + +void QV4DebugClient::messageReceived(const QByteArray &data) +{ + Q_D(QV4DebugClient); + QPacket ds(connection()->currentDataStreamVersion(), data); + QByteArray command; + ds >> command; + + if (command == "V8DEBUG") { + QByteArray type; + ds >> type >> d->response; + + if (type == CONNECT) { + emit connected(); + + } else if (type == INTERRUPT) { + emit interrupted(); + + } else if (type == V8MESSAGE) { + const QJsonObject value = QJsonDocument::fromJson(d->response).object(); + QString type = value.value(QLatin1String(TYPE)).toString(); + + if (type == QLatin1String("response")) { + + if (!value.value(QLatin1String("success")).toBool()) { + emit failure(); + qDebug() << "Received success == false response from application:" + << value.value(QLatin1String("message")).toString(); + return; + } + + QString debugCommand(value.value(QLatin1String(COMMAND)).toString()); + if (debugCommand == QLatin1String(BACKTRACE) || + debugCommand == QLatin1String(LOOKUP) || + debugCommand == QLatin1String(SETBREAKPOINT) || + debugCommand == QLatin1String(EVALUATE) || + debugCommand == QLatin1String(VERSION) || + debugCommand == QLatin1String(DISCONNECT) || + debugCommand == QLatin1String(GARBAGECOLLECTOR) || + debugCommand == QLatin1String(CHANGEBREAKPOINT) || + debugCommand == QLatin1String(CLEARBREAKPOINT) || + debugCommand == QLatin1String(FRAME) || + debugCommand == QLatin1String(SCOPE) || + debugCommand == QLatin1String(SCOPES) || + debugCommand == QLatin1String(SCRIPTS) || + debugCommand == QLatin1String(SOURCE) || + debugCommand == QLatin1String(SETEXCEPTIONBREAK)) { + emit result(); + } else { + // DO NOTHING + } + + } else if (type == QLatin1String(EVENT)) { + QString event(value.value(QLatin1String(EVENT)).toString()); + + if (event == QLatin1String("break") || event == QLatin1String("exception")) + emit stopped(); + } + } + } +} + +void QV4DebugClientPrivate::sendMessage(const QByteArray &command, const QJsonObject &args) +{ + Q_Q(QV4DebugClient); + const QByteArray msg = packMessage(command, args); + if (q->state() == QQmlDebugClient::Enabled) { + q->sendMessage(msg); + } else { + sendBuffer.append(msg); + } +} + +void QV4DebugClientPrivate::flushSendBuffer() +{ + foreach (const QByteArray &msg, sendBuffer) + sendMessage(msg); + sendBuffer.clear(); +} + +QByteArray QV4DebugClientPrivate::packMessage(const QByteArray &type, const QJsonObject &object) +{ + QPacket rs(connection->currentDataStreamVersion()); + QByteArray cmd = "V8DEBUG"; + rs << cmd << type << QJsonDocument(object).toJson(QJsonDocument::Compact); + return rs.data(); +} + +QT_END_NAMESPACE diff --git a/src/qmldebug/qv4debugclient_p.h b/src/qmldebug/qv4debugclient_p.h new file mode 100644 index 0000000000..fdcf4284c5 --- /dev/null +++ b/src/qmldebug/qv4debugclient_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QV4DEBUGCLIENT_P_H +#define QV4DEBUGCLIENT_P_H + +#include <QtQmlDebug/private/qqmldebugclient_p.h> +#include <QtCore/qjsonvalue.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. +// + +QT_BEGIN_NAMESPACE + +class QV4DebugClientPrivate; +class QV4DebugClient : public QQmlDebugClient +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QV4DebugClient) + +public: + enum StepAction + { + Continue, + In, + Out, + Next + }; + + enum Exception + { + All, + Uncaught + }; + + struct Response + { + QString command; + QJsonValue body; + }; + + QV4DebugClient(QQmlDebugConnection *connection); + + void connect(); + void disconnect(); + + void interrupt(); + void continueDebugging(StepAction stepAction); + void evaluate(const QString &expr, int frame = -1, int context = -1); + void lookup(const QList<int> &handles, bool includeSource = false); + void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); + void frame(int number = -1); + void scope(int number = -1, int frameNumber = -1); + void scripts(int types = 4, const QList<int> &ids = QList<int>(), bool includeSource = false); + void setBreakpoint(const QString &target, int line = -1, int column = -1, bool enabled = true, + const QString &condition = QString(), int ignoreCount = -1); + void clearBreakpoint(int breakpoint); + void changeBreakpoint(int breakpoint, bool enabled); + void setExceptionBreak(Exception type, bool enabled = false); + void version(); + + Response response() const; + +protected: + void messageReceived(const QByteArray &data) override; + +signals: + void connected(); + void interrupted(); + void result(); + void failure(); + void stopped(); +}; + +QT_END_NAMESPACE + +#endif // QV4DEBUGCLIENT_P_H diff --git a/src/qmldebug/qv4debugclient_p_p.h b/src/qmldebug/qv4debugclient_p_p.h new file mode 100644 index 0000000000..993c281632 --- /dev/null +++ b/src/qmldebug/qv4debugclient_p_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QV4DEBUGCLIENT_P_P_H +#define QV4DEBUGCLIENT_P_P_H + +#include "qv4debugclient_p.h" +#include "qqmldebugclient_p_p.h" + +#include <QtCore/qjsonobject.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. +// + +QT_BEGIN_NAMESPACE + +class QV4DebugClientPrivate : public QQmlDebugClientPrivate +{ + Q_DECLARE_PUBLIC(QV4DebugClient) + +public: + QV4DebugClientPrivate(QQmlDebugConnection *connection); + + void sendMessage(const QByteArray &command, const QJsonObject &args = QJsonObject()); + void flushSendBuffer(); + QByteArray packMessage(const QByteArray &type, const QJsonObject &object); + void onStateChanged(QQmlDebugClient::State state); + + int seq = 0; + QList<QByteArray> sendBuffer; + QByteArray response; +}; + +QT_END_NAMESPACE + +#endif // QV4DEBUGCLIENT_P_P_H diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro index 05aa6f66f5..45029400b9 100644 --- a/src/qmldevtools/qmldevtools.pro +++ b/src/qmldevtools/qmldevtools.pro @@ -17,5 +17,6 @@ include(../qml/parser/parser.pri) include(../qml/jsruntime/jsruntime.pri) include(../qml/compiler/compiler.pri) include(../qml/memory/memory.pri) +include(../qml/qmldirparser/qmldirparser.pri) load(qt_module) diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro index e2200e5abb..0bf05093be 100644 --- a/src/qmltest/qmltest.pro +++ b/src/qmltest/qmltest.pro @@ -4,7 +4,7 @@ QMAKE_DOCS = $$PWD/doc/qtqmltest.qdocconf DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_FOREACH QT = core testlib-private -QT_PRIVATE = quick qml-private gui core-private gui-private +QT_PRIVATE = quick quick-private qml-private gui core-private gui-private # Testlib is only a private dependency, which results in our users not # inheriting testlibs's MODULE_CONFIG transitively. Make it explicit. diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index f666bc2284..8803075284 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -44,10 +44,14 @@ #include <QtQml/qqml.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcontext.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> #include <QtQml/qjsvalue.h> #include <QtQml/qjsengine.h> #include <QtQml/qqmlpropertymap.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/qquickitem.h> #include <QtGui/qopengl.h> #include <QtCore/qurl.h> #include <QtCore/qfileinfo.h> @@ -72,6 +76,65 @@ QT_BEGIN_NAMESPACE +/*! + \fn bool qIsPolishScheduled(const QQuickItem *item) + \relates QtQuickTest + \since 5.13 + + Returns \c true if \l {QQuickItem::}{updatePolish()} has not been called + on \a item since the last call to \l {QQuickItem::}{polish()}, + otherwise returns \c false. + + When assigning values to properties in QML, any layouting the item + must do as a result of the assignment might not take effect immediately, + but can instead be postponed until the item is polished. For these cases, + you can use this function to ensure that the item has been polished + before the execution of the test continues. For example: + + \code + QVERIFY(QQuickTest::qIsPolishScheduled(item)); + QVERIFY(QQuickTest::qWaitForItemPolished(item)); + \endcode + + Without the call to \c qIsPolishScheduled() above, the + call to \c qWaitForItemPolished() might see that no polish + was scheduled and therefore pass instantly, assuming that + the item had already been polished. This function + makes it obvious why an item wasn't polished and allows tests to + fail early under such circumstances. + + \sa QQuickItem::polish(), QQuickItem::updatePolish() +*/ +bool QQuickTest::qIsPolishScheduled(const QQuickItem *item) +{ + return QQuickItemPrivate::get(item)->polishScheduled; +} + +/*! + \fn bool qWaitForItemPolished(const QQuickItem *item, int timeout = 5000) + \relates QtQuickTest + \since 5.13 + + Waits for \a timeout milliseconds or until + \l {QQuickItem::}{updatePolish()} has been called on \a item. + + Returns \c true if \c updatePolish() was called on \a item within + \a timeout milliseconds, otherwise returns \c false. + + To use this function, add the following line to your test's \c .pro file: + + \code + QT += qmltest + \endcode + + \sa QQuickItem::polish(), QQuickItem::updatePolish(), + QQuickTest::qIsPolishScheduled() +*/ +bool QQuickTest::qWaitForItemPolished(const QQuickItem *item, int timeout) +{ + return QTest::qWaitFor([&]() { return !QQuickItemPrivate::get(item)->polishScheduled; }, timeout); +} + class QTestRootObject : public QObject { Q_OBJECT @@ -198,6 +261,21 @@ bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000) return spy.size(); } +void maybeInvokeSetupMethod(QObject *setupObject, const char *member, QGenericArgument val0 = QGenericArgument(nullptr)) +{ + // It's OK if it doesn't exist: since we have more than one callback that + // can be called, it makes sense if the user only implements one of them. + // We do this the long way rather than just calling the static + // QMetaObject::invokeMethod(), because that will issue a warning if the + // function doesn't exist, which we don't want. + const QMetaObject *setupMetaObject = setupObject->metaObject(); + const int methodIndex = setupMetaObject->indexOfMethod(member); + if (methodIndex != -1) { + const QMetaMethod method = setupMetaObject->method(methodIndex); + method.invoke(setupObject, val0); + } +} + using namespace QV4::CompiledData; class TestCaseCollector @@ -359,10 +437,8 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch } } - if (setup) { - // Don't check the return value; it's OK if it doesn't exist. - QMetaObject::invokeMethod(setup, "applicationAvailable"); - } + if (setup) + maybeInvokeSetupMethod(setup, "applicationAvailable()"); // Look for QML-specific command-line options. // -import dir Specify an import directory. @@ -535,11 +611,8 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch // Do this down here so that import paths, plugin paths, // file selectors, etc. are available in case the user needs access to them. - if (setup) { - // Don't check the return value; it's OK if it doesn't exist. - // If we add more callbacks in the future, it makes sense if the user only implements one of them. - QMetaObject::invokeMethod(setup, "qmlEngineAvailable", Q_ARG(QQmlEngine*, view.engine())); - } + if (setup) + maybeInvokeSetupMethod(setup, "qmlEngineAvailable(QQmlEngine*)", Q_ARG(QQmlEngine*, view.engine())); view.setObjectName(fi.baseName()); view.setTitle(view.objectName()); @@ -588,10 +661,8 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch } } - if (setup) { - // Don't check the return value; it's OK if it doesn't exist. - QMetaObject::invokeMethod(setup, "cleanupTestCase"); - } + if (setup) + maybeInvokeSetupMethod(setup, "cleanupTestCase()"); // Flush the current logging stream. QuickTestResult::setProgramName(nullptr); diff --git a/src/qmltest/quicktest.h b/src/qmltest/quicktest.h index 62ed749722..8e3510c9a5 100644 --- a/src/qmltest/quicktest.h +++ b/src/qmltest/quicktest.h @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE -QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS +class QQuickItem; Q_QUICK_TEST_EXPORT int quick_test_main(int argc, char **argv, const char *name, const char *sourceDir); Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const char *name, const char *sourceDir, QObject *setup); @@ -55,7 +55,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_MAIN(name) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ return quick_test_main(argc, argv, #name, QUICK_TEST_SOURCE_DIR); \ } @@ -63,7 +62,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_OPENGL_MAIN(name) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ return quick_test_main(argc, argv, #name, QUICK_TEST_SOURCE_DIR); \ } @@ -71,7 +69,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_MAIN_WITH_SETUP(name, QuickTestSetupClass) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ QuickTestSetupClass setup; \ return quick_test_main_with_setup(argc, argv, #name, QUICK_TEST_SOURCE_DIR, &setup); \ @@ -82,7 +79,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_MAIN(name) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ return quick_test_main(argc, argv, #name, nullptr); \ } @@ -90,7 +86,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_OPENGL_MAIN(name) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ return quick_test_main(argc, argv, #name, nullptr); \ } @@ -98,7 +93,6 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #define QUICK_TEST_MAIN_WITH_SETUP(name, QuickTestSetupClass) \ int main(int argc, char **argv) \ { \ - QTEST_ADD_GPU_BLACKLIST_SUPPORT \ QTEST_SET_MAIN_SOURCE_PATH \ QuickTestSetupClass setup; \ return quick_test_main_with_setup(argc, argv, #name, nullptr, &setup); \ @@ -106,6 +100,11 @@ Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const #endif +namespace QQuickTest { +Q_QUICK_TEST_EXPORT bool qIsPolishScheduled(const QQuickItem *item); +Q_QUICK_TEST_EXPORT bool qWaitForItemPolished(const QQuickItem *item, int timeout = 5000); +} + QT_END_NAMESPACE #endif diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 3225dc95cd..4dbec585c4 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include "quicktestresult_p.h" +#include "quicktest.h" #include <QtTest/qtestcase.h> #include <QtTest/qtestsystem.h> #include <QtTest/private/qtestblacklist_p.h> @@ -787,6 +788,16 @@ QObject *QuickTestResult::findChild(QObject *parent, const QString &objectName) return parent ? parent->findChild<QObject*>(objectName) : 0; } +bool QuickTestResult::isPolishScheduled(QQuickItem *item) const +{ + return QQuickTest::qIsPolishScheduled(item); +} + +bool QuickTestResult::waitForItemPolished(QQuickItem *item, int timeout) +{ + return QQuickTest::qWaitForItemPolished(item, timeout); +} + namespace QTest { void qtest_qParseArgs(int argc, char *argv[], bool qml); }; @@ -802,7 +813,6 @@ void QuickTestResult::setProgramName(const char *name) { if (name) { QTestPrivate::parseBlackList(); - QTestPrivate::parseGpuBlackList(); QTestResult::reset(); } else if (!name && loggingStarted) { QTestResult::setCurrentTestObject(globalProgramName); @@ -829,7 +839,7 @@ int QuickTestResult::exitCode() #endif } +QT_END_NAMESPACE + #include "quicktestresult.moc" #include "moc_quicktestresult_p.cpp" - -QT_END_NAMESPACE diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h index b2eeefdfff..0659919a39 100644 --- a/src/qmltest/quicktestresult_p.h +++ b/src/qmltest/quicktestresult_p.h @@ -160,6 +160,9 @@ public Q_SLOTS: Q_REVISION(1) QObject *findChild(QObject *parent, const QString &objectName); + bool isPolishScheduled(QQuickItem *item) const; + bool waitForItemPolished(QQuickItem *item, int timeout); + public: // Helper functions for the C++ main() shell. static void parseArgs(int argc, char *argv[]); diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp index 3bb40546be..41a02fc09c 100644 --- a/src/quick/accessible/qaccessiblequickview.cpp +++ b/src/quick/accessible/qaccessiblequickview.cpp @@ -91,7 +91,7 @@ QAccessibleInterface *QAccessibleQuickWindow::focusChild() const QAccessible::Role QAccessibleQuickWindow::role() const { - return QAccessible::Window; // FIXME + return QAccessible::Window; } QAccessible::State QAccessibleQuickWindow::state() const diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 1c338fa79d..ed5fdf3a4a 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -192,19 +192,19 @@ static bool isCrashingType(const QQmlType &type) { QString name = type.qmlTypeName(); - if (type.qmlTypeName() == QLatin1String("QtMultimedia/MediaPlayer")) + if (name == QLatin1String("QtMultimedia/MediaPlayer")) return true; - if (type.qmlTypeName() == QLatin1String("QtMultimedia/Audio")) + if (name == QLatin1String("QtMultimedia/Audio")) return true; - if (type.qmlTypeName() == QLatin1String("QtQuick.Controls/MenuItem")) + if (name == QLatin1String("QtQuick.Controls/MenuItem")) return true; - if (type.qmlTypeName() == QLatin1String("QtQuick.Controls/Menu")) + if (name == QLatin1String("QtQuick.Controls/Menu")) return true; - if (type.qmlTypeName() == QLatin1String("QtQuick/Timer")) + if (name == QLatin1String("QtQuick/Timer")) return true; return false; diff --git a/src/quick/handlers/handlers.pri b/src/quick/handlers/handlers.pri index 1258822f40..226cca22cb 100644 --- a/src/quick/handlers/handlers.pri +++ b/src/quick/handlers/handlers.pri @@ -10,6 +10,7 @@ HEADERS += \ $$PWD/qquickpointerhandler_p_p.h \ $$PWD/qquickpointhandler_p.h \ $$PWD/qquicksinglepointhandler_p.h \ + $$PWD/qquicksinglepointhandler_p_p.h \ $$PWD/qquicktaphandler_p.h \ $$PWD/qquickdragaxis_p.h diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp index 82e5b1b05d..8f2f403975 100644 --- a/src/quick/handlers/qquicksinglepointhandler.cpp +++ b/src/quick/handlers/qquicksinglepointhandler.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qquicksinglepointhandler_p.h" +#include "qquicksinglepointhandler_p_p.h" QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH_TARGET) @@ -59,19 +60,25 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH_TARGET) */ QQuickSinglePointHandler::QQuickSinglePointHandler(QQuickItem *parent) - : QQuickPointerDeviceHandler(parent) + : QQuickPointerDeviceHandler(*(new QQuickSinglePointHandlerPrivate), parent) +{ +} + +QQuickSinglePointHandler::QQuickSinglePointHandler(QQuickSinglePointHandlerPrivate &dd, QQuickItem *parent) + : QQuickPointerDeviceHandler(dd, parent) { } bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event) { + Q_D(QQuickSinglePointHandler); if (!QQuickPointerDeviceHandler::wantsPointerEvent(event)) return false; if (event->device()->pointerType() != QQuickPointerDevice::Finger && (event->buttons() & acceptedButtons()) == 0 && (event->button() & acceptedButtons()) == 0) return false; - if (m_pointInfo.m_id) { + if (d->pointInfo.id()) { // We already know which one we want, so check whether it's there. // It's expected to be an update or a release. // If we no longer want it, cancel the grab. @@ -81,7 +88,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event) int c = event->pointCount(); for (int i = 0; i < c; ++i) { QQuickEventPoint *p = event->point(i); - const bool found = (p->pointId() == m_pointInfo.m_id); + const bool found = (p->pointId() == d->pointInfo.id()); if (found) missing = false; if (wantsEventPoint(p)) { @@ -91,10 +98,10 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event) } } if (missing) - qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << hex << m_pointInfo.m_id + qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << hex << d->pointInfo.id() << "is missing from current event, but was neither canceled nor released"; if (point) { - if (candidatePointCount == 1 || (candidatePointCount > 1 && m_ignoreAdditionalPoints)) { + if (candidatePointCount == 1 || (candidatePointCount > 1 && d->ignoreAdditionalPoints)) { point->setAccepted(); return true; } else { @@ -121,35 +128,37 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event) chosen->setAccepted(); } } - return m_pointInfo.m_id; + return d->pointInfo.id(); } void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event) { + Q_D(QQuickSinglePointHandler); QQuickPointerDeviceHandler::handlePointerEventImpl(event); - QQuickEventPoint *currentPoint = event->pointById(m_pointInfo.m_id); + QQuickEventPoint *currentPoint = event->pointById(d->pointInfo.id()); Q_ASSERT(currentPoint); - m_pointInfo.reset(currentPoint); + d->pointInfo.reset(currentPoint); handleEventPoint(currentPoint); if (currentPoint->state() == QQuickEventPoint::Released && (event->buttons() & acceptedButtons()) == Qt::NoButton) { setExclusiveGrab(currentPoint, false); - reset(); + d->reset(); } emit pointChanged(); } void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) { + Q_D(QQuickSinglePointHandler); if (grabber != this) return; switch (transition) { case QQuickEventPoint::GrabExclusive: - m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition(); + d->pointInfo.m_sceneGrabPosition = point->sceneGrabPosition(); setActive(true); QQuickPointerHandler::onGrabChanged(grabber, transition, point); break; case QQuickEventPoint::GrabPassive: - m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition(); + d->pointInfo.m_sceneGrabPosition = point->sceneGrabPosition(); QQuickPointerHandler::onGrabChanged(grabber, transition, point); break; case QQuickEventPoint::OverrideGrabPassive: @@ -160,32 +169,35 @@ void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQui case QQuickEventPoint::CancelGrabExclusive: // the grab is lost or relinquished, so the point is no longer relevant QQuickPointerHandler::onGrabChanged(grabber, transition, point); - reset(); + d->reset(); break; } } void QQuickSinglePointHandler::setIgnoreAdditionalPoints(bool v) { - m_ignoreAdditionalPoints = v; + Q_D(QQuickSinglePointHandler); + d->ignoreAdditionalPoints = v; } void QQuickSinglePointHandler::moveTarget(QPointF pos, QQuickEventPoint *point) { + Q_D(QQuickSinglePointHandler); target()->setPosition(pos); - m_pointInfo.m_scenePosition = point->scenePosition(); - m_pointInfo.m_position = target()->mapFromScene(m_pointInfo.m_scenePosition); + d->pointInfo.m_scenePosition = point->scenePosition(); + d->pointInfo.m_position = target()->mapFromScene(d->pointInfo.m_scenePosition); } void QQuickSinglePointHandler::setPointId(int id) { - m_pointInfo.m_id = id; + Q_D(QQuickSinglePointHandler); + d->pointInfo.m_id = id; } -void QQuickSinglePointHandler::reset() +QQuickHandlerPoint QQuickSinglePointHandler::point() const { - setActive(false); - m_pointInfo.reset(); + Q_D(const QQuickSinglePointHandler); + return d->pointInfo; } /*! @@ -196,4 +208,16 @@ void QQuickSinglePointHandler::reset() handled, this object is reset to default values (all coordinates are 0). */ +QQuickSinglePointHandlerPrivate::QQuickSinglePointHandlerPrivate() + : QQuickPointerDeviceHandlerPrivate() +{ +} + +void QQuickSinglePointHandlerPrivate::reset() +{ + Q_Q(QQuickSinglePointHandler); + q->setActive(false); + pointInfo.reset(); +} + QT_END_NAMESPACE diff --git a/src/quick/handlers/qquicksinglepointhandler_p.h b/src/quick/handlers/qquicksinglepointhandler_p.h index b9e5b12224..edc55aaaf6 100644 --- a/src/quick/handlers/qquicksinglepointhandler_p.h +++ b/src/quick/handlers/qquicksinglepointhandler_p.h @@ -56,24 +56,29 @@ QT_BEGIN_NAMESPACE +class QQuickSinglePointHandlerPrivate; + class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointHandler : public QQuickPointerDeviceHandler { Q_OBJECT Q_PROPERTY(QQuickHandlerPoint point READ point NOTIFY pointChanged) + public: explicit QQuickSinglePointHandler(QQuickItem *parent = nullptr); - QQuickHandlerPoint point() const { return m_pointInfo; } + QQuickHandlerPoint point() const; Q_SIGNALS: void pointChanged(); protected: + QQuickSinglePointHandler(QQuickSinglePointHandlerPrivate &dd, QQuickItem *parent); + bool wantsPointerEvent(QQuickPointerEvent *event) override; void handlePointerEventImpl(QQuickPointerEvent *event) override; virtual void handleEventPoint(QQuickEventPoint *point) = 0; - QQuickEventPoint *currentPoint(QQuickPointerEvent *ev) { return ev->pointById(m_pointInfo.m_id); } + QQuickEventPoint *currentPoint(QQuickPointerEvent *ev); void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override; void setIgnoreAdditionalPoints(bool v = true); @@ -82,12 +87,7 @@ protected: void setPointId(int id); -private: - void reset(); - -private: - QQuickHandlerPoint m_pointInfo; - bool m_ignoreAdditionalPoints = false; + Q_DECLARE_PRIVATE(QQuickSinglePointHandler) }; QT_END_NAMESPACE diff --git a/src/quick/handlers/qquicksinglepointhandler_p_p.h b/src/quick/handlers/qquicksinglepointhandler_p_p.h new file mode 100644 index 0000000000..1e66c25e14 --- /dev/null +++ b/src/quick/handlers/qquicksinglepointhandler_p_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 QQUICKPOINTERSINGLEHANDLER_P_H +#define QQUICKPOINTERSINGLEHANDLER_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 "qquickhandlerpoint_p.h" +#include "qquickpointerdevicehandler_p_p.h" +#include "qquicksinglepointhandler_p.h" + +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointHandlerPrivate : public QQuickPointerDeviceHandlerPrivate +{ + Q_DECLARE_PUBLIC(QQuickSinglePointHandler) + +public: + static QQuickSinglePointHandlerPrivate* get(QQuickSinglePointHandler *q) { return q->d_func(); } + static const QQuickSinglePointHandlerPrivate* get(const QQuickSinglePointHandler *q) { return q->d_func(); } + + QQuickSinglePointHandlerPrivate(); + + void reset(); + + QQuickHandlerPoint pointInfo; + bool ignoreAdditionalPoints = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOINTERSINGLEHANDLER_P_H + diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 06dddabb65..14443a2f2f 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -735,7 +735,7 @@ void QQuickCanvasItem::updatePolish() for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) { function = it.value().value(); - jsCall->args[0] = QV4::Value::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000); + jsCall->args[0] = QV4::Value::fromUInt32(QDateTime::currentMSecsSinceEpoch()); function->call(jsCall); } } diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h index b7c4fa5b67..7e9b18e101 100644 --- a/src/quick/items/qquickflickable_p.h +++ b/src/quick/items/qquickflickable_p.h @@ -117,7 +117,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem public: QQuickFlickable(QQuickItem *parent=nullptr); - ~QQuickFlickable(); + ~QQuickFlickable() override; QQmlListProperty<QObject> flickableData(); QQmlListProperty<QQuickItem> flickableChildren(); diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index fabd3ef03b..0cd4c446d9 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4444,6 +4444,8 @@ void QQuickItem::update() When the scene graph processes the request, it will call updatePolish() on this item. + + \sa updatePolish(), QQuickTest::qIsPolishScheduled() */ void QQuickItem::polish() { diff --git a/src/quick/items/qquickitemviewfxitem.cpp b/src/quick/items/qquickitemviewfxitem.cpp index f9c65967ea..60e9d7b115 100644 --- a/src/quick/items/qquickitemviewfxitem.cpp +++ b/src/quick/items/qquickitemviewfxitem.cpp @@ -45,9 +45,9 @@ QT_BEGIN_NAMESPACE QQuickItemViewFxItem::QQuickItemViewFxItem(QQuickItem *item, bool ownItem, QQuickItemChangeListener* changeListener) : item(item) - , ownItem(ownItem) , changeListener(changeListener) , transitionableItem(nullptr) + , ownItem(ownItem) , releaseAfterTransition(false) , trackGeom(false) { diff --git a/src/quick/items/qquickitemviewfxitem_p_p.h b/src/quick/items/qquickitemviewfxitem_p_p.h index 48ffe248bc..3bc5ba440c 100644 --- a/src/quick/items/qquickitemviewfxitem_p_p.h +++ b/src/quick/items/qquickitemviewfxitem_p_p.h @@ -94,13 +94,13 @@ public: virtual bool contains(qreal x, qreal y) const = 0; - int index = -1; QPointer<QQuickItem> item; - bool ownItem; QQuickItemChangeListener *changeListener; QQuickItemViewTransitionableItem *transitionableItem; - bool releaseAfterTransition; - bool trackGeom; + int index = -1; + bool ownItem : 1; + bool releaseAfterTransition : 1; + bool trackGeom : 1; }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index cad598d2c0..3aa00340b2 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -245,7 +245,11 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType) { - QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(qmlEngine(item), item); + auto engine = qmlEngine(item); + if (!engine) + return; + + QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(engine, item); for (int i = 0; i < uniformData[shaderType].size(); ++i) { if (signalMappers[shaderType].at(i) == 0) continue; @@ -317,7 +321,8 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, Key::ShaderType shaderType, const QByteArray &code) { - QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(qmlEngine(item), item); + auto engine = qmlEngine(item); + QQmlPropertyCache *propCache = (engine) ? QQmlData::ensurePropertyCache(engine, item) : nullptr; int index = 0; int typeIndex = -1; int typeLength = 0; @@ -350,9 +355,11 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, } else if (nameLength > srLen && qstrncmp("qt_SubRect_", s + nameIndex, srLen) == 0) { d.specialType = UniformData::SubRect; } else { - if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) { - if (!pd->isFunction()) - d.propertyIndex = pd->coreIndex(); + if (propCache) { + if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) { + if (!pd->isFunction()) + d.propertyIndex = pd->coreIndex(); + } } const int mappedId = uniformData[shaderType].size() | (shaderType << 16); mapper = new QtPrivate::MappedSlotObject([this, mappedId](){ diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index eaf0e4cf89..b1900c5b7a 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -1774,6 +1774,16 @@ QQuickTableView::QQuickTableView(QQuickItem *parent) setFlag(QQuickItem::ItemIsFocusScope); } +QQuickTableView::~QQuickTableView() +{ +} + +QQuickTableView::QQuickTableView(QQuickTableViewPrivate &dd, QQuickItem *parent) + : QQuickFlickable(dd, parent) +{ + setFlag(QQuickItem::ItemIsFocusScope); +} + int QQuickTableView::rows() const { return d_func()->tableSize.height(); diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h index 9fcd4c6c17..c5197b4230 100644 --- a/src/quick/items/qquicktableview_p.h +++ b/src/quick/items/qquicktableview_p.h @@ -82,7 +82,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableView : public QQuickFlickable public: QQuickTableView(QQuickItem *parent = nullptr); - + ~QQuickTableView() override; int rows() const; int columns() const; @@ -98,8 +98,8 @@ public: QJSValue columnWidthProvider() const; void setColumnWidthProvider(QJSValue provider); - QVariant model() const; - void setModel(const QVariant &newModel); + virtual QVariant model() const; + virtual void setModel(const QVariant &newModel); QQmlComponent *delegate() const; void setDelegate(QQmlComponent *); @@ -130,6 +130,9 @@ protected: void viewportMoved(Qt::Orientations orientation) override; void componentComplete() override; +protected: + QQuickTableView(QQuickTableViewPrivate &dd, QQuickItem *parent); + private: Q_DISABLE_COPY(QQuickTableView) Q_DECLARE_PRIVATE(QQuickTableView) diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index 504d629b3e..792aa31a88 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -1051,7 +1051,7 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText if (text.contains(QChar::ObjectReplacementCharacter)) { QTextFrame *frame = qobject_cast<QTextFrame *>(textDocument->objectForFormat(charFormat)); - if (frame && frame->frameFormat().position() == QTextFrameFormat::InFlow) { + if (!frame || frame->frameFormat().position() == QTextFrameFormat::InFlow) { int blockRelativePosition = textPos - block.position(); QTextLine line = block.layout()->lineForTextPosition(blockRelativePosition); if (!currentLine().isValid() diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index dd5960e925..b5a68a2283 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -4608,6 +4608,62 @@ void QQuickWindow::resetOpenGLState() */ /*! + \qmlproperty QWindow Window::transientParent + \since 5.13 + + The window for which this window is a transient pop-up. + + This is a hint to the window manager that this window is a dialog or pop-up + on behalf of the transient parent. It usually means that the transient + window will be centered over its transient parent when it is initially + shown, that minimizing the parent window will also minimize the transient + window, and so on; however results vary somewhat from platform to platform. + + Normally if you declare a Window inside an Item or inside another Window, + this relationship is deduced automatically. In that case, if you declare + this window's \l visible property \c true, it will not actually be shown + until the \c transientParent window is shown. + + However if you set this property, then Qt Quick will no longer wait until + the \c transientParent window is shown before showing this window. If you + want to to be able to show a transient window independently of the "parent" + Item or Window within which it was declared, you can remove that + relationship by setting \c transientParent to \c null: + + \l qml + import QtQuick.Window 2.13 + + Window { + // visible is false by default + Window { + transientParent: null + visible: true + } + } + \qml + + In order to cause the window to be centered above its transient parent by + default, depending on the window manager, it may also be necessary to set + the \l Window::flags property with a suitable \l Qt::WindowType (such as + \c Qt::Dialog). +*/ + +/*! + \property QQuickWindow::transientParent + \brief The window for which this window is a transient pop-up. + \since 5.13 + + This is a hint to the window manager that this window is a dialog or pop-up + on behalf of the transient parent, which may be any kind of \l QWindow. + + In order to cause the window to be centered above its transient parent by + default, depending on the window manager, it may also be necessary to set + the \l flags property with a suitable \l Qt::WindowType (such as \c Qt::Dialog). + + \sa parent() + */ + +/*! \qmlproperty Item Window::activeFocusItem \since 5.1 diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index ab3f49d5b6..2b109c0897 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -124,7 +124,8 @@ void QQuickWindowQmlImpl::componentComplete() Q_D(QQuickWindowQmlImpl); d->complete = true; QQuickItem *itemParent = qmlobject_cast<QQuickItem *>(QObject::parent()); - if (itemParent && !itemParent->window()) { + const bool transientParentAlreadySet = QQuickWindowPrivate::get(this)->transientParentPropertySet; + if (!transientParentAlreadySet && itemParent && !itemParent->window()) { qCDebug(lcTransient) << "window" << title() << "has invisible Item parent" << itemParent << "transientParent" << transientParent() << "declared visibility" << d->visibility << "; delaying show"; connect(itemParent, &QQuickItem::windowChanged, this, @@ -210,6 +211,9 @@ void QQuickWindowModule::defineModule() qmlRegisterUncreatableType<QQuickScreen,1>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property.")); qmlRegisterUncreatableType<QQuickScreenInfo,2>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property.")); qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property.")); + qmlRegisterRevision<QWindow,13>(uri, 2, 13); + qmlRegisterRevision<QQuickWindow,13>(uri, 2, 13); + qmlRegisterType<QQuickWindowQmlImpl,13>(uri, 2, 13, "Window"); } QT_END_NAMESPACE diff --git a/src/quick/quick.pro b/src/quick/quick.pro index 0f5f5abca3..37d2ad1172 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -21,7 +21,6 @@ QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf ANDROID_LIB_DEPENDENCIES = \ lib/libQt5QuickParticles.so MODULE_PLUGIN_TYPES += \ - accessible/libqtaccessiblequick.so \ scenegraph ANDROID_BUNDLED_FILES += \ qml \ diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h index 526f52b7e5..3b78f78a0e 100644 --- a/src/quick/scenegraph/util/qsgimagenode.h +++ b/src/quick/scenegraph/util/qsgimagenode.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGImageNode : public QSGGeometryNode { public: - ~QSGImageNode() override { } + ~QSGImageNode() override = default; virtual void setRect(const QRectF &rect) = 0; inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } diff --git a/src/quick/scenegraph/util/qsgninepatchnode.h b/src/quick/scenegraph/util/qsgninepatchnode.h index e76afd3c4a..b690a50e9d 100644 --- a/src/quick/scenegraph/util/qsgninepatchnode.h +++ b/src/quick/scenegraph/util/qsgninepatchnode.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGNinePatchNode : public QSGGeometryNode { public: - ~QSGNinePatchNode() override { } + ~QSGNinePatchNode() override = default; virtual void setTexture(QSGTexture *texture) = 0; virtual void setBounds(const QRectF &bounds) = 0; diff --git a/src/quick/scenegraph/util/qsgrectanglenode.h b/src/quick/scenegraph/util/qsgrectanglenode.h index ba52b65b07..c435dc790f 100644 --- a/src/quick/scenegraph/util/qsgrectanglenode.h +++ b/src/quick/scenegraph/util/qsgrectanglenode.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGRectangleNode : public QSGGeometryNode { public: - ~QSGRectangleNode() override { } + ~QSGRectangleNode() override = default; virtual void setRect(const QRectF &rect) = 0; inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 982d05691d..720f08f69b 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -49,6 +49,7 @@ # include <qopenglfunctions.h> # include <QtGui/qopenglcontext.h> # include <QtGui/qopenglfunctions.h> +# include <QtGui/private/qopengltextureuploader_p.h> # include <private/qsgdefaultrendercontext_p.h> #endif #include <private/qsgmaterialshader_p.h> @@ -89,7 +90,7 @@ static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK" QT_BEGIN_NAMESPACE -#if QT_CONFIG(opengl) +#if QT_CONFIG(opengl) && !defined(QT_NO_DEBUG) inline static bool isPowerOfTwo(int x) { // Assumption: x >= 1 @@ -755,9 +756,7 @@ void QSGPlainTexture::bind() // ### TODO: check for out-of-memory situations... - QImage tmp = (m_image.format() == QImage::Format_RGB32 || m_image.format() == QImage::Format_ARGB32_Premultiplied) - ? m_image - : m_image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption; // Downscale the texture to fit inside the max texture limit if it is too big. // It would be better if the image was already downscaled to the right size, @@ -771,75 +770,19 @@ void QSGPlainTexture::bind() max = rc->maxTextureSize(); else funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); - if (tmp.width() > max || tmp.height() > max) { - tmp = tmp.scaled(qMin(max, tmp.width()), qMin(max, tmp.height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - m_texture_size = tmp.size(); - } + + m_texture_size = m_texture_size.boundedTo(QSize(max, max)); // Scale to a power of two size if mipmapping is requested and the // texture is npot and npot textures are not properly supported. if (mipmapFiltering() != QSGTexture::None - && (!isPowerOfTwo(m_texture_size.width()) || !isPowerOfTwo(m_texture_size.height())) && !funcs->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) { - tmp = tmp.scaled(qNextPowerOfTwo(m_texture_size.width()), qNextPowerOfTwo(m_texture_size.height()), - Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - m_texture_size = tmp.size(); + options |= QOpenGLTextureUploader::PowerOfTwoBindOption; } - if (tmp.width() * 4 != tmp.bytesPerLine()) - tmp = tmp.copy(); - - qint64 convertTime = 0; - if (profileFrames) - convertTime = qsg_renderer_timer.nsecsElapsed(); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareConvert); - updateBindOptions(m_dirty_bind_options); - GLenum externalFormat = GL_RGBA; - GLenum internalFormat = GL_RGBA; - -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) - QString *deviceName = - static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName")); - static bool wrongfullyReportsBgra8888Support = deviceName != 0 - && (deviceName->compare(QLatin1String("samsung SM-T211"), Qt::CaseInsensitive) == 0 - || deviceName->compare(QLatin1String("samsung SM-T210"), Qt::CaseInsensitive) == 0 - || deviceName->compare(QLatin1String("samsung SM-T215"), Qt::CaseInsensitive) == 0); -#else - static bool wrongfullyReportsBgra8888Support = false; -#endif - - if (context->hasExtension(QByteArrayLiteral("GL_EXT_bgra"))) { - externalFormat = GL_BGRA; -#ifdef QT_OPENGL_ES - internalFormat = GL_BGRA; -#else - if (context->isOpenGLES()) - internalFormat = GL_BGRA; -#endif // QT_OPENGL_ES - } else if (!wrongfullyReportsBgra8888Support - && (context->hasExtension(QByteArrayLiteral("GL_EXT_texture_format_BGRA8888")) - || context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888")))) { - externalFormat = GL_BGRA; - internalFormat = GL_BGRA; -#if defined(Q_OS_DARWIN) && !defined(Q_OS_OSX) - } else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) { - externalFormat = GL_BGRA; - internalFormat = GL_RGBA; -#endif - } else { - tmp = std::move(tmp).convertToFormat(QImage::Format_RGBA8888_Premultiplied); - } - - qint64 swizzleTime = 0; - if (profileFrames) - swizzleTime = qsg_renderer_timer.nsecsElapsed(); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareSwizzle); - - funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_texture_size.width(), m_texture_size.height(), 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits()); + QOpenGLTextureUploader::textureImage(GL_TEXTURE_2D, m_image, options, QSize(max, max)); qint64 uploadTime = 0; if (profileFrames) @@ -856,15 +799,11 @@ void QSGPlainTexture::bind() if (profileFrames) { mipmapTime = qsg_renderer_timer.nsecsElapsed(); qCDebug(QSG_LOG_TIME_TEXTURE, - "plain texture uploaded in: %dms (%dx%d), bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d%s", + "plain texture uploaded in: %dms (%dx%d), bind=%d, upload=%d, mipmap=%d%s", int(mipmapTime / 1000000), m_texture_size.width(), m_texture_size.height(), int(bindTime / 1000000), - int((convertTime - bindTime)/1000000), - int((swizzleTime - convertTime)/1000000), - (externalFormat == GL_BGRA ? "BGRA" : "RGBA"), - (internalFormat == GL_BGRA ? "BGRA" : "RGBA"), - int((uploadTime - swizzleTime)/1000000), + int((uploadTime - bindTime)/1000000), int((mipmapTime - uploadTime)/1000000), m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : ""); } diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 0dd2a88ca1..d31e112031 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -61,9 +61,7 @@ #include <QThread> #include <QMutex> #include <QMutexLocker> -#include <QWaitCondition> #include <QBuffer> -#include <QWaitCondition> #include <QtCore/qdebug.h> #include <private/qobject_p.h> #include <QQmlFile> @@ -222,7 +220,6 @@ private: QMutex mutex; QQuickPixmapReaderThreadObject *threadObject; - QWaitCondition waitCondition; #if QT_CONFIG(qml_network) QNetworkAccessManager *networkAccessManager(); diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro index 8fef435d98..acd5546a02 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro @@ -1,13 +1,12 @@ CONFIG += testcase TARGET = tst_qqmldebugjs -QT += qml testlib gui-private core-private +QT += testlib gui-private core-private macos:CONFIG -= app_bundle SOURCES += tst_qqmldebugjs.cpp INCLUDEPATH += ../shared include(../shared/debugutil.pri) -include(../shared/qqmlenginedebugclient.pri) TESTDATA = data/* diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 1202cddc05..1ac28c473b 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -28,10 +28,10 @@ #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../shared/qqmlenginedebugclient.h" #include "../../../shared/util.h" -#include <private/qqmldebugclient_p.h> +#include <private/qqmlenginedebugclient_p.h> +#include <private/qv4debugclient_p.h> #include <private/qqmldebugconnection_p.h> #include <private/qpacket_p.h> @@ -43,72 +43,8 @@ #include <QtCore/qdir.h> #include <QtCore/qmutex.h> #include <QtCore/qlibraryinfo.h> -#include <QtQml/qjsengine.h> - -const char *V8REQUEST = "v8request"; -const char *V8MESSAGE = "v8message"; -const char *SEQ = "seq"; -const char *TYPE = "type"; -const char *COMMAND = "command"; -const char *ARGUMENTS = "arguments"; -const char *STEPACTION = "stepaction"; -const char *STEPCOUNT = "stepcount"; -const char *EXPRESSION = "expression"; -const char *FRAME = "frame"; -const char *CONTEXT = "context"; -const char *GLOBAL = "global"; -const char *DISABLEBREAK = "disable_break"; -const char *HANDLES = "handles"; -const char *INCLUDESOURCE = "includeSource"; -const char *FROMFRAME = "fromFrame"; -const char *TOFRAME = "toFrame"; -const char *BOTTOM = "bottom"; -const char *NUMBER = "number"; -const char *FRAMENUMBER = "frameNumber"; -const char *TYPES = "types"; -const char *IDS = "ids"; -const char *FILTER = "filter"; -const char *FROMLINE = "fromLine"; -const char *TOLINE = "toLine"; -const char *TARGET = "target"; -const char *LINE = "line"; -const char *COLUMN = "column"; -const char *ENABLED = "enabled"; -const char *CONDITION = "condition"; -const char *IGNORECOUNT = "ignoreCount"; -const char *BREAKPOINT = "breakpoint"; -const char *FLAGS = "flags"; - -const char *CONTINEDEBUGGING = "continue"; -const char *EVALUATE = "evaluate"; -const char *LOOKUP = "lookup"; -const char *BACKTRACE = "backtrace"; -const char *SCOPE = "scope"; -const char *SCOPES = "scopes"; -const char *SCRIPTS = "scripts"; -const char *SOURCE = "source"; -const char *SETBREAKPOINT = "setbreakpoint"; -const char *CLEARBREAKPOINT = "clearbreakpoint"; -const char *CHANGEBREAKPOINT = "changebreakpoint"; -const char *SETEXCEPTIONBREAK = "setexceptionbreak"; -const char *VERSION = "version"; -const char *DISCONNECT = "disconnect"; -const char *GARBAGECOLLECTOR = "gc"; - -const char *CONNECT = "connect"; -const char *INTERRUPT = "interrupt"; - -const char *REQUEST = "request"; -const char *IN = "in"; -const char *NEXT = "next"; -const char *OUT = "out"; - -const char *SCRIPT = "script"; -const char *SCRIPTREGEXP = "scriptRegExp"; -const char *EVENT = "event"; - -const char *ALL = "all"; -const char *UNCAUGHT = "uncaught"; +#include <QtCore/qjsonobject.h> +#include <QtCore/qjsonarray.h> const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block"; const char *NORMALMODE = "-qmljsdebugger=port:3771,3800"; @@ -129,13 +65,6 @@ const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml"; const char *ENCODEQMLSCOPE_QMLFILE = "encodeQmlScope.qml"; const char *BREAKONANCHOR_QMLFILE = "breakOnAnchor.qml"; -#define VARIANTMAPINIT \ - QString obj("{}"); \ - QJSValue jsonVal = parser.call(QJSValueList() << obj); \ - jsonVal.setProperty(SEQ,QJSValue(seq++)); \ - jsonVal.setProperty(TYPE,REQUEST); - - #undef QVERIFY #define QVERIFY(statement) \ do {\ @@ -146,9 +75,6 @@ do {\ }\ } while (0) - -class QJSDebugClient; - class tst_QQmlDebugJS : public QQmlDebugTest { Q_OBJECT @@ -231,7 +157,7 @@ private: ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true, bool restrictServices = false); QList<QQmlDebugClient *> createClients() override; - QPointer<QJSDebugClient> m_client; + QPointer<QV4DebugClient> m_client; void targetData(); bool waitForClientSignal(const char *signal, int timeout = 30000); @@ -240,555 +166,7 @@ private: QTime t; }; -class QJSDebugClient : public QQmlDebugClient -{ - Q_OBJECT -public: - enum StepAction - { - Continue, - In, - Out, - Next - }; - - enum Exception - { - All, - Uncaught - }; - - QJSDebugClient(QQmlDebugConnection *connection) - : QQmlDebugClient(QLatin1String("V8Debugger"), connection), - seq(0) - { - parser = jsEngine.evaluate(QLatin1String("JSON.parse")); - stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); - QObject::connect(this, &QQmlDebugClient::stateChanged, - this, &QJSDebugClient::onStateChanged); - } - - void connect(); - void interrupt(); - - void continueDebugging(StepAction stepAction); - void evaluate(QString expr, int frame = -1, int context = -1); - void lookup(QList<int> handles, bool includeSource = false); - void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); - void frame(int number = -1); - void scope(int number = -1, int frameNumber = -1); - void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant()); - void setBreakpoint(QString target, int line = -1, int column = -1, bool enabled = true, - QString condition = QString(), int ignoreCount = -1); - void clearBreakpoint(int breakpoint); - void changeBreakpoint(int breakpoint, bool enabled); - void setExceptionBreak(Exception type, bool enabled = false); - void version(); - void disconnect(); - -protected: - //inherited from QQmlDebugClient - void onStateChanged(State state); - void messageReceived(const QByteArray &data); - -signals: - void connected(); - void interruptRequested(); - void result(); - void failure(); - void stopped(); - -private: - void sendMessage(const QByteArray &); - void flushSendBuffer(); - QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray()); - -private: - QJSEngine jsEngine; - int seq; - - QList<QByteArray> sendBuffer; -public: - QJSValue parser; - QJSValue stringify; - QByteArray response; - -}; - -void QJSDebugClient::connect() -{ - const QJSValue jsonVal = parser.call(QJSValueList() << QLatin1String("{}")); - sendMessage(packMessage(CONNECT, - stringify.call(QJSValueList() << jsonVal).toString().toUtf8())); -} - -void QJSDebugClient::interrupt() -{ - sendMessage(packMessage(INTERRUPT)); -} - -void QJSDebugClient::continueDebugging(StepAction action) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "continue", - // "arguments" : { "stepaction" : <"in", "next" or "out">, - // "stepcount" : <number of steps (default 1)> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING))); - - if (action != Continue) { - QJSValue args = parser.call(QJSValueList() << obj); - switch (action) { - case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN))); - break; - case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT))); - break; - case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT))); - break; - default:break; - } - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::evaluate(QString expr, int frame, int context) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "evaluate", - // "arguments" : { "expression" : <expression to evaluate>, - // "frame" : <number>, - // "context" : <object ID> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE))); - - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr)); - - if (frame != -1) - args.setProperty(QLatin1String(FRAME),QJSValue(frame)); - - if (context != -1) - args.setProperty(QLatin1String(CONTEXT), QJSValue(context)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::lookup(QList<int> handles, bool includeSource) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "lookup", - // "arguments" : { "handles" : <array of handles>, - // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>, - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP))); - - QJSValue args = parser.call(QJSValueList() << obj); - - QString arr("[]"); - QJSValue array = parser.call(QJSValueList() << arr); - int index = 0; - foreach (int handle, handles) { - array.setProperty(index++,QJSValue(handle)); - } - args.setProperty(QLatin1String(HANDLES),array); - - if (includeSource) - args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "backtrace", - // "arguments" : { "fromFrame" : <number> - // "toFrame" : <number> - // "bottom" : <boolean, set to true if the bottom of the stack is requested> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE))); - - QJSValue args = parser.call(QJSValueList() << obj); - - if (fromFrame != -1) - args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame)); - - if (toFrame != -1) - args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame)); - - if (bottom) - args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::frame(int number) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "frame", - // "arguments" : { "number" : <frame number> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME))); - - if (number != -1) { - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(NUMBER),QJSValue(number)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::scope(int number, int frameNumber) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "scope", - // "arguments" : { "number" : <scope number> - // "frameNumber" : <frame number, optional uses selected frame if missing> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE))); - - if (number != -1) { - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(NUMBER),QJSValue(number)); - - if (frameNumber != -1) - args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "scripts", - // "arguments" : { "types" : <types of scripts to retrieve - // set bit 0 for native scripts - // set bit 1 for extension scripts - // set bit 2 for normal scripts - // (default is 4 for normal scripts)> - // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned> - // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned> - // "filter" : <string or number: filter string or script id. - // If a number is specified, then only the script with the same number as its script id will be retrieved. - // If a string is specified, then only scripts whose names contain the filter string will be retrieved.> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS))); - - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(TYPES),QJSValue(types)); - - if (ids.count()) { - QString arr("[]"); - QJSValue array = parser.call(QJSValueList() << arr); - int index = 0; - foreach (int id, ids) { - array.setProperty(index++,QJSValue(id)); - } - args.setProperty(QLatin1String(IDS),array); - } - - if (includeSource) - args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::setBreakpoint(QString target, int line, int column, bool enabled, - QString condition, int ignoreCount) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "setbreakpoint", - // "arguments" : { "type" : "scriptRegExp" - // "target" : <function expression or script identification> - // "line" : <line in script or function> - // "column" : <character position within the line> - // "enabled" : <initial enabled state. True or false, default is true> - // "condition" : <string with break point condition> - // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0> - // } - // } - - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT))); - - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(SCRIPTREGEXP))); - args.setProperty(QLatin1String(TARGET),QJSValue(target)); - - if (line != -1) - args.setProperty(QLatin1String(LINE),QJSValue(line)); - - if (column != -1) - args.setProperty(QLatin1String(COLUMN),QJSValue(column)); - - args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); - - if (!condition.isEmpty()) - args.setProperty(QLatin1String(CONDITION),QJSValue(condition)); - - if (ignoreCount != -1) - args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::clearBreakpoint(int breakpoint) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "clearbreakpoint", - // "arguments" : { "breakpoint" : <number of the break point to clear> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT))); - - QJSValue args = parser.call(QJSValueList() << obj); - - args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "changebreakpoint", - // "arguments" : { "breakpoint" : <number of the break point to change> - // "enabled" : <bool: enables the break type if true, disables if false> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND), QLatin1String(CHANGEBREAKPOINT)); - - QJSValue args = parser.call(QJSValueList() << obj); - - args.setProperty(QLatin1String(BREAKPOINT), breakpoint); - args.setProperty(QLatin1String(ENABLED), enabled); - jsonVal.setProperty(QLatin1String(ARGUMENTS), args); - - const QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::setExceptionBreak(Exception type, bool enabled) -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "setexceptionbreak", - // "arguments" : { "type" : <string: "all", or "uncaught">, - // "enabled" : <optional bool: enables the break type if true> - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK))); - - QJSValue args = parser.call(QJSValueList() << obj); - - if (type == All) - args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL))); - else if (type == Uncaught) - args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT))); - - if (enabled) - args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::version() -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "version", - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION))); - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::disconnect() -{ - // { "seq" : <number>, - // "type" : "request", - // "command" : "disconnect", - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT))); - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(DISCONNECT, json.toString().toUtf8())); -} - -void QJSDebugClient::onStateChanged(State state) -{ - if (state == Enabled) - flushSendBuffer(); -} - -void QJSDebugClient::messageReceived(const QByteArray &data) -{ - QPacket ds(connection()->currentDataStreamVersion(), data); - QByteArray command; - ds >> command; - - if (command == "V8DEBUG") { - QByteArray type; - ds >> type >> response; - - if (type == CONNECT) { - emit connected(); - - } else if (type == INTERRUPT) { - emit interruptRequested(); - - } else if (type == V8MESSAGE) { - QString jsonString(response); - QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - QString type = value.value("type").toString(); - - if (type == "response") { - - if (!value.value("success").toBool()) { - emit failure(); - qDebug() << "Received success == false response from application:" - << value.value("message").toString(); - return; - } - - QString debugCommand(value.value("command").toString()); - if (debugCommand == "backtrace" || - debugCommand == "lookup" || - debugCommand == "setbreakpoint" || - debugCommand == "evaluate" || - debugCommand == "version" || - debugCommand == "disconnect" || - debugCommand == "gc" || - debugCommand == "changebreakpoint" || - debugCommand == "clearbreakpoint" || - debugCommand == "frame" || - debugCommand == "scope" || - debugCommand == "scopes" || - debugCommand == "scripts" || - debugCommand == "source" || - debugCommand == "setexceptionbreak" /*|| - debugCommand == "profile"*/) { - emit result(); - } else { - // DO NOTHING - } - - } else if (type == QLatin1String(EVENT)) { - QString event(value.value(QLatin1String(EVENT)).toString()); - - if (event == "break" || - event == "exception") - emit stopped(); - } - - } - } -} - -void QJSDebugClient::sendMessage(const QByteArray &msg) -{ - if (state() == Enabled) { - QQmlDebugClient::sendMessage(msg); - } else { - sendBuffer.append(msg); - } -} - -void QJSDebugClient::flushSendBuffer() -{ - foreach (const QByteArray &msg, sendBuffer) - QQmlDebugClient::sendMessage(msg); - sendBuffer.clear(); -} - -QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message) -{ - QPacket rs(connection()->currentDataStreamVersion()); - QByteArray cmd = "V8DEBUG"; - rs << cmd << type << message; - return rs.data(); -} void tst_QQmlDebugJS::initTestCase() { @@ -842,7 +220,7 @@ void tst_QQmlDebugJS::interrupt() m_client->connect(); m_client->interrupt(); - QVERIFY(waitForClientSignal(SIGNAL(interruptRequested()))); + QVERIFY(waitForClientSignal(SIGNAL(interrupted()))); } void tst_QQmlDebugJS::getVersion() @@ -896,13 +274,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(ONCOMPLETED_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() @@ -917,13 +293,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(ONCOMPLETED_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() @@ -939,13 +313,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(TIMER_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() @@ -960,13 +332,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(TEST_JSFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptOnComment() @@ -983,13 +353,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment() QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1)); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() @@ -1006,13 +374,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1)); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() @@ -1027,13 +393,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); } void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() @@ -1050,11 +414,8 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() QVERIFY(waitForClientSignal(SIGNAL(stopped()))); //Get the frame index - QString jsonString = m_client->response; - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - { - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); int frameIndex = body.value("index").toInt(); //Verify the value of 'result' @@ -1062,13 +423,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() QVERIFY(waitForClientSignal(SIGNAL(result()))); } - jsonString = m_client->response; - QJSValue val = m_client->parser.call(QJSValueList() << QJSValue(jsonString)); - QVERIFY(val.isObject()); - QJSValue body = val.property(QStringLiteral("body")); - QVERIFY(body.isObject()); - val = body.property("value"); - QVERIFY(val.isNumber()); + const QJsonObject body = m_client->response().body.toObject(); + QVERIFY(!body.isEmpty()); + QJsonValue val = body.value("value"); + QVERIFY(val.isDouble()); const int a = val.toInt(); QVERIFY(a > out); @@ -1086,15 +444,12 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE)); - m_client->continueDebugging(QJSDebugClient::Continue); + m_client->continueDebugging(QV4DebugClient::Continue); QVERIFY(m_process->waitForFinished()); QCOMPARE(m_process->exitStatus(), QProcess::NormalExit); } @@ -1134,34 +489,32 @@ void tst_QQmlDebugJS::clearBreakpoint() QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - //Will hit 1st brakpoint, change this breakpoint enable = false - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + { + //Will hit 1st brakpoint, change this breakpoint enable = false + const QJsonObject body = m_client->response().body.toObject(); + const QJsonArray breakpointsHit = body.value("breakpoints").toArray(); - QVariantMap body = value.value("body").toMap(); - QList<QVariant> breakpointsHit = body.value("breakpoints").toList(); + int breakpoint = breakpointsHit.at(0).toInt(); + m_client->clearBreakpoint(breakpoint); - int breakpoint = breakpointsHit.at(0).toInt(); - m_client->clearBreakpoint(breakpoint); + QVERIFY(waitForClientSignal(SIGNAL(result()))); - QVERIFY(waitForClientSignal(SIGNAL(result()))); + //Continue with debugging + m_client->continueDebugging(QV4DebugClient::Continue); + //Hit 2nd breakpoint + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - //Continue with debugging - m_client->continueDebugging(QJSDebugClient::Continue); - //Hit 2nd breakpoint - QVERIFY(waitForClientSignal(SIGNAL(stopped()))); + //Continue with debugging + m_client->continueDebugging(QV4DebugClient::Continue); + } - //Continue with debugging - m_client->continueDebugging(QJSDebugClient::Continue); //Should stop at 2nd breakpoint QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - jsonString = m_client->response; - value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); + { + const QJsonObject body = m_client->response().body.toObject(); + QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); + } } void tst_QQmlDebugJS::changeBreakpoint() @@ -1174,23 +527,21 @@ void tst_QQmlDebugJS::changeBreakpoint() QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess); bool isStopped = false; - QObject::connect(m_client.data(), &QJSDebugClient::stopped, this, [&]() { isStopped = true; }); + QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() { isStopped = true; }); auto continueDebugging = [&]() { - m_client->continueDebugging(QJSDebugClient::Continue); + m_client->continueDebugging(QV4DebugClient::Continue); isStopped = false; }; m_client->connect(); auto extractBody = [&]() { - const QVariantMap value = m_client->parser.call( - QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap(); - return value.value("body").toMap(); + return m_client->response().body.toObject(); }; - auto extractBreakPointId = [&](const QVariantMap &body) { - const QList<QVariant> breakpointsHit = body.value("breakpoints").toList(); + auto extractBreakPointId = [&](const QJsonObject &body) { + const QJsonArray breakpointsHit = body.value("breakpoints").toArray(); if (breakpointsHit.size() != 1) return -1; return breakpointsHit[0].toInt(); @@ -1198,7 +549,7 @@ void tst_QQmlDebugJS::changeBreakpoint() auto setBreakPoint = [&](int sourceLine, bool enabled) { int id = -1; - auto connection = QObject::connect(m_client.data(), &QJSDebugClient::result, [&]() { + auto connection = QObject::connect(m_client.data(), &QV4DebugClient::result, [&]() { id = extractBody().value("breakpoint").toInt(); }); @@ -1221,7 +572,7 @@ void tst_QQmlDebugJS::changeBreakpoint() auto verifyBreakpoint = [&](int sourceLine, int breakpointId) { QTRY_VERIFY_WITH_TIMEOUT(isStopped, 30000); - const QVariantMap body = extractBody(); + const QJsonObject body = extractBody(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine); QCOMPARE(extractBreakPointId(body), breakpointId); }; @@ -1261,7 +612,7 @@ void tst_QQmlDebugJS::setExceptionBreak() QFETCH(bool, qmlscene); QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess); - m_client->setExceptionBreak(QJSDebugClient::All,true); + m_client->setExceptionBreak(QV4DebugClient::All,true); m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); } @@ -1278,24 +629,19 @@ void tst_QQmlDebugJS::stepNext() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - m_client->continueDebugging(QJSDebugClient::Next); + m_client->continueDebugging(QV4DebugClient::Next); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = m_client->response().body.toObject(); QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(STEPACTION_QMLFILE)); } -static QVariantMap responseBody(QJSDebugClient *client) +static QJsonObject responseBody(QV4DebugClient *client) { - const QString jsonString(client->response); - const QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)) - .toVariant().toMap(); - return value.value("body").toMap(); + return client->response().body.toObject(); } void tst_QQmlDebugJS::stepIn() @@ -1312,12 +658,12 @@ void tst_QQmlDebugJS::stepIn() QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine); - m_client->continueDebugging(QJSDebugClient::In); + m_client->continueDebugging(QV4DebugClient::In); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - const QVariantMap body = responseBody(m_client); + const QJsonObject body = responseBody(m_client); QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); } void tst_QQmlDebugJS::stepOut() @@ -1334,12 +680,12 @@ void tst_QQmlDebugJS::stepOut() QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine); - m_client->continueDebugging(QJSDebugClient::Out); + m_client->continueDebugging(QV4DebugClient::Out); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - const QVariantMap body = responseBody(m_client); + const QJsonObject body = responseBody(m_client); QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); } void tst_QQmlDebugJS::continueDebugging() @@ -1356,16 +702,14 @@ void tst_QQmlDebugJS::continueDebugging() m_client->connect(); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - m_client->continueDebugging(QJSDebugClient::Continue); + m_client->continueDebugging(QV4DebugClient::Continue); QVERIFY(waitForClientSignal(SIGNAL(stopped()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); + const QJsonObject body = responseBody(m_client); QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); + QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), + QLatin1String(STEPACTION_QMLFILE)); } void tst_QQmlDebugJS::backtrace() @@ -1449,32 +793,27 @@ void tst_QQmlDebugJS::evaluateInLocalScope() m_client->frame(); QVERIFY(waitForClientSignal(SIGNAL(result()))); - //Get the frame index - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - int frameIndex = body.value("index").toInt(); - - m_client->evaluate(QLatin1String("root.a"), frameIndex); - QVERIFY(waitForClientSignal(SIGNAL(result()))); - - //Verify the value of 'timer.interval' - jsonString = m_client->response; - value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - body = value.value("body").toMap(); + { + //Get the frame index + const QJsonObject body = responseBody(m_client); + int frameIndex = body.value("index").toInt(); + m_client->evaluate(QLatin1String("root.a"), frameIndex); + QVERIFY(waitForClientSignal(SIGNAL(result()))); + } - QCOMPARE(body.value("value").toInt(),10); + { + //Verify the value of 'timer.interval' + const QJsonObject body = responseBody(m_client); + QCOMPARE(body.value("value").toInt(),10); + } } void tst_QQmlDebugJS::evaluateInContext() { m_connection = new QQmlDebugConnection(); - m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) - + "/qmlscene", this); - m_client = new QJSDebugClient(m_connection); + m_process = new QQmlDebugProcess( + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); + m_client = new QV4DebugClient(m_connection); QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection)); m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE)); @@ -1497,7 +836,7 @@ void tst_QQmlDebugJS::evaluateInContext() QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result()))); QVERIFY(engineClient->engines().count()); - engineClient->queryRootContexts(engineClient->engines()[0].debugId, &success); + engineClient->queryRootContexts(engineClient->engines()[0], &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result()))); @@ -1530,14 +869,12 @@ void tst_QQmlDebugJS::getScripts() m_client->scripts(); QVERIFY(waitForClientSignal(SIGNAL(result()))); - QString jsonString(m_client->response); - QVariantMap value = m_client->parser.call(QJSValueList() - << QJSValue(jsonString)).toVariant().toMap(); - QList<QVariant> scripts = value.value("body").toList(); + const QJsonArray scripts = m_client->response().body.toArray(); QCOMPARE(scripts.count(), 1); - QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml"))); + QVERIFY(scripts.first().toObject()[QStringLiteral("name")].toString() + .endsWith(QStringLiteral("data/test.qml"))); } void tst_QQmlDebugJS::encodeQmlScope() @@ -1551,42 +888,38 @@ void tst_QQmlDebugJS::encodeQmlScope() bool isStopped = false; bool scopesFailed = false; - QObject::connect(m_client.data(), &QJSDebugClient::failure, this, [&]() { - qWarning() << "received failure" << m_client->response; + QObject::connect(m_client.data(), &QV4DebugClient::failure, this, [&]() { + qWarning() << "received failure" << m_client->response().body; scopesFailed = true; m_process->stop(); numFrames = 2; isStopped = false; }); - QObject::connect(m_client.data(), &QJSDebugClient::stopped, this, [&]() { + QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() { m_client->frame(); isStopped = true; }); - QObject::connect(m_client.data(), &QJSDebugClient::result, this, [&]() { - const QVariantMap value = m_client->parser.call( - QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap(); - - const QMap<QString, QVariant> body = value.value("body").toMap(); - const QString command = value.value("command").toString(); + QObject::connect(m_client.data(), &QV4DebugClient::result, this, [&]() { + const QV4DebugClient::Response value = m_client->response(); - if (command == QString("scope")) { + if (value.command == QString("scope")) { // If the scope commands fail we get a failure() signal above. if (++numReceivedScopes == numExpectedScopes) { - m_client->continueDebugging(QJSDebugClient::Continue); + m_client->continueDebugging(QV4DebugClient::Continue); isStopped = false; } - } else if (command == QString("frame")) { + } else if (value.command == QString("frame")) { // We want at least a global scope and some kind of local scope here. - const QList<QVariant> scopes = body.value("scopes").toList(); - if (scopes.length() < 2) + const QJsonArray scopes = value.body.toObject().value("scopes").toArray(); + if (scopes.count() < 2) scopesFailed = true; - for (const QVariant &scope : scopes) { + for (const QJsonValue &scope : scopes) { ++numExpectedScopes; - m_client->scope(scope.toMap().value("index").toInt()); + m_client->scope(scope.toObject().value("index").toInt()); } ++numFrames; @@ -1611,21 +944,21 @@ void tst_QQmlDebugJS::breakOnAnchor() int breaks = 0; bool stopped = false; - QObject::connect(m_client.data(), &QJSDebugClient::stopped, this, [&]() { + QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() { stopped = true; ++breaks; m_client->evaluate("this", 0, -1); }); - QObject::connect(m_client.data(), &QJSDebugClient::result, this, [&]() { + QObject::connect(m_client.data(), &QV4DebugClient::result, this, [&]() { if (stopped) { - m_client->continueDebugging(QJSDebugClient::Continue); + m_client->continueDebugging(QV4DebugClient::Continue); stopped = false; } }); - QObject::connect(m_client.data(), &QJSDebugClient::failure, this, [&]() { - qWarning() << "received failure" << m_client->response; + QObject::connect(m_client.data(), &QV4DebugClient::failure, this, [&]() { + qWarning() << "received failure" << m_client->response().body; }); m_client->setBreakpoint(file, 34); @@ -1643,7 +976,7 @@ void tst_QQmlDebugJS::breakOnAnchor() QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients() { - m_client = new QJSDebugClient(m_connection); + m_client = new QV4DebugClient(m_connection); return QList<QQmlDebugClient *>({m_client}); } @@ -1661,10 +994,9 @@ bool tst_QQmlDebugJS::waitForClientSignal(const char *signal, int timeout) void tst_QQmlDebugJS::checkVersionParameters() { - const QVariantMap value = m_client->parser.call( - QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap(); - QCOMPARE(value.value("command").toString(), QString("version")); - const QVariantMap body = value.value("body").toMap(); + const QV4DebugClient::Response value = m_client->response(); + QCOMPARE(value.command, QString("version")); + const QJsonObject body = value.body.toObject(); QCOMPARE(body.value("UnpausedEvaluate").toBool(), true); QCOMPARE(body.value("ContextEvaluate").toBool(), true); QCOMPARE(body.value("ChangeBreakpoint").toBool(), true); diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro index 54244c6d16..454a1e3ab0 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro @@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle SOURCES += tst_qqmlenginedebuginspectorintegration.cpp -include(../shared/qqmlinspectorclient.pri) -include(../shared/qqmlenginedebugclient.pri) include(../shared/debugutil.pri) TESTDATA = data/* diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp index 249416a3b9..980e2be1f1 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp @@ -26,12 +26,12 @@ ** ****************************************************************************/ -#include "qqmlinspectorclient.h" -#include "qqmlenginedebugclient.h" #include "../shared/debugutil_p.h" #include "../../../shared/util.h" #include <private/qqmldebugconnection_p.h> +#include <private/qqmlenginedebugclient_p.h> +#include <private/qqmlinspectorclient_p.h> #include <QtTest/qtest.h> #include <QtTest/qsignalspy.h> @@ -49,7 +49,7 @@ private: ConnectResult init(bool restrictServices); QList<QQmlDebugClient *> createClients() override; - QmlDebugObjectReference findRootObject(); + QQmlEngineDebugObjectReference findRootObject(); QPointer<QQmlInspectorClient> m_inspectorClient; QPointer<QQmlEngineDebugClient> m_engineDebugClient; @@ -65,23 +65,23 @@ private slots: void destroyObject(); }; -QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject() +QQmlEngineDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject() { bool success = false; m_engineDebugClient->queryAvailableEngines(&success); if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result()))) - return QmlDebugObjectReference(); + return QQmlEngineDebugObjectReference(); - m_engineDebugClient->queryRootContexts(m_engineDebugClient->engines()[0].debugId, &success); + m_engineDebugClient->queryRootContexts(m_engineDebugClient->engines()[0], &success); if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result()))) - return QmlDebugObjectReference(); + return QQmlEngineDebugObjectReference(); int count = m_engineDebugClient->rootContext().contexts.count(); m_engineDebugClient->queryObject( m_engineDebugClient->rootContext().contexts[count - 1].objects[0], &success); if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result()))) - return QmlDebugObjectReference(); + return QQmlEngineDebugObjectReference(); return m_engineDebugClient->object(); } @@ -121,7 +121,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup() QCOMPARE(init(true), ConnectSuccess); bool success = false; - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(rootObject.debugId != -1); const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName(); int lineNumber = rootObject.source.lineNumber; @@ -131,7 +131,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result()))); - foreach (QmlDebugObjectReference child, rootObject.children) { + foreach (QQmlEngineDebugObjectReference child, rootObject.children) { success = false; lineNumber = child.source.lineNumber; columnNumber = child.source.columnNumber; @@ -146,10 +146,10 @@ void tst_QQmlEngineDebugInspectorIntegration::select() { QCOMPARE(init(true), ConnectSuccess); - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QList<int> childIds; int requestId = 0; - foreach (const QmlDebugObjectReference &child, rootObject.children) { + foreach (const QQmlEngineDebugObjectReference &child, rootObject.children) { requestId = m_inspectorClient->select(QList<int>() << child.debugId); QTRY_COMPARE(m_recipient->lastResponseId, requestId); QVERIFY(m_recipient->lastResult); @@ -171,7 +171,7 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject() " color: \"blue\"\n" "}"); - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(rootObject.debugId != -1); QCOMPARE(rootObject.children.length(), 2); @@ -192,7 +192,7 @@ void tst_QQmlEngineDebugInspectorIntegration::moveObject() QCOMPARE(init(true), ConnectSuccess); QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled); - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(rootObject.debugId != -1); QCOMPARE(rootObject.children.length(), 2); @@ -217,7 +217,7 @@ void tst_QQmlEngineDebugInspectorIntegration::destroyObject() QCOMPARE(init(true), ConnectSuccess); QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled); - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(rootObject.debugId != -1); QCOMPARE(rootObject.children.length(), 2); diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro index ed4224446e..5ff65ba276 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro @@ -5,7 +5,6 @@ osx:CONFIG -= app_bundle SOURCES += \ tst_qqmlenginedebugservice.cpp -include(../shared/qqmlenginedebugclient.pri) include(../shared/debugutil.pri) DEFINES += QT_QML_DEBUG_NO_WARNING diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index c613d88b2b..99c90c142f 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -26,7 +26,6 @@ ** ****************************************************************************/ -#include "qqmlenginedebugclient.h" #include "debugutil_p.h" #include "../../../shared/util.h" @@ -36,6 +35,7 @@ #include <private/qqmlmetatype_p.h> #include <private/qqmlproperty_p.h> #include <private/qqmldebugconnection_p.h> +#include <private/qqmlenginedebugclient_p.h> #include <QtTest/qtest.h> #include <QtTest/qsignalspy.h> @@ -60,7 +60,7 @@ #define QVERIFYOBJECT(statement) \ do {\ if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\ - return QmlDebugObjectReference();\ + return QQmlEngineDebugObjectReference();\ }\ } while (0) @@ -126,14 +126,14 @@ public: tst_QQmlEngineDebugService() : m_conn(nullptr), m_dbg(nullptr), m_engine(nullptr), m_rootItem(nullptr) {} private: - QmlDebugObjectReference findRootObject(int context = 0, + QQmlEngineDebugObjectReference findRootObject(int context = 0, bool recursive = false); - QmlDebugPropertyReference findProperty( - const QList<QmlDebugPropertyReference> &props, + QQmlEngineDebugPropertyReference findProperty( + const QList<QQmlEngineDebugPropertyReference> &props, const QString &name) const; void recursiveObjectTest(QObject *o, - const QmlDebugObjectReference &oref, + const QQmlEngineDebugObjectReference &oref, bool recursive) const; void getContexts(); @@ -182,7 +182,7 @@ private slots: void createObjectOnDestruction(); }; -QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( +QQmlEngineDebugObjectReference tst_QQmlEngineDebugService::findRootObject( int context, bool recursive) { bool success = false; @@ -191,7 +191,7 @@ QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( QVERIFYOBJECT(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QVERIFYOBJECT(m_dbg->engines().count()); - m_dbg->queryRootContexts(m_dbg->engines()[0].debugId, &success); + m_dbg->queryRootContexts(m_dbg->engines()[0], &success); QVERIFYOBJECT(success); QVERIFYOBJECT(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); @@ -207,18 +207,18 @@ QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( return m_dbg->object(); } -QmlDebugPropertyReference tst_QQmlEngineDebugService::findProperty( - const QList<QmlDebugPropertyReference> &props, const QString &name) const +QQmlEngineDebugPropertyReference tst_QQmlEngineDebugService::findProperty( + const QList<QQmlEngineDebugPropertyReference> &props, const QString &name) const { - foreach (const QmlDebugPropertyReference &p, props) { + foreach (const QQmlEngineDebugPropertyReference &p, props) { if (p.name == name) return p; } - return QmlDebugPropertyReference(); + return QQmlEngineDebugPropertyReference(); } void tst_QQmlEngineDebugService::recursiveObjectTest( - QObject *o, const QmlDebugObjectReference &oref, bool recursive) const + QObject *o, const QQmlEngineDebugObjectReference &oref, bool recursive) const { const QMetaObject *meta = o->metaObject(); @@ -236,8 +236,8 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( int debugId = QQmlDebugService::idForObject(child); QVERIFY(debugId >= 0); - QmlDebugObjectReference cref; - foreach (const QmlDebugObjectReference &ref, oref.children) { + QQmlEngineDebugObjectReference cref; + foreach (const QQmlEngineDebugObjectReference &ref, oref.children) { QVERIFY(!ref.className.isEmpty()); if (ref.debugId == debugId) { cref = ref; @@ -250,7 +250,7 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( recursiveObjectTest(child, cref, true); } - foreach (const QmlDebugPropertyReference &p, oref.properties) { + foreach (const QQmlEngineDebugPropertyReference &p, oref.properties) { QCOMPARE(p.objectDebugId, QQmlDebugService::idForObject(o)); // signal properties are fake - they are generated from QQmlAbstractBoundSignal children @@ -269,7 +269,8 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( QCOMPARE(p.name, QString::fromUtf8(pmeta.name())); if (pmeta.userType() == QMetaType::QObjectStar) { - const QmlDebugObjectReference ref = qvariant_cast<QmlDebugObjectReference>(p.value); + const QQmlEngineDebugObjectReference ref + = qvariant_cast<QQmlEngineDebugObjectReference>(p.value); QObject *pobj = qvariant_cast<QObject *>(pmeta.read(o)); if (pobj) { if (pobj->objectName().isEmpty()) @@ -312,9 +313,9 @@ void tst_QQmlEngineDebugService::getContexts() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - QList<QmlDebugEngineReference> engines = m_dbg->engines(); + QList<QQmlEngineDebugEngineReference> engines = m_dbg->engines(); QCOMPARE(engines.count(), 1); - m_dbg->queryRootContexts(engines.first().debugId, &success); + m_dbg->queryRootContexts(engines.first(), &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); @@ -441,7 +442,7 @@ void tst_QQmlEngineDebugService::cleanupTestCase() void tst_QQmlEngineDebugService::setMethodBody() { bool success; - QmlDebugObjectReference obj = findRootObject(2); + QQmlEngineDebugObjectReference obj = findRootObject(2); QVERIFY(!obj.className.isEmpty()); QObject *root = m_components.at(2); @@ -483,9 +484,9 @@ void tst_QQmlEngineDebugService::setMethodBody() void tst_QQmlEngineDebugService::watch_property() { - QmlDebugObjectReference obj = findRootObject(); + QQmlEngineDebugObjectReference obj = findRootObject(); QVERIFY(!obj.className.isEmpty()); - QmlDebugPropertyReference prop = findProperty(obj.properties, "width"); + QQmlEngineDebugPropertyReference prop = findProperty(obj.properties, "width"); bool success; @@ -494,7 +495,7 @@ void tst_QQmlEngineDebugService::watch_property() QVERIFY(!success); delete unconnected; - m_dbg->addWatch(QmlDebugPropertyReference(), &success); + m_dbg->addWatch(QQmlEngineDebugPropertyReference(), &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); @@ -528,7 +529,7 @@ void tst_QQmlEngineDebugService::watch_property() void tst_QQmlEngineDebugService::watch_object() { - QmlDebugObjectReference obj = findRootObject(); + QQmlEngineDebugObjectReference obj = findRootObject(); QVERIFY(!obj.className.isEmpty()); bool success; @@ -538,7 +539,7 @@ void tst_QQmlEngineDebugService::watch_object() QVERIFY(!success); delete unconnected; - m_dbg->addWatch(QmlDebugObjectReference(), &success); + m_dbg->addWatch(QQmlEngineDebugObjectReference(), &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); @@ -594,7 +595,7 @@ void tst_QQmlEngineDebugService::watch_expression() int origWidth = m_rootItem->property("width").toInt(); - QmlDebugObjectReference obj = findRootObject(); + QQmlEngineDebugObjectReference obj = findRootObject(); QVERIFY(!obj.className.isEmpty()); bool success; @@ -604,7 +605,7 @@ void tst_QQmlEngineDebugService::watch_expression() QVERIFY(!success); delete unconnected; - m_dbg->addWatch(QmlDebugObjectReference(), expr, &success); + m_dbg->addWatch(QQmlEngineDebugObjectReference(), expr, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); @@ -654,7 +655,7 @@ void tst_QQmlEngineDebugService::watch_expression_data() void tst_QQmlEngineDebugService::watch_context() { - QmlDebugContextReference c; + QQmlEngineDebugContextReference c; QTest::ignoreMessage(QtWarningMsg, "QQmlEngineDebugClient::addWatch(): Not implemented"); bool success; m_dbg->addWatch(c, QString(), &success); @@ -663,7 +664,7 @@ void tst_QQmlEngineDebugService::watch_context() void tst_QQmlEngineDebugService::watch_file() { - QmlDebugFileReference f; + QQmlEngineDebugFileReference f; QTest::ignoreMessage(QtWarningMsg, "QQmlEngineDebugClient::addWatch(): Not implemented"); bool success; m_dbg->addWatch(f, &success); @@ -684,10 +685,10 @@ void tst_QQmlEngineDebugService::queryAvailableEngines() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); // TODO test multiple engines - QList<QmlDebugEngineReference> engines = m_dbg->engines(); + QList<QQmlEngineDebugEngineReference> engines = m_dbg->engines(); QCOMPARE(engines.count(), 1); - foreach (const QmlDebugEngineReference &e, engines) { + foreach (const QQmlEngineDebugEngineReference &e, engines) { QCOMPARE(e.debugId, QQmlDebugService::idForObject(m_engine)); QCOMPARE(e.name, m_engine->objectName()); } @@ -700,19 +701,19 @@ void tst_QQmlEngineDebugService::queryRootContexts() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QVERIFY(m_dbg->engines().count()); - int engineId = m_dbg->engines()[0].debugId; + const QQmlEngineDebugEngineReference engine = m_dbg->engines()[0]; QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr); - unconnected->queryRootContexts(engineId, &success); + unconnected->queryRootContexts(engine, &success); QVERIFY(!success); delete unconnected; - m_dbg->queryRootContexts(engineId, &success); + m_dbg->queryRootContexts(engine, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QQmlContext *actualContext = m_engine->rootContext(); - QmlDebugContextReference context = m_dbg->rootContext(); + QQmlEngineDebugContextReference context = m_dbg->rootContext(); QCOMPARE(context.debugId, QQmlDebugService::idForObject(actualContext)); QCOMPARE(context.name, actualContext->objectName()); @@ -730,7 +731,7 @@ void tst_QQmlEngineDebugService::queryObject() bool success; - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr); @@ -742,11 +743,11 @@ void tst_QQmlEngineDebugService::queryObject() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - QmlDebugObjectReference obj = m_dbg->object(); + QQmlEngineDebugObjectReference obj = m_dbg->object(); QVERIFY(!obj.className.isEmpty()); // check source as defined in main() - QmlDebugFileReference source = obj.source; + QQmlEngineDebugFileReference source = obj.source; QCOMPARE(source.url, QUrl::fromLocalFile("")); QCOMPARE(source.lineNumber, 3); QCOMPARE(source.columnNumber, 1); @@ -755,14 +756,14 @@ void tst_QQmlEngineDebugService::queryObject() recursiveObjectTest(m_rootItem, obj, recursive); if (recursive) { - foreach (const QmlDebugObjectReference &child, obj.children) { + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); QVERIFY(child.properties.count() > 0); } - QmlDebugObjectReference rect; - QmlDebugObjectReference text; - foreach (const QmlDebugObjectReference &child, obj.children) { + QQmlEngineDebugObjectReference rect; + QQmlEngineDebugObjectReference text; + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); if (child.className == "Rectangle") rect = child; @@ -777,7 +778,7 @@ void tst_QQmlEngineDebugService::queryObject() QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue"))); } else { - foreach (const QmlDebugObjectReference &child, obj.children) { + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); QCOMPARE(child.properties.count(), 0); } @@ -798,7 +799,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() bool success; - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName(); @@ -821,11 +822,11 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->objects().count(), 1); - QmlDebugObjectReference obj = m_dbg->objects().first(); + QQmlEngineDebugObjectReference obj = m_dbg->objects().first(); QVERIFY(!obj.className.isEmpty()); // check source as defined in main() - QmlDebugFileReference source = obj.source; + QQmlEngineDebugFileReference source = obj.source; QCOMPARE(source.url, QUrl(fileName)); QCOMPARE(source.lineNumber, lineNumber); QCOMPARE(source.columnNumber, columnNumber); @@ -834,14 +835,14 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() recursiveObjectTest(m_rootItem, obj, recursive); if (recursive) { - foreach (const QmlDebugObjectReference &child, obj.children) { + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); QVERIFY(child.properties.count() > 0); } - QmlDebugObjectReference rect; - QmlDebugObjectReference text; - foreach (const QmlDebugObjectReference &child, obj.children) { + QQmlEngineDebugObjectReference rect; + QQmlEngineDebugObjectReference text; + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); if (child.className == "Rectangle") rect = child; @@ -856,7 +857,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue"))); } else { - foreach (const QmlDebugObjectReference &child, obj.children) { + foreach (const QQmlEngineDebugObjectReference &child, obj.children) { QVERIFY(!child.className.isEmpty()); QCOMPARE(child.properties.count(), 0); } @@ -873,7 +874,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation_data() void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() { - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); int contextId = rootObject.contextDebugId; QQmlContext *context = qobject_cast<QQmlContext *>(QQmlDebugService::objectForId(contextId)); @@ -900,7 +901,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - foreach (QmlDebugObjectReference child, rootObject.children) { + foreach (QQmlEngineDebugObjectReference child, rootObject.children) { QVERIFY(!child.className.isEmpty()); success = false; lineNumber = child.source.lineNumber; @@ -923,7 +924,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - foreach (QmlDebugObjectReference child, rootObject.children) { + foreach (QQmlEngineDebugObjectReference child, rootObject.children) { QVERIFY(!child.className.isEmpty()); success = false; lineNumber = child.source.lineNumber; @@ -939,7 +940,7 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes() { bool success; - QmlDebugObjectReference rootObject = findRootObject(4, true); + QQmlEngineDebugObjectReference rootObject = findRootObject(4, true); QVERIFY(!rootObject.className.isEmpty()); QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr); @@ -951,7 +952,7 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - QmlDebugObjectReference obj = m_dbg->object(); + QQmlEngineDebugObjectReference obj = m_dbg->object(); QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties, "modelIndex").value, @@ -962,14 +963,14 @@ void tst_QQmlEngineDebugService::jsonData() { bool success; - QmlDebugObjectReference rootObject = findRootObject(5, true); + QQmlEngineDebugObjectReference rootObject = findRootObject(5, true); QVERIFY(!rootObject.className.isEmpty()); m_dbg->queryObject(rootObject, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - QmlDebugObjectReference obj = m_dbg->object(); + QQmlEngineDebugObjectReference obj = m_dbg->object(); QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties, "data").value, @@ -1064,10 +1065,10 @@ void tst_QQmlEngineDebugService::queryExpressionResultBC_data() void tst_QQmlEngineDebugService::setBindingForObject() { - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); QVERIFY(rootObject.debugId != -1); - QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); + QQmlEngineDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); QCOMPARE(widthPropertyRef.value, QVariant(10)); QCOMPARE(widthPropertyRef.binding, QString()); @@ -1112,7 +1113,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); QCOMPARE(rootObject.children.size(), 5); // Rectangle, Text, MouseArea, Component.onCompleted, NonScriptPropertyElement - QmlDebugObjectReference mouseAreaObject = rootObject.children.at(2); + QQmlEngineDebugObjectReference mouseAreaObject = rootObject.children.at(2); QVERIFY(!mouseAreaObject.className.isEmpty()); m_dbg->queryObjectRecursive(mouseAreaObject, &success); QVERIFY(success); @@ -1120,7 +1121,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() mouseAreaObject = m_dbg->object(); QCOMPARE(mouseAreaObject.className, QString("MouseArea")); - QmlDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered"); + QQmlEngineDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered"); QCOMPARE(onEnteredRef.name, QString("onEntered")); // Sorry, can't do that anymore: QCOMPARE(onEnteredRef.value, QVariant("{ console.log('hello') }")); @@ -1149,10 +1150,10 @@ void tst_QQmlEngineDebugService::setBindingForObject() void tst_QQmlEngineDebugService::resetBindingForObject() { - QmlDebugObjectReference rootObject = findRootObject(); + QQmlEngineDebugObjectReference rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); QVERIFY(rootObject.debugId != -1); - QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); + QQmlEngineDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); bool success = false; @@ -1188,7 +1189,7 @@ void tst_QQmlEngineDebugService::resetBindingForObject() rootObject = findRootObject(); QVERIFY(!rootObject.className.isEmpty()); - QmlDebugPropertyReference boldPropertyRef = findProperty(rootObject.properties, "font.bold"); + QQmlEngineDebugPropertyReference boldPropertyRef = findProperty(rootObject.properties, "font.bold"); QCOMPARE(boldPropertyRef.value.toBool(), false); QCOMPARE(boldPropertyRef.binding, QString()); @@ -1200,7 +1201,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() const int sourceIndex = 3; - QmlDebugObjectReference obj = findRootObject(sourceIndex); + QQmlEngineDebugObjectReference obj = findRootObject(sourceIndex); QVERIFY(!obj.className.isEmpty()); QVERIFY(obj.debugId != -1); QVERIFY(obj.children.count() >= 2); @@ -1233,11 +1234,11 @@ void tst_QQmlEngineDebugService::setBindingInStates() // change the binding - QmlDebugObjectReference state = obj.children[1]; + QQmlEngineDebugObjectReference state = obj.children[1]; QCOMPARE(state.className, QString("State")); QVERIFY(state.children.count() > 0); - QmlDebugObjectReference propertyChange = state.children[0]; + QQmlEngineDebugObjectReference propertyChange = state.children[0]; QVERIFY(!propertyChange.className.isEmpty()); QVERIFY(propertyChange.debugId != -1); @@ -1316,43 +1317,43 @@ void tst_QQmlEngineDebugService::queryObjectTree() { const int sourceIndex = 3; - QmlDebugObjectReference obj = findRootObject(sourceIndex, true); + QQmlEngineDebugObjectReference obj = findRootObject(sourceIndex, true); QVERIFY(!obj.className.isEmpty()); QVERIFY(obj.debugId != -1); QVERIFY(obj.children.count() >= 2); // check state - QmlDebugObjectReference state = obj.children[1]; + QQmlEngineDebugObjectReference state = obj.children[1]; QCOMPARE(state.className, QString("State")); QVERIFY(state.children.count() > 0); - QmlDebugObjectReference propertyChange = state.children[0]; + QQmlEngineDebugObjectReference propertyChange = state.children[0]; QVERIFY(!propertyChange.className.isEmpty()); QVERIFY(propertyChange.debugId != -1); - QmlDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties,"target"); + QQmlEngineDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties,"target"); QCOMPARE(propertyChangeTarget.objectDebugId, propertyChange.debugId); - QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value); + QQmlEngineDebugObjectReference targetReference = qvariant_cast<QQmlEngineDebugObjectReference>(propertyChangeTarget.value); QVERIFY(!targetReference.className.isEmpty()); QCOMPARE(targetReference.debugId, -1); QCOMPARE(targetReference.name, QString("<unnamed object>")); // check transition - QmlDebugObjectReference transition = obj.children[0]; + QQmlEngineDebugObjectReference transition = obj.children[0]; QCOMPARE(transition.className, QString("Transition")); QCOMPARE(findProperty(transition.properties,"from").value.toString(), QString("*")); QCOMPARE(findProperty(transition.properties,"to").value, findProperty(state.properties,"name").value); QVERIFY(transition.children.count() > 0); - QmlDebugObjectReference animation = transition.children[0]; + QQmlEngineDebugObjectReference animation = transition.children[0]; QVERIFY(!animation.className.isEmpty()); QVERIFY(animation.debugId != -1); - QmlDebugPropertyReference animationTarget = findProperty(animation.properties,"target"); + QQmlEngineDebugPropertyReference animationTarget = findProperty(animation.properties,"target"); QCOMPARE(animationTarget.objectDebugId, animation.debugId); - targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value); + targetReference = qvariant_cast<QQmlEngineDebugObjectReference>(animationTarget.value); QVERIFY(!targetReference.className.isEmpty()); QCOMPARE(targetReference.debugId, -1); QCOMPARE(targetReference.name, QString("<unnamed object>")); @@ -1362,7 +1363,7 @@ void tst_QQmlEngineDebugService::queryObjectTree() } void tst_QQmlEngineDebugService::asynchronousCreate() { - QmlDebugObjectReference object; + QQmlEngineDebugObjectReference object; auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) { object.debugId = objectId; }); diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro index 3d4473c693..0d42030b52 100644 --- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro +++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro @@ -6,7 +6,6 @@ osx:CONFIG -= app_bundle SOURCES += tst_qqmlinspector.cpp -include(../shared/qqmlinspectorclient.pri) include(../shared/debugutil.pri) TESTDATA = data/* diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index 5c9506eb21..6685558bb5 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -26,12 +26,12 @@ ** ****************************************************************************/ -#include "qqmlinspectorclient.h" #include "../shared/debugutil_p.h" #include "../shared/qqmldebugprocess_p.h" #include "../../../shared/util.h" #include <private/qqmldebugconnection_p.h> +#include <private/qqmlinspectorclient_p.h> #include <QtTest/qtest.h> #include <QtTest/qsignalspy.h> diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index e0bd5413fe..085eb7b87a 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -201,7 +201,7 @@ private: CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith }; - ConnectResult connect(bool block, const QString &testFile, bool recordFromStart = true, + ConnectResult connect(bool block, const QString &file, bool recordFromStart = true, uint flushInterval = 0, bool restrictServices = true, const QString &executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"); @@ -209,8 +209,8 @@ private: void checkTraceReceived(); void checkJsHeap(); bool verify(MessageListType type, int expectedPosition, - const QQmlProfilerEventType &expectedType, quint32 checks, - const QVector<qint64> &numbers); + const QQmlProfilerEventType &expected, quint32 checks, + const QVector<qint64> &expectedNumbers); QList<QQmlDebugClient *> createClients() override; QScopedPointer<QQmlProfilerTestClient> m_client; @@ -235,7 +235,7 @@ private slots: private: bool m_recordFromStart = true; - bool m_flushInterval = 0; + bool m_flushInterval = false; bool m_isComplete = false; // Don't use ({...}) here as MSVC will interpret that as the "QVector(int size)" ctor. @@ -305,7 +305,7 @@ void tst_QQmlProfilerService::checkJsHeap() qint64 used = 0; qint64 lastTimestamp = -1; foreach (const QQmlProfilerEvent &message, m_client->jsHeapMessages) { - const qint64 amount = message.number<qint64>(0); + const auto amount = message.number<qint64>(0); const QQmlProfilerEventType &type = m_client->types.at(message.typeIndex()); switch (type.detailType()) { case HeapPage: @@ -328,10 +328,11 @@ void tst_QQmlProfilerService::checkJsHeap() if (lastTimestamp == -1) { lastTimestamp = message.timestamp(); continue; - } else if (message.timestamp() == lastTimestamp) { - continue; } + if (message.timestamp() == lastTimestamp) + continue; + lastTimestamp = message.timestamp(); QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1") @@ -759,7 +760,7 @@ void tst_QQmlProfilerService::memory() QVERIFY(m_client); int smallItems = 0; - for (auto message : m_client->jsHeapMessages) { + for (const auto& message : m_client->jsHeapMessages) { const QQmlProfilerEventType &type = m_client->types[message.typeIndex()]; if (type.detailType() == SmallItem) ++smallItems; @@ -793,7 +794,7 @@ void tst_QQmlProfilerService::compile() checkJsHeap(); Message rangeStage = MaximumMessage; - for (auto message : m_client->qmlMessages) { + for (const auto& message : m_client->qmlMessages) { const QQmlProfilerEventType &type = m_client->types[message.typeIndex()]; if (type.rangeType() == Compiling) { switch (rangeStage) { diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h deleted file mode 100644 index 5d74f2d43c..0000000000 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module 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$ -** -****************************************************************************/ - -#ifndef QQMLENGINEDEBUGCLIENT_H -#define QQMLENGINEDEBUGCLIENT_H - -#include <private/qqmldebugclient_p.h> -#include <private/qpacket_p.h> - -#include <QtCore/qurl.h> -#include <QtCore/qvariant.h> - -struct QmlDebugPropertyReference -{ - QmlDebugPropertyReference() - : objectDebugId(-1), hasNotifySignal(false) - { - } - - QmlDebugPropertyReference &operator=( - const QmlDebugPropertyReference &o) - { - objectDebugId = o.objectDebugId; name = o.name; value = o.value; - valueTypeName = o.valueTypeName; binding = o.binding; - hasNotifySignal = o.hasNotifySignal; - return *this; - } - - int objectDebugId; - QString name; - QVariant value; - QString valueTypeName; - QString binding; - bool hasNotifySignal; -}; - -struct QmlDebugFileReference -{ - QmlDebugFileReference() - : lineNumber(-1), columnNumber(-1) - { - } - - QmlDebugFileReference &operator=( - const QmlDebugFileReference &o) - { - url = o.url; lineNumber = o.lineNumber; columnNumber = o.columnNumber; - return *this; - } - - QUrl url; - int lineNumber; - int columnNumber; -}; - -struct QmlDebugObjectReference -{ - QmlDebugObjectReference() - : debugId(-1), contextDebugId(-1) - { - } - - QmlDebugObjectReference(int id) - : debugId(id), contextDebugId(-1) - { - } - - QmlDebugObjectReference &operator=( - const QmlDebugObjectReference &o) - { - debugId = o.debugId; className = o.className; idString = o.idString; - name = o.name; source = o.source; contextDebugId = o.contextDebugId; - properties = o.properties; children = o.children; - return *this; - } - int debugId; - QString className; - QString idString; - QString name; - QmlDebugFileReference source; - int contextDebugId; - QList<QmlDebugPropertyReference> properties; - QList<QmlDebugObjectReference> children; -}; - -Q_DECLARE_METATYPE(QmlDebugObjectReference) - -struct QmlDebugContextReference -{ - QmlDebugContextReference() - : debugId(-1) - { - } - - QmlDebugContextReference &operator=( - const QmlDebugContextReference &o) - { - debugId = o.debugId; name = o.name; objects = o.objects; - contexts = o.contexts; - return *this; - } - - int debugId; - QString name; - QList<QmlDebugObjectReference> objects; - QList<QmlDebugContextReference> contexts; -}; - -struct QmlDebugEngineReference -{ - QmlDebugEngineReference() - : debugId(-1) - { - } - - QmlDebugEngineReference(int id) - : debugId(id) - { - } - - QmlDebugEngineReference &operator=( - const QmlDebugEngineReference &o) - { - debugId = o.debugId; name = o.name; - return *this; - } - - int debugId; - QString name; -}; - -class QQmlEngineDebugClient : public QQmlDebugClient -{ - Q_OBJECT -public: - explicit QQmlEngineDebugClient(QQmlDebugConnection *conn); - - quint32 addWatch(const QmlDebugPropertyReference &, - bool *success); - quint32 addWatch(const QmlDebugContextReference &, const QString &, - bool *success); - quint32 addWatch(const QmlDebugObjectReference &, const QString &, - bool *success); - quint32 addWatch(const QmlDebugObjectReference &, - bool *success); - quint32 addWatch(const QmlDebugFileReference &, - bool *success); - - void removeWatch(quint32 watch, bool *success); - - quint32 queryAvailableEngines(bool *success); - quint32 queryRootContexts(const QmlDebugEngineReference &, - bool *success); - quint32 queryObject(const QmlDebugObjectReference &, - bool *success); - quint32 queryObjectsForLocation(const QString &file, - int lineNumber, int columnNumber, bool *success); - quint32 queryObjectRecursive(const QmlDebugObjectReference &, - bool *success); - quint32 queryObjectsForLocationRecursive(const QString &file, - int lineNumber, int columnNumber, bool *success); - quint32 queryExpressionResult(int objectDebugId, - const QString &expr, - bool *success); - quint32 queryExpressionResultBC(int objectDebugId, - const QString &expr, - bool *success); - quint32 setBindingForObject(int objectDebugId, const QString &propertyName, - const QVariant &bindingExpression, - bool isLiteralValue, - QString source, int line, bool *success); - quint32 resetBindingForObject(int objectDebugId, - const QString &propertyName, bool *success); - quint32 setMethodBody(int objectDebugId, const QString &methodName, - const QString &methodBody, bool *success); - - quint32 getId() { return m_nextId++; } - - void decode(QPacket &ds, QmlDebugContextReference &); - void decode(QPacket &ds, QmlDebugObjectReference &, bool simple); - void decode(QPacket &ds, QList<QmlDebugObjectReference> &o, bool simple); - - QList<QmlDebugEngineReference> engines() { return m_engines; } - QmlDebugContextReference rootContext() { return m_rootContext; } - QmlDebugObjectReference object() { return m_object; } - QList<QmlDebugObjectReference> objects() { return m_objects; } - QVariant resultExpr() { return m_exprResult; } - bool valid() { return m_valid; } - -signals: - void newObject(int objectId); - void valueChanged(QByteArray,QVariant); - void result(); - -protected: - void messageReceived(const QByteArray &); - -private: - quint32 m_nextId; - bool m_valid; - QList<QmlDebugEngineReference> m_engines; - QmlDebugContextReference m_rootContext; - QmlDebugObjectReference m_object; - QList<QmlDebugObjectReference> m_objects; - QVariant m_exprResult; -}; - -#endif // QQMLENGINEDEBUGCLIENT_H diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri deleted file mode 100644 index a969b4f153..0000000000 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri +++ /dev/null @@ -1,3 +0,0 @@ -HEADERS += $$PWD/qqmlenginedebugclient.h - -SOURCES += $$PWD/qqmlenginedebugclient.cpp diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri b/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri deleted file mode 100644 index c136e1313a..0000000000 --- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri +++ /dev/null @@ -1,3 +0,0 @@ -HEADERS += $$PWD/qqmlinspectorclient.h - -SOURCES += $$PWD/qqmlinspectorclient.cpp diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 00c631141b..b75f069fab 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -500,7 +500,7 @@ void tst_QJSEngine::newVariant_valueOfToString() QJSValue value = object.property("valueOf").callWithInstance(object); QVERIFY(value.isObject()); QVERIFY(value.strictlyEquals(object)); - QCOMPARE(object.toString(), QString::fromLatin1("QVariant(QPoint)")); + QCOMPARE(object.toString(), QString::fromLatin1("QVariant(QPoint, QPoint(10,20))")); } } diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index f9718e3699..b58cd98d1e 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -405,7 +405,7 @@ void tst_QJSValue::toString() // then fall back to "QVariant(typename)" QJSValue variant = eng.toScriptValue(QPoint(10, 20)); QVERIFY(variant.isVariant()); - QCOMPARE(variant.toString(), QString::fromLatin1("QVariant(QPoint)")); + QCOMPARE(variant.toString(), QString::fromLatin1("QVariant(QPoint, QPoint(10,20))")); variant = eng.toScriptValue(QUrl()); QVERIFY(variant.isVariant()); QVERIFY(variant.toString().isEmpty()); diff --git a/tests/auto/qml/qqmlconsole/data/logging.qml b/tests/auto/qml/qqmlconsole/data/logging.qml index 0764ad7545..8ed2dd73a1 100644 --- a/tests/auto/qml/qqmlconsole/data/logging.qml +++ b/tests/auto/qml/qqmlconsole/data/logging.qml @@ -68,6 +68,7 @@ QtObject { console.log(1, ["ping","pong"], new Object, 2); console.log(contextStringListProperty); + console.log(customObject); try { console.log(exception); diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp index 817ca0a257..f26eaa0817 100644 --- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp +++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp @@ -51,6 +51,15 @@ private: QQmlEngine engine; }; +struct CustomObject {}; + +QDebug operator<<(QDebug dbg, const CustomObject &) +{ + return dbg << "MY OBJECT"; +} + +Q_DECLARE_METATYPE(CustomObject) + void tst_qqmlconsole::logging() { QUrl testUrl = testFileUrl("logging.qml"); @@ -83,11 +92,16 @@ void tst_qqmlconsole::logging() QTest::ignoreMessage(QtDebugMsg, "1 pong! [object Object]"); QTest::ignoreMessage(QtDebugMsg, "1 [ping,pong] [object Object] 2"); QTest::ignoreMessage(QtDebugMsg, "[Hello,World]"); + QTest::ignoreMessage(QtDebugMsg, "QVariant(CustomObject, MY OBJECT)"); QScopedPointer<QQmlContext> loggingContext(new QQmlContext(engine.rootContext())); QStringList stringList; stringList << QStringLiteral("Hello") << QStringLiteral("World"); loggingContext->setContextProperty("contextStringListProperty", stringList); + CustomObject customObject; + QVERIFY(QMetaType::registerDebugStreamOperator<CustomObject>()); + loggingContext->setContextProperty("customObject", QVariant::fromValue(customObject)); + QQmlComponent component(&engine, testUrl); QScopedPointer<QObject> object(component.create(loggingContext.data())); QVERIFY(object != nullptr); diff --git a/tests/auto/qml/qqmlsqldatabase/data/changeVersion.qml b/tests/auto/qml/qqmlsqldatabase/data/changeVersion.qml new file mode 100644 index 0000000000..7d2683d869 --- /dev/null +++ b/tests/auto/qml/qqmlsqldatabase/data/changeVersion.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.2 +import QtQuick.LocalStorage 2.0 + +QtObject { + property var db; + property string version; + + function create() { + db = LocalStorage.openDatabaseSync("testdb", "2", "stuff for testing", 100000); + version = db.version; + } + + function upgrade() { + db = db.changeVersion(db.version, "22", function(y) {}); + version = db.version; + } +} diff --git a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp index f1dcefdab6..28f9c9a0c2 100644 --- a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp +++ b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp @@ -63,6 +63,7 @@ private slots: void testQml_cleanopen_data(); void testQml_cleanopen(); void totalDatabases(); + void upgradeDatabase(); void cleanupTestCase(); @@ -200,6 +201,22 @@ void tst_qqmlsqldatabase::totalDatabases() QCOMPARE(QDir(dbDir()+"/Databases").entryInfoList(QDir::Files|QDir::NoDotAndDotDot).count(), total_databases_created_by_tests*2); } +void tst_qqmlsqldatabase::upgradeDatabase() +{ + QQmlComponent component(engine, testFile("changeVersion.qml")); + QVERIFY(component.isReady()); + + QObject *object = component.create(); + QVERIFY(object); + QVERIFY(object->property("version").toString().isEmpty()); + + QVERIFY(QMetaObject::invokeMethod(object, "create")); + QCOMPARE(object->property("version").toString(), QLatin1String("2")); + + QVERIFY(QMetaObject::invokeMethod(object, "upgrade")); + QCOMPARE(object->property("version").toString(), QLatin1String("22")); +} + QTEST_MAIN(tst_qqmlsqldatabase) #include "tst_qqmlsqldatabase.moc" diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index 1ee4510e30..6ccfc77c25 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -90,6 +90,7 @@ private slots: void customValueTypeInQml(); void gadgetInheritance(); void gadgetTemplateInheritance(); + void sequences(); void toStringConversion(); void enumerableProperties(); void enumProperties(); @@ -1590,6 +1591,7 @@ struct BaseGadget Q_PROPERTY(int baseProperty READ baseProperty WRITE setBaseProperty) public: BaseGadget() : m_baseProperty(0) {} + BaseGadget(int initValue) : m_baseProperty(initValue) {} int baseProperty() const { return m_baseProperty; } void setBaseProperty(int value) { m_baseProperty = value; } @@ -1686,6 +1688,47 @@ void tst_qqmlvaluetypes::gadgetTemplateInheritance() QCOMPARE(value.property("baseProperty").toInt(), 42); } +void tst_qqmlvaluetypes::sequences() +{ + QJSEngine engine; + { + QList<BaseGadget> gadgetList{1, 4, 7, 8, 15}; + QJSValue value = engine.toScriptValue(gadgetList); + QCOMPARE(value.property("length").toInt(), gadgetList.length()); + for (int i = 0; i < gadgetList.length(); ++i) + QCOMPARE(value.property(i).property("baseProperty").toInt(), gadgetList.at(i).baseProperty()); + } + { + std::vector<BaseGadget> container{1, 4, 7, 8, 15}; + QJSValue value = engine.toScriptValue(container); + QCOMPARE(value.property("length").toInt(), int(container.size())); + for (size_t i = 0; i < container.size(); ++i) + QCOMPARE(value.property(i).property("baseProperty").toInt(), container.at(i).baseProperty()); + } + { + QVector<QChar> qcharVector{1, 4, 42, 8, 15}; + QJSValue value = engine.toScriptValue(qcharVector); + QCOMPARE(value.property("length").toInt(), qcharVector.length()); + for (int i = 0; i < qcharVector.length(); ++i) + QCOMPARE(value.property(i).toInt(), qcharVector.at(i)); + } + { + MyTypeObject a, b, c; + QSet<QObject*> objSet{&a, &b, &c}; + QJSValue value = engine.toScriptValue(objSet); + QCOMPARE(value.property("length").toInt(), objSet.size()); + for (int i = 0; i < objSet.size(); ++i) + QCOMPARE(value.property(i).property("point").property("x").toInt(), a.point().x()); + } + { + MyTypeObject a, b, c; + QSet<MyTypeObject*> container{&a, &b, &c}; + QJSValue value = engine.toScriptValue(container); + QCOMPARE(value.property("length").toInt(), container.size()); + for (int i = 0; i < container.size(); ++i) + QCOMPARE(value.property(i).property("point").property("x").toInt(), a.point().x()); + } +} struct StringLessGadget { Q_GADGET }; diff --git a/tests/auto/qml/qv4assembler/data/crash.qml b/tests/auto/qml/qv4assembler/data/crash.qml new file mode 100644 index 0000000000..dfdb9ceba5 --- /dev/null +++ b/tests/auto/qml/qv4assembler/data/crash.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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.2 +import Crash 1.0 + +QtObject { + property Crash crash: Crash { + id: crash + } + + // Recursion makes the crash more reliable + // With a single frame the unwinder might guess + // the next frame by chance. + function recurse(x) { + if (x > 32) + crash.crash(); + else + recurse(x + 1); + } + + property Timer timer: Timer { + interval: 10 + running: true + onTriggered: recurse(0) + } +} + diff --git a/tests/auto/qml/qv4assembler/qv4assembler.pro b/tests/auto/qml/qv4assembler/qv4assembler.pro index afd7586ac7..895e241cc9 100644 --- a/tests/auto/qml/qv4assembler/qv4assembler.pro +++ b/tests/auto/qml/qv4assembler/qv4assembler.pro @@ -1,7 +1,12 @@ CONFIG += testcase TARGET = tst_qv4assembler + +include (../../shared/util.pri) + macos:CONFIG -= app_bundle +TESTDATA = data/* + SOURCES += tst_qv4assembler.cpp QT += qml-private testlib diff --git a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp index 9bd1afa256..a04024f2e3 100644 --- a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp +++ b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp @@ -26,18 +26,34 @@ ** ****************************************************************************/ +#include <util.h> + #include <QtTest/QtTest> #include <QtCore/qprocess.h> #include <QtCore/qtemporaryfile.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlapplicationengine.h> + +#ifdef Q_OS_WIN +#include <Windows.h> +#endif -class tst_QV4Assembler : public QObject +class tst_QV4Assembler : public QQmlDataTest { Q_OBJECT private slots: + void initTestCase() override; void perfMapFile(); + void functionTable(); }; +void tst_QV4Assembler::initTestCase() +{ + qputenv("QV4_JIT_CALL_THRESHOLD", "0"); + QQmlDataTest::initTestCase(); +} + void tst_QV4Assembler::perfMapFile() { #if !defined(Q_OS_LINUX) @@ -85,6 +101,42 @@ void tst_QV4Assembler::perfMapFile() #endif } +#ifdef Q_OS_WIN +class Crash : public QObject +{ + Q_OBJECT +public: + explicit Crash(QObject *parent = nullptr) : QObject(parent) { } + Q_INVOKABLE static void crash(); +}; + +static bool crashHandlerHit = false; + +static LONG WINAPI crashHandler(EXCEPTION_POINTERS*) +{ + crashHandlerHit = true; + return EXCEPTION_CONTINUE_EXECUTION; +} + +void Crash::crash() +{ + SetUnhandledExceptionFilter(crashHandler); + RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nullptr); +} +#endif + +void tst_QV4Assembler::functionTable() +{ +#ifndef Q_OS_WIN + QSKIP("Function tables only exist on windows."); +#else + QQmlApplicationEngine engine; + qmlRegisterType<Crash>("Crash", 1, 0, "Crash"); + engine.load(testFileUrl("crash.qml")); + QTRY_VERIFY(crashHandlerHit); +#endif +} + QTEST_MAIN(tst_QV4Assembler) #include "tst_qv4assembler.moc" diff --git a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro index 85f71bb605..a337473d99 100644 --- a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro +++ b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro @@ -8,7 +8,7 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -QT += core-private gui-private qml-private quick-private network testlib +QT += core-private gui-private qml-private quick-private network testlib qmltest OTHER_FILES += \ $$files(data/*.qml) diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp index 4ca31fd957..d2bbf9e6b1 100644 --- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -28,6 +28,7 @@ #include <QtTest/QtTest> #include "../../shared/util.h" #include <QtQuick/qquickview.h> +#include <QtQuickTest/QtQuickTest> #include <private/qabstractanimation_p.h> #include <private/qquickanimatedsprite_p.h> #include <private/qquickitem_p.h> @@ -290,8 +291,8 @@ void tst_qquickanimatedsprite::test_reparenting() sprite->setParentItem(window.rootObject()); // don't crash (QTBUG-51162) sprite->polish(); - QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, true); - QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, false); + QVERIFY(QQuickTest::qIsPolishScheduled(sprite)); + QVERIFY(QQuickTest::qWaitForItemPolished(sprite)); } class KillerThread : public QThread diff --git a/tests/auto/quick/qquickgridview/qquickgridview.pro b/tests/auto/quick/qquickgridview/qquickgridview.pro index 3c33cc78fb..5051f8bc62 100644 --- a/tests/auto/quick/qquickgridview/qquickgridview.pro +++ b/tests/auto/quick/qquickgridview/qquickgridview.pro @@ -10,5 +10,5 @@ include (../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private qml-private quick-private testlib +QT += core-private gui-private qml-private quick-private testlib qmltest diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 301ec43cb5..3b704d7fa4 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -29,6 +29,7 @@ #include <QtTest/QtTest> #include <QtCore/qstringlistmodel.h> #include <QtQuick/qquickview.h> +#include <QtQuickTest/QtQuickTest> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlcontext.h> @@ -535,7 +536,7 @@ void tst_QQuickGridView::inserted_defaultLayout(QQuickGridView::Flow flow, insertCount = insertCount_ttb; } if (setContentPos(gridview, contentYRowOffset)) - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QList<QPair<QString, QString> > newData; for (int i=0; i<insertCount; i++) @@ -721,13 +722,13 @@ void tst_QQuickGridView::insertBeforeVisible() QTRY_VERIFY(contentItem != nullptr); gridview->setCacheBuffer(cacheBuffer); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // trigger a refill (not just setting contentY) so that the visibleItems grid is updated int firstVisibleIndex = 12; // move to an index where the top item is not visible gridview->setContentY(firstVisibleIndex/3 * 60.0); gridview->setCurrentIndex(firstVisibleIndex); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QTRY_COMPARE(gridview->currentIndex(), firstVisibleIndex); QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", firstVisibleIndex); @@ -744,7 +745,7 @@ void tst_QQuickGridView::insertBeforeVisible() // now, moving to the top of the view should position the inserted items correctly int itemsOffsetAfterMove = (insertCount / 3) * -60.0; gridview->setCurrentIndex(0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QTRY_COMPARE(gridview->currentIndex(), 0); QTRY_COMPARE(gridview->contentY(), 0.0 + itemsOffsetAfterMove); @@ -803,7 +804,7 @@ void tst_QQuickGridView::removed_basic() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.removeItem(1); QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); @@ -890,7 +891,7 @@ void tst_QQuickGridView::removed_basic() QTRY_VERIFY(gridview->currentItem() != oldCurrent); gridview->setContentY(0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // Confirm items positioned correctly itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -966,7 +967,7 @@ void tst_QQuickGridView::removed_defaultLayout(QQuickGridView::Flow flow, firstVisible = firstVisible_ttb; } if (setContentPos(gridview, contentYRowOffset)) - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.removeItems(removeIndex, removeCount); gridview->forceLayout(); @@ -1182,7 +1183,7 @@ void tst_QQuickGridView::addOrRemoveBeforeVisible() gridview->setCurrentIndex(0); qApp->processEvents(); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // scroll down until item 0 is no longer drawn // (bug not triggered if we just move using content y, since that doesn't @@ -1193,7 +1194,7 @@ void tst_QQuickGridView::addOrRemoveBeforeVisible() QTRY_COMPARE(gridview->currentIndex(), 24); QTRY_COMPARE(gridview->contentY(), 220.0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 0)); // 0 shouldn't be visible if (doAdd) { @@ -1254,7 +1255,7 @@ void tst_QQuickGridView::clear() QVERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.clear(); gridview->forceLayout(); @@ -1307,7 +1308,7 @@ void tst_QQuickGridView::moved_defaultLayout(QQuickGridView::Flow flow, QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *currentItem = gridview->currentItem(); QTRY_VERIFY(currentItem != nullptr); @@ -1318,10 +1319,10 @@ void tst_QQuickGridView::moved_defaultLayout(QQuickGridView::Flow flow, count = count_ttb; } if (setContentPos(gridview, contentYRowOffset)) - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.moveItems(from, to, count); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // Confirm items positioned correctly and indexes correct QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); @@ -1560,7 +1561,7 @@ void tst_QQuickGridView::multipleChanges(bool condensed) QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "grid"); QTRY_VERIFY(gridview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); for (int i=0; i<changes.count(); i++) { switch (changes[i].type) { @@ -1588,10 +1589,10 @@ void tst_QQuickGridView::multipleChanges(bool condensed) break; } if (condensed) { - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); } } - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(gridview->count(), newCount); QCOMPARE(gridview->count(), model.count()); @@ -1834,7 +1835,7 @@ void tst_QQuickGridView::currentIndex() QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "grid"); QVERIFY(gridview != nullptr); - QTRY_VERIFY(!QQuickItemPrivate::get(gridview)->polishScheduled); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); @@ -1936,7 +1937,7 @@ void tst_QQuickGridView::noCurrentIndex() QVERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // current index should be -1 QCOMPARE(gridview->currentIndex(), -1); @@ -1981,7 +1982,7 @@ void tst_QQuickGridView::keyNavigation() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); @@ -2491,7 +2492,7 @@ void tst_QQuickGridView::positionViewAtBeginningEnd() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // positionViewAtBeginning gridview->setContentY(150); @@ -2578,10 +2579,10 @@ void tst_QQuickGridView::positionViewAtIndex() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); window->rootObject()->setProperty("enforceRange", enforceRange); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); if (topToBottom) gridview->setContentX(initContentPos); @@ -2791,7 +2792,7 @@ void tst_QQuickGridView::resetModel() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QTRY_COMPARE(gridview->count(), model.rowCount()); @@ -2840,7 +2841,7 @@ void tst_QQuickGridView::enforceRange() QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0); QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0); QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3023,7 +3024,7 @@ void tst_QQuickGridView::footer() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3272,7 +3273,7 @@ void tst_QQuickGridView::header() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3296,7 +3297,7 @@ void tst_QQuickGridView::header() QCOMPARE(item->position(), firstDelegatePos); model.clear(); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(header->position(), initialHeaderPos); // header should stay where it is if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentHeight(), header->height()); @@ -3349,7 +3350,7 @@ void tst_QQuickGridView::header() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); gridview->setWidth(240); gridview->setHeight(320); @@ -3494,7 +3495,7 @@ void tst_QQuickGridView::extents() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3655,7 +3656,7 @@ void tst_QQuickGridView::resizeViewAndRepaint() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // item at index 10 should not be currently visible QVERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10)); @@ -3736,7 +3737,7 @@ void tst_QQuickGridView::resizeGrid() // items are aligned correctly in right-to-left window->rootObject()->setWidth(260); window->rootObject()->setHeight(320); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(gridview->contentX(), initialContentPos.x()); QCOMPARE(gridview->contentY(), initialContentPos.y()); @@ -3760,7 +3761,7 @@ void tst_QQuickGridView::resizeGrid() // change from 3x5 grid to 4x7 window->rootObject()->setWidth(window->rootObject()->width() + 80); window->rootObject()->setHeight(window->rootObject()->height() + 60*2); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // other than in LeftToRight+RightToLeft layout, the first item should not move // if view is resized @@ -3865,7 +3866,7 @@ void tst_QQuickGridView::changeColumnCount() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); // a single column of 6 items are visible int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -3879,7 +3880,7 @@ void tst_QQuickGridView::changeColumnCount() // now 6x3 grid is visible, plus 1 extra below for refill gridview->setWidth(240); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); QCOMPARE(itemCount, 6*3 + 1); for (int i = 0; i < model.count() && i < itemCount; ++i) { @@ -3891,7 +3892,7 @@ void tst_QQuickGridView::changeColumnCount() // back to single column gridview->setWidth(100); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); QCOMPARE(itemCount, 6); for (int i = 0; i < model.count() && i < itemCount; ++i) { @@ -4139,7 +4140,7 @@ void tst_QQuickGridView::margins() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(gridview->contentX(), -30.); QCOMPARE(gridview->originX(), 0.); @@ -4217,7 +4218,7 @@ void tst_QQuickGridView::margins() // remove item before visible and check that left margin is maintained // and originX is updated gridview->setContentX(-400); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.removeItems(0, 4); gridview->forceLayout(); QTRY_COMPARE(model.count(), gridview->count()); @@ -4259,7 +4260,7 @@ void tst_QQuickGridView::margins() QVERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(contentItem->x(), 200); QCOMPARE(contentItem->y(), 20); @@ -4341,7 +4342,7 @@ void tst_QQuickGridView::snapToRow() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -4461,7 +4462,7 @@ void tst_QQuickGridView::snapOneRow() gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); gridview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -4623,7 +4624,7 @@ void tst_QQuickGridView::populateTransitions() QTRY_COMPARE(gridview->property("countPopulateTransitions").toInt(), 0); QTRY_COMPARE(gridview->property("countAddTransitions").toInt(), 18); } else { - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QCOMPARE(gridview->property("countPopulateTransitions").toInt(), 0); QCOMPARE(gridview->property("countAddTransitions").toInt(), 0); } @@ -4659,7 +4660,7 @@ void tst_QQuickGridView::populateTransitions() for (int i = 0; i < 30; i++) model.addItem("item" + QString::number(i), ""); window->rootContext()->setContextProperty("testModel", &model); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QTRY_COMPARE(gridview->property("countPopulateTransitions").toInt(), usePopulateTransition ? 18 : 0); QTRY_COMPARE(gridview->property("countAddTransitions").toInt(), 0); @@ -4747,11 +4748,11 @@ void tst_QQuickGridView::addTransitions() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); if (contentYRowOffset != 0) { gridview->setContentY(contentYRowOffset * 60.0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -4956,7 +4957,7 @@ void tst_QQuickGridView::moveTransitions() if (contentYRowOffset != 0) { gridview->setContentY(contentYRowOffset * 60.0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -5197,11 +5198,11 @@ void tst_QQuickGridView::removeTransitions() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); if (contentYRowOffset != 0) { gridview->setContentY(contentYRowOffset * 60.0); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -5415,7 +5416,7 @@ void tst_QQuickGridView::displacedTransitions() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); gridview->setProperty("displaceTransitionsDone", false); @@ -5436,7 +5437,7 @@ void tst_QQuickGridView::displacedTransitions() break; case ListChange::Moved: model.moveItems(change.index, change.to, change.count); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); break; case ListChange::SetCurrent: case ListChange::SetContentY: @@ -5634,11 +5635,11 @@ void tst_QQuickGridView::multipleTransitions() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); if (contentY != 0) { gridview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); } int timeBetweenActions = window->rootObject()->property("timeBetweenActions").toInt(); @@ -5675,7 +5676,7 @@ void tst_QQuickGridView::multipleTransitions() case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); gridview->forceLayout(); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); if (i == changes.count() - 1) { QTRY_VERIFY(!gridview->property("runningMoveTargets").toBool()); QTRY_VERIFY(!gridview->property("runningMoveDisplaced").toBool()); @@ -5685,12 +5686,12 @@ void tst_QQuickGridView::multipleTransitions() break; case ListChange::SetCurrent: gridview->setCurrentIndex(changes[i].index); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); gridview->forceLayout(); break; case ListChange::SetContentY: gridview->setContentY(changes[i].pos); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); gridview->forceLayout(); break; case ListChange::Polish: @@ -5804,7 +5805,7 @@ void tst_QQuickGridView::multipleDisplaced() QTRY_VERIFY(gridview != nullptr); QQuickItem *contentItem = gridview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.moveItems(12, 8, 1); QTest::qWait(window->rootObject()->property("duration").toInt() / 2); @@ -5854,7 +5855,7 @@ void tst_QQuickGridView::regression_QTBUG_57225() QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "grid"); QVERIFY(gridview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); model.removeItems(removeIndex, removeCount); QTRY_VERIFY(gridview->property("animationDone").toBool()); @@ -6127,7 +6128,7 @@ void tst_QQuickGridView::unrequestedVisibility() // move a non-visible item into view model.moveItems(10, 9, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QTRY_VERIFY(item = findItem<QQuickItem>(leftContent, "wrapper", 1)); QCOMPARE(delegateVisible(item), false); @@ -6150,7 +6151,7 @@ void tst_QQuickGridView::unrequestedVisibility() // move a visible item out of view model.moveItems(5, 3, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QVERIFY(item = findItem<QQuickItem>(leftContent, "wrapper", 3)); QCOMPARE(delegateVisible(item), false); @@ -6163,7 +6164,7 @@ void tst_QQuickGridView::unrequestedVisibility() // move a non-visible item into view model.moveItems(3, 5, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QVERIFY(item = findItem<QQuickItem>(leftContent, "wrapper", 3)); QCOMPARE(delegateVisible(item), false); @@ -6176,7 +6177,7 @@ void tst_QQuickGridView::unrequestedVisibility() // move a visible item out of view model.moveItems(9, 10, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QVERIFY(item = findItem<QQuickItem>(leftContent, "wrapper", 3)); QCOMPARE(delegateVisible(item), false); @@ -6189,7 +6190,7 @@ void tst_QQuickGridView::unrequestedVisibility() // move a non-visible item into view model.moveItems(10, 9, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QVERIFY(item = findItem<QQuickItem>(leftContent, "wrapper", 3)); QCOMPARE(delegateVisible(item), false); diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro index a95b6fdf33..b1031e3bb7 100644 --- a/tests/auto/quick/qquicklistview/qquicklistview.pro +++ b/tests/auto/quick/qquicklistview/qquicklistview.pro @@ -17,5 +17,5 @@ include (../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private qml-private quick-private testlib +QT += core-private gui-private qml-private quick-private testlib qmltest diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index ff796a5bd8..03422c5b14 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -31,6 +31,7 @@ #include <QtCore/QSortFilterProxyModel> #include <QtGui/QStandardItemModel> #include <QtQuick/qquickview.h> +#include <QtQuickTest/QtQuickTest> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlexpression.h> @@ -470,8 +471,7 @@ void tst_QQuickListView::items(const QUrl &source) // Force a layout, necessary if ListView is completed before DelegateModel. listview->forceLayout(); - int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - QTRY_COMPARE(itemCount, 0); + QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").isEmpty()); QTRY_COMPARE(listview->highlightResizeVelocity(), 1000.0); QTRY_COMPARE(listview->highlightMoveVelocity(), 100000.0); @@ -647,7 +647,7 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); contentY = -listview->height() - contentY; } listview->setContentY(contentY); @@ -660,7 +660,7 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v model.insertItems(insertIndex, newData); //Wait for polish (updates list to the model changes) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->property("count").toInt(), model.count()); @@ -841,7 +841,7 @@ void tst_QQuickListView::insertBeforeVisible() QTRY_VERIFY(contentItem != nullptr); listview->setCacheBuffer(cacheBuffer); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // trigger a refill (not just setting contentY) so that the visibleItems grid is updated int firstVisibleIndex = 20; // move to an index where the top item is not visible @@ -849,7 +849,7 @@ void tst_QQuickListView::insertBeforeVisible() listview->setCurrentIndex(firstVisibleIndex); qApp->processEvents(); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), firstVisibleIndex); QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", firstVisibleIndex); QVERIFY(item); @@ -869,7 +869,7 @@ void tst_QQuickListView::insertBeforeVisible() // now, moving to the top of the view should position the inserted items correctly int itemsOffsetAfterMove = (removeCount - insertCount) * 20; listview->setCurrentIndex(0); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), 0); QTRY_COMPARE(listview->contentY(), 0.0 + itemsOffsetAfterMove); @@ -952,7 +952,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.removeItem(1); QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count()); @@ -1031,7 +1031,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) listview->setContentY(20); // That's the top now // let transitions settle. - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -1045,7 +1045,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) // remove current item beyond visible items. listview->setCurrentIndex(20); listview->setContentY(40); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.removeItem(20); QTRY_COMPARE(listview->currentIndex(), 20); @@ -1053,7 +1053,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) // remove item before current, but visible listview->setCurrentIndex(8); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); oldCurrent = listview->currentItem(); model.removeItem(6); @@ -1061,7 +1061,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) QTRY_COMPARE(listview->currentItem(), oldCurrent); listview->setContentY(80); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // remove all visible items model.removeItems(1, 18); @@ -1139,14 +1139,14 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); contentY = -listview->height() - contentY; } listview->setContentY(contentY); model.removeItems(removeIndex, removeCount); //Wait for polish (updates list to the model changes) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->property("count").toInt(), model.count()); @@ -1320,7 +1320,7 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou QTRY_VERIFY(contentItem != nullptr); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.clear(); @@ -1378,20 +1378,20 @@ void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayou QTRY_VERIFY(contentItem != nullptr); // always need to wait for view to be painted before the first move() - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); bool waitForPolish = (contentY != 0); if (verticalLayoutDirection == QQuickItemView::BottomToTop) { listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); contentY = -listview->height() - contentY; } listview->setContentY(contentY); if (waitForPolish) - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.moveItems(from, to, count); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -1604,7 +1604,7 @@ void tst_QQuickListView::multipleChanges(bool condensed) QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i=0; i<changes.count(); i++) { switch (changes[i].type) { @@ -1632,10 +1632,10 @@ void tst_QQuickListView::multipleChanges(bool condensed) continue; } if (!condensed) { - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); } } - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(listview->count(), newCount); QCOMPARE(listview->count(), model.count()); @@ -1852,7 +1852,7 @@ void tst_QQuickListView::swapWithFirstItem() QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // ensure content position is stable listview->setContentY(0); @@ -1915,7 +1915,7 @@ void tst_QQuickListView::enforceRange() QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0); QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0); QTRY_COMPARE(listview->highlightRangeMode(), QQuickListView::StrictlyEnforceRange); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -1970,7 +1970,7 @@ void tst_QQuickListView::enforceRange_withoutHighlight() QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); qreal expectedPos = -100.0; @@ -2014,7 +2014,7 @@ void tst_QQuickListView::spacing() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -2073,7 +2073,7 @@ void tst_QQuickListView::sections(const QUrl &source) QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -2143,9 +2143,9 @@ void tst_QQuickListView::sections(const QUrl &source) // check that headers change when item changes listview->setContentY(0); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.modifyItem(0, "changed", "2"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); item = findItem<QQuickItem>(contentItem, "wrapper", 1); QTRY_VERIFY(item); @@ -2173,7 +2173,7 @@ void tst_QQuickListView::sectionsDelegate() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -2197,7 +2197,7 @@ void tst_QQuickListView::sectionsDelegate() model.modifyItem(2, "Three", "aaa"); model.modifyItem(3, "Four", "aaa"); model.modifyItem(4, "Five", "aaa"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 0; i < 3; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, @@ -2233,7 +2233,7 @@ void tst_QQuickListView::sectionsDelegate() model.modifyItem(9, "Two", "aaa"); model.modifyItem(10, "Two", "aaa"); model.modifyItem(11, "Two", "aaa"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(findItems<QQuickItem>(contentItem, "sect_aaa").count(), 1); window->rootObject()->setProperty("sectionProperty", "name"); // ensure view has settled. @@ -2283,7 +2283,7 @@ void tst_QQuickListView::sectionsDragOutsideBounds() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // QTBUG-17769 // Drag view up beyond bounds @@ -2329,11 +2329,11 @@ void tst_QQuickListView::sectionsDelegate_headerVisibility() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // ensure section header is maintained in view listview->setCurrentIndex(20); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_VERIFY(qFuzzyCompare(listview->contentY(), 200.0)); QTRY_VERIFY(!listview->isMoving()); listview->setCurrentIndex(0); @@ -2360,7 +2360,7 @@ void tst_QQuickListView::sectionsPositioning() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 0; i < 3; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "sect_" + QString::number(i)); @@ -2378,12 +2378,12 @@ void tst_QQuickListView::sectionsPositioning() // move down a little and check that section header is at top listview->setContentY(10); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(topItem->y(), 0.); // push the top header up listview->setContentY(110); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); topItem = findVisibleChild(contentItem, "sect_0"); // section header QVERIFY(topItem); QCOMPARE(topItem->y(), 100.); @@ -2398,13 +2398,13 @@ void tst_QQuickListView::sectionsPositioning() // Move past section 0 listview->setContentY(120); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); topItem = findVisibleChild(contentItem, "sect_0"); // section header QVERIFY(!topItem); // Push section footer down listview->setContentY(70); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer QVERIFY(bottomItem); QCOMPARE(bottomItem->y(), 380.); @@ -2416,7 +2416,7 @@ void tst_QQuickListView::sectionsPositioning() model.modifyItem(2, "Three", "aAa"); model.modifyItem(3, "Four", "aaA"); model.modifyItem(4, "Five", "Aaa"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentSection(), QString("aaa")); @@ -2432,7 +2432,7 @@ void tst_QQuickListView::sectionsPositioning() // remove section boundary listview->setContentY(120); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.removeItem(5); listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); @@ -2449,27 +2449,27 @@ void tst_QQuickListView::sectionsPositioning() // Change the next section listview->setContentY(0); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer QVERIFY(bottomItem); QTRY_COMPARE(bottomItem->y(), 300.); model.modifyItem(14, "New", "new"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer QTRY_COMPARE(bottomItem->y(), 300.); // delegate size increase should push section footer down listview->setContentY(70); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_3")); // section footer QTRY_COMPARE(bottomItem->y(), 370.); QQuickItem *inlineSection = findVisibleChild(contentItem, "sect_new"); item = findItem<QQuickItem>(contentItem, "wrapper", 13); QVERIFY(item); item->setHeight(40.); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(bottomItem->y(), 380.); QCOMPARE(inlineSection->y(), 360.); item->setHeight(20.); @@ -2477,14 +2477,14 @@ void tst_QQuickListView::sectionsPositioning() // Turn sticky footer off listview->setContentY(20); window->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart))); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_VERIFY(item = findVisibleChild(contentItem, "sect_new")); // inline label restored QCOMPARE(item->y(), 340.); // Turn sticky header off listview->setContentY(30); window->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels))); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_VERIFY(item = findVisibleChild(contentItem, "sect_aaa")); // inline label restored QCOMPARE(item->y(), 0.); @@ -2520,7 +2520,7 @@ void tst_QQuickListView::sectionPropertyChange() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly for (int i = 0; i < 2; ++i) { @@ -2530,7 +2530,7 @@ void tst_QQuickListView::sectionPropertyChange() } QMetaObject::invokeMethod(window->rootObject(), "switchGroups"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly for (int i = 0; i < 2; ++i) { @@ -2540,7 +2540,7 @@ void tst_QQuickListView::sectionPropertyChange() } QMetaObject::invokeMethod(window->rootObject(), "switchGroups"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly for (int i = 0; i < 2; ++i) { @@ -2550,7 +2550,7 @@ void tst_QQuickListView::sectionPropertyChange() } QMetaObject::invokeMethod(window->rootObject(), "switchGrouped"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly for (int i = 0; i < 2; ++i) { @@ -2560,7 +2560,7 @@ void tst_QQuickListView::sectionPropertyChange() } QMetaObject::invokeMethod(window->rootObject(), "switchGrouped"); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly for (int i = 0; i < 2; ++i) { @@ -2584,7 +2584,7 @@ void tst_QQuickListView::sectionDelegateChange() QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QQUICK_VERIFY_POLISH(listview); + QQuickTest::qWaitForItemPolished(listview); QVERIFY(findItems<QQuickItem>(contentItem, "section1").count() > 0); QCOMPARE(findItems<QQuickItem>(contentItem, "section2").count(), 0); @@ -2596,7 +2596,7 @@ void tst_QQuickListView::sectionDelegateChange() } QMetaObject::invokeMethod(window->rootObject(), "switchDelegates"); - QQUICK_VERIFY_POLISH(listview); + QQuickTest::qWaitForItemPolished(listview); QCOMPARE(findItems<QQuickItem>(contentItem, "section1").count(), 0); QVERIFY(findItems<QQuickItem>(contentItem, "section2").count() > 0); @@ -2628,7 +2628,7 @@ void tst_QQuickListView::sectionsItemInsertion() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 0; i < 3; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "sect_" + QString::number(i)); @@ -2644,7 +2644,7 @@ void tst_QQuickListView::sectionsItemInsertion() for (int i = 0; i < 10; i++) model.insertItem(i, "Item" + QString::number(i), QLatin1String("A")); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); QVERIFY(itemCount > 10); @@ -2782,7 +2782,7 @@ void tst_QQuickListView::currentIndex() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // currentIndex is initialized to 20 // currentItem should be in view @@ -2885,7 +2885,7 @@ void tst_QQuickListView::noCurrentIndex() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // current index should be -1 at startup // and we should not have a currentItem or highlightItem @@ -2930,7 +2930,7 @@ void tst_QQuickListView::keyNavigation() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); @@ -3245,7 +3245,7 @@ void tst_QQuickListView::positionViewAtBeginningEnd() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); listview->setContentY(100); @@ -3305,10 +3305,10 @@ void tst_QQuickListView::positionViewAtIndex() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); window->rootObject()->setProperty("enforceRange", enforceRange); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); listview->setContentY(initContentY); @@ -3385,7 +3385,7 @@ void tst_QQuickListView::resetModel() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->count(), model.rowCount()); @@ -3656,7 +3656,7 @@ void tst_QQuickListView::QTBUG_11105() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -3748,7 +3748,7 @@ void tst_QQuickListView::header() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3827,7 +3827,7 @@ void tst_QQuickListView::header() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); listview->setWidth(240); listview->setHeight(320); @@ -3934,7 +3934,7 @@ void tst_QQuickListView::headerChangesViewport() QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -3984,7 +3984,7 @@ void tst_QQuickListView::footer() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -4173,7 +4173,7 @@ void tst_QQuickListView::extents() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -4313,7 +4313,7 @@ void tst_QQuickListView::resizeView() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -4329,7 +4329,7 @@ void tst_QQuickListView::resizeView() QCOMPARE(heightRatio.toReal(), 0.4); listview->setHeight(200); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QMetaObject::invokeMethod(window->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); QCOMPARE(heightRatio.toReal(), 0.25); @@ -4390,7 +4390,7 @@ void tst_QQuickListView::resizeViewAndRepaint() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // item at index 10 should not be currently visible QVERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10)); @@ -4425,7 +4425,7 @@ void tst_QQuickListView::sizeLessThan1() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Confirm items positioned correctly int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); @@ -4477,13 +4477,13 @@ void tst_QQuickListView::resizeDelegate() QVERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(listview->count(), model.rowCount()); listview->setCurrentIndex(25); listview->setContentY(0); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 0; i < 16; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); @@ -4495,7 +4495,7 @@ void tst_QQuickListView::resizeDelegate() QTRY_COMPARE(listview->highlightItem()->y(), 500.0); window->rootObject()->setProperty("delegateHeight", 30); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 0; i < 11; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); @@ -4509,7 +4509,7 @@ void tst_QQuickListView::resizeDelegate() listview->setCurrentIndex(1); listview->positionViewAtIndex(25, QQuickListView::Beginning); listview->positionViewAtIndex(5, QQuickListView::Beginning); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 5; i < 16; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); @@ -4521,7 +4521,7 @@ void tst_QQuickListView::resizeDelegate() QTRY_COMPARE(listview->highlightItem()->y(), 30.0); window->rootObject()->setProperty("delegateHeight", 20); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); for (int i = 5; i < 11; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); @@ -4558,7 +4558,7 @@ void tst_QQuickListView::resizeFirstDelegate() QVERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *item = nullptr; for (int i = 0; i < model.count(); ++i) { @@ -4597,7 +4597,7 @@ void tst_QQuickListView::resizeFirstDelegate() listview->setCurrentIndex(19); qApp->processEvents(); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // items 0-2 should have been deleted for (int i=0; i<3; i++) { @@ -4628,7 +4628,7 @@ void tst_QQuickListView::repositionResizedDelegate() QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *positioner = findItem<QQuickItem>(window->rootObject(), "positioner"); QVERIFY(positioner); @@ -4643,7 +4643,7 @@ void tst_QQuickListView::repositionResizedDelegate() listview->setContentX(contentPos_itemFirstHalfVisible.x()); listview->setContentY(contentPos_itemFirstHalfVisible.y()); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); prevSpyCount = spy.count(); QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "incrementRepeater")); QTRY_COMPARE(positioner->boundingRect().size(), resizedPositionerRect.size()); @@ -4660,7 +4660,7 @@ void tst_QQuickListView::repositionResizedDelegate() listview->setContentX(contentPos_itemSecondHalfVisible.x()); listview->setContentY(contentPos_itemSecondHalfVisible.y()); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); prevSpyCount = spy.count(); QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "incrementRepeater")); @@ -4768,7 +4768,7 @@ void tst_QQuickListView::indexAt_itemAt() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *item = nullptr; if (index >= 0) { @@ -4926,7 +4926,7 @@ void tst_QQuickListView::rightToLeft() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQmlObjectModel *model = window->rootObject()->findChild<QQmlObjectModel*>("itemModel"); QTRY_VERIFY(model != nullptr); @@ -5039,7 +5039,7 @@ void tst_QQuickListView::margins() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(listview->contentY(), -30.); QCOMPARE(listview->originY(), 0.); @@ -5048,7 +5048,7 @@ void tst_QQuickListView::margins() listview->positionViewAtEnd(); qreal pos = listview->contentY(); listview->setContentY(pos + 80); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); listview->returnToBounds(); QTRY_COMPARE(listview->contentY(), pos + 50); @@ -5059,7 +5059,7 @@ void tst_QQuickListView::margins() listview->forceLayout(); QTRY_COMPARE(listview->count(), model.count()); listview->setContentY(-50); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); listview->returnToBounds(); QCOMPARE(listview->originY(), 20.); QTRY_COMPARE(listview->contentY(), -10.); @@ -5112,7 +5112,7 @@ void tst_QQuickListView::marginsResize() listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // view is resized after componentCompleted - top margin should still be visible if (orientation == QQuickListView::Vertical) @@ -5252,7 +5252,7 @@ void tst_QQuickListView::snapToItem() listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -5304,7 +5304,7 @@ void tst_QQuickListView::snapToItemWithSpacing_QTBUG_59852() auto *listView = qobject_cast<QQuickListView*>(window->rootObject()); QVERIFY(listView); - QTRY_COMPARE(QQuickItemPrivate::get(listView)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listView)); // each item in the list is 100 pixels tall, and the spacing is 100 @@ -5335,14 +5335,14 @@ void tst_QQuickListView::snapOneItemResize_QTBUG_43555() QSignalSpy currentIndexSpy(listview, SIGNAL(currentIndexChanged())); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), 5); currentIndexSpy.clear(); window->resize(QSize(400, 320)); QTRY_COMPARE(int(listview->width()), 400); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), 5); QCOMPARE(currentIndexSpy.count(), 0); @@ -5652,7 +5652,7 @@ void tst_QQuickListView::snapOneItem() listview->setLayoutDirection(layoutDirection); listview->setVerticalLayoutDirection(verticalLayoutDirection); listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); @@ -5721,14 +5721,14 @@ void tst_QQuickListView::snapOneItemCurrentIndexRemoveAnimation() QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), 0); QSignalSpy currentIndexSpy(listview, SIGNAL(currentIndexChanged())); QMetaObject::invokeMethod(window->rootObject(), "removeItemZero"); QTRY_COMPARE(listview->property("transitionsRun").toInt(), 1); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(listview->currentIndex(), 0); QCOMPARE(currentIndexSpy.count(), 0); @@ -5744,7 +5744,7 @@ void tst_QQuickListView::snapOneItemWrongDirection() QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QTRY_COMPARE(listview->currentIndex(), 0); listview->flick(0,500); @@ -5894,7 +5894,7 @@ void tst_QQuickListView::unrequestedVisibility() QCOMPARE(delegateVisible(item), false); model.moveItems(19, 1, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); QTRY_VERIFY((item = findItem<QQuickItem>(leftContent, wrapperObjectName, 1))); QCOMPARE(delegateVisible(item), false); @@ -5923,7 +5923,7 @@ void tst_QQuickListView::unrequestedVisibility() QCOMPARE(delegateVisible(item), false); model.moveItems(3, 4, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); item = findItem<QQuickItem>(leftContent, wrapperObjectName, 4); QVERIFY(item); @@ -5939,7 +5939,7 @@ void tst_QQuickListView::unrequestedVisibility() QCOMPARE(delegateVisible(item), false); model.moveItems(4, 3, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); item = findItem<QQuickItem>(leftContent, wrapperObjectName, 4); QVERIFY(item); @@ -5955,7 +5955,7 @@ void tst_QQuickListView::unrequestedVisibility() QCOMPARE(delegateVisible(item), false); model.moveItems(16, 17, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); item = findItem<QQuickItem>(leftContent, wrapperObjectName, 4); QVERIFY(item); @@ -5971,7 +5971,7 @@ void tst_QQuickListView::unrequestedVisibility() QCOMPARE(delegateVisible(item), false); model.moveItems(17, 16, 1); - QTRY_COMPARE(QQuickItemPrivate::get(leftview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(leftview)); item = findItem<QQuickItem>(leftContent, wrapperObjectName, 4); QVERIFY(item); @@ -6031,7 +6031,7 @@ void tst_QQuickListView::populateTransitions() QTRY_COMPARE(listview->property("countPopulateTransitions").toInt(), 0); QTRY_COMPARE(listview->property("countAddTransitions").toInt(), 16); } else { - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(listview->property("countPopulateTransitions").toInt(), 0); QCOMPARE(listview->property("countAddTransitions").toInt(), 0); } @@ -6142,7 +6142,7 @@ void tst_QQuickListView::sizeTransitions() QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); QTRY_VERIFY(listview != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // the following will start the transition model.addItem(QLatin1String("Test"), ""); @@ -6207,11 +6207,11 @@ void tst_QQuickListView::addTransitions() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); if (contentY != 0) { listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -6407,7 +6407,7 @@ void tst_QQuickListView::moveTransitions() if (contentY != 0) { listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -6606,11 +6606,11 @@ void tst_QQuickListView::removeTransitions() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); if (contentY != 0) { listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); } QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); @@ -6818,7 +6818,7 @@ void tst_QQuickListView::displacedTransitions() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); listview->setProperty("displaceTransitionsDone", false); @@ -6839,7 +6839,7 @@ void tst_QQuickListView::displacedTransitions() break; case ListChange::Moved: model.moveItems(change.index, change.to, change.count); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); break; case ListChange::SetCurrent: case ListChange::SetContentY: @@ -7038,11 +7038,11 @@ void tst_QQuickListView::multipleTransitions() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); if (contentY != 0) { listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); } int timeBetweenActions = window->rootObject()->property("timeBetweenActions").toInt(); @@ -7076,7 +7076,7 @@ void tst_QQuickListView::multipleTransitions() break; case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); if (i == changes.count() - 1) { QTRY_VERIFY(!listview->property("runningMoveTargets").toBool()); QTRY_VERIFY(!listview->property("runningMoveDisplaced").toBool()); @@ -7089,7 +7089,7 @@ void tst_QQuickListView::multipleTransitions() break; case ListChange::SetContentY: listview->setContentY(changes[i].pos); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); break; case ListChange::Polish: break; @@ -7195,7 +7195,7 @@ void tst_QQuickListView::multipleDisplaced() QTRY_VERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); model.moveItems(12, 8, 1); QTest::qWait(window->rootObject()->property("duration").toInt() / 2); @@ -7289,7 +7289,7 @@ void tst_QQuickListView::flickBeyondBounds() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); // Flick view up beyond bounds flick(window.data(), QPoint(10, 10), QPoint(10, -2000), 180); @@ -7401,7 +7401,7 @@ void tst_QQuickListView::destroyItemOnCreation() QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QCOMPARE(window->rootObject()->property("createdIndex").toInt(), -1); model.addItem("new item", ""); @@ -7425,7 +7425,7 @@ void tst_QQuickListView::parentBinding() QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem != nullptr); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item); @@ -8829,7 +8829,7 @@ void tst_QQuickListView::QTBUG_34576_velocityZero() QVERIFY(listview); QQuickItem *contentItem = listview->contentItem(); QVERIFY(contentItem); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); QSignalSpy horizontalVelocitySpy(listview, SIGNAL(horizontalVelocityChanged())); diff --git a/tests/auto/quick/qquickpathview/qquickpathview.pro b/tests/auto/quick/qquickpathview/qquickpathview.pro index 90c1eb0c67..f21fb64fa4 100644 --- a/tests/auto/quick/qquickpathview/qquickpathview.pro +++ b/tests/auto/quick/qquickpathview/qquickpathview.pro @@ -9,5 +9,5 @@ include (../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private qml-private quick-private testlib +QT += core-private gui-private qml-private quick-private testlib qmltest qtHaveModule(widgets): QT += widgets diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index aceb61bde4..8d3abb7ce3 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -38,6 +38,7 @@ #include <QtQuick/private/qquickpath_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickrectangle_p.h> +#include <QtQuickTest/QtQuickTest> #include <QtQml/private/qqmllistmodel_p.h> #include <QtQml/private/qqmlvaluetype_p.h> #include <QtGui/qstandarditemmodel.h> @@ -714,13 +715,13 @@ void tst_QQuickPathView::consecutiveModelChanges() pathview->setCurrentIndex(changes[i].index); break; case ListChange::Polish: - QQUICK_VERIFY_POLISH(pathview); + QQuickTest::qWaitForItemPolished(pathview); break; default: continue; } } - QQUICK_VERIFY_POLISH(pathview); + QQuickTest::qWaitForItemPolished(pathview); QCOMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), count); QCOMPARE(pathview->count(), count); diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro index 6e85ba9db8..d1547df189 100644 --- a/tests/auto/quick/qquickpositioners/qquickpositioners.pro +++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro @@ -9,4 +9,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -QT += testlib +QT += testlib qmltest diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index 9881af690c..80be25d1b0 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -31,6 +31,7 @@ #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquickpositioners_p.h> #include <QtQuick/private/qquicktransition_p.h> +#include <QtQuickTest/QtQuickTest> #include <private/qquickitem_p.h> #include <qqmlexpression.h> #include "../shared/viewtestutil.h" @@ -1062,7 +1063,7 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN QTRY_COMPARE(window->rootObject()->property("populateTransitionsDone").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("addTransitionsDone").toInt(), model.count()); } else { - QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(positioner)); QTRY_COMPARE(window->rootObject()->property("populateTransitionsDone").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("addTransitionsDone").toInt(), 0); } @@ -1128,7 +1129,7 @@ void tst_qquickpositioners::addTransitions(const QString &positionerObjectName) QQuickItem *positioner = window->rootObject()->findChild<QQuickItem*>(positionerObjectName); QVERIFY(positioner); positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model)); - QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(positioner)); for (int i = 0; i < initialItemCount; i++) model.addItem("Original item" + QString::number(i), ""); @@ -1253,7 +1254,7 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) QQuickItem *positioner = window->rootObject()->findChild<QQuickItem*>(positionerObjectName); QVERIFY(positioner); positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model)); - QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(positioner)); switch (change.type) { case ListChange::Removed: @@ -1262,7 +1263,7 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) break; case ListChange::Moved: model.moveItems(change.index, change.to, change.count); - QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(positioner)); break; case ListChange::Inserted: case ListChange::SetCurrent: @@ -3815,7 +3816,7 @@ void tst_qquickpositioners::test_mirroring() QQuickItem *positionerB = itemB->parentItem(); positionerA->setWidth(positionerA->width() * 2); positionerB->setWidth(positionerB->width() * 2); - QTRY_VERIFY(!QQuickItemPrivate::get(positionerA)->polishScheduled && !QQuickItemPrivate::get(positionerB)->polishScheduled); + QVERIFY(QQuickTest::qWaitForItemPolished(positionerA) && QQuickTest::qWaitForItemPolished(positionerB)); QTRY_COMPARE(itemA->x(), itemB->x()); } diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp index f601f520bb..a57b7d4c1f 100644 --- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp +++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp @@ -46,6 +46,10 @@ class TestShaderEffect : public QQuickShaderEffect Q_PROPERTY(QMatrix4x4 mat4x4 READ mat4x4Read NOTIFY dummyChanged) public: + TestShaderEffect(QQuickItem* parent = nullptr) : QQuickShaderEffect(parent) + { + } + QMatrix4x4 mat4x4Read() const { return QMatrix4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1); } QVariant dummyRead() const { return QVariant(); } @@ -79,6 +83,8 @@ private slots: void deleteShaderEffectSource(); void twoImagesOneShaderEffect(); + void withoutQmlEngine(); + private: enum PresenceFlags { VertexPresent = 0x01, @@ -320,6 +326,16 @@ void tst_qquickshadereffect::twoImagesOneShaderEffect() delete view; } +void tst_qquickshadereffect::withoutQmlEngine() +{ + // using a shader without QML engine used to crash + auto window = new QQuickWindow; + auto shaderEffect = new TestShaderEffect(window->contentItem()); + shaderEffect->setVertexShader(""); + QVERIFY(shaderEffect->isComponentComplete()); + delete window; +} + QTEST_MAIN(tst_qquickshadereffect) #include "tst_qquickshadereffect.moc" diff --git a/tests/auto/quick/qquicktableview/qquicktableview.pro b/tests/auto/quick/qquicktableview/qquicktableview.pro index f4d0265dd3..cf831ed5b5 100644 --- a/tests/auto/quick/qquicktableview/qquicktableview.pro +++ b/tests/auto/quick/qquicktableview/qquicktableview.pro @@ -1,4 +1,5 @@ CONFIG += testcase +QT += qmltest TARGET = tst_qquicktableview macos:CONFIG -= app_bundle diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index d475ef9c4d..a3b9aa4c03 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include <QtQuickTest/quicktest.h> #include <QtQuick/qquickview.h> #include <QtQuick/private/qquicktableview_p.h> @@ -79,8 +80,8 @@ Q_DECLARE_METATYPE(QMarginsF); DECLARE_TABLEVIEW_VARIABLES #define WAIT_UNTIL_POLISHED \ - QVERIFY(tableViewPrivate->polishScheduled); \ - QTRY_VERIFY(!tableViewPrivate->polishScheduled) + QVERIFY(QQuickTest::qIsPolishScheduled(tableView)); \ + QVERIFY(QQuickTest::qWaitForItemPolished(tableView)) class tst_QQuickTableView : public QQmlDataTest { diff --git a/tests/auto/quick/qquicktext/qquicktext.pro b/tests/auto/quick/qquicktext/qquicktext.pro index f76e8c95b2..fdea9dcddd 100644 --- a/tests/auto/quick/qquicktext/qquicktext.pro +++ b/tests/auto/quick/qquicktext/qquicktext.pro @@ -11,4 +11,4 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private qml-private quick-private network testlib +QT += core-private gui-private qml-private quick-private network testlib qmltest diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index a9c35e0cc4..fd0ba0f49b 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -32,6 +32,7 @@ #include <QtQml/qqmlcomponent.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuickTest/QtQuickTest> #include <private/qquicktext_p_p.h> #include <private/qquicktextdocument_p.h> #include <private/qquickvaluetypes_p.h> @@ -3142,7 +3143,7 @@ void tst_qquicktext::fontSizeMode() QVERIFY(myText != nullptr); myText->setText(text); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); qreal originalWidth = myText->contentWidth(); qreal originalHeight = myText->contentHeight(); @@ -3156,7 +3157,7 @@ void tst_qquicktext::fontSizeMode() myText->setFont(font); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Font size reduced to fit within the width of the item. qreal horizontalFitWidth = myText->contentWidth(); qreal horizontalFitHeight = myText->contentHeight(); @@ -3165,28 +3166,28 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the size with HorizontalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Font size increased to fill the height of the item. qreal verticalFitHeight = myText->contentHeight(); QVERIFY(myText->contentWidth() > myText->width()); @@ -3195,57 +3196,57 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the height of a single line with VerticalFit but will crop the width. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as HorizontalFit with no wrapping. QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::FixedSize); myText->setWrapMode(QQuickText::Wrap); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); originalWidth = myText->contentWidth(); originalHeight = myText->contentHeight(); @@ -3255,7 +3256,7 @@ void tst_qquicktext::fontSizeMode() QVERIFY(originalHeight > myText->height()); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the // same size as without text wrapping. QCOMPARE(myText->contentWidth(), horizontalFitWidth); @@ -3263,16 +3264,16 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the size with HorizontalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // VerticalFit should reduce the size to the wrapped text within the vertical height. verticalFitHeight = myText->contentHeight(); qreal verticalFitWidth = myText->contentWidth(); @@ -3282,40 +3283,40 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the height or width of a wrapped text with VerticalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as VerticalFit with wrapping. QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::FixedSize); myText->setMaximumLineCount(2); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // The original text wrapped should exceed the height of the item. QVERIFY(originalWidth <= myText->width() + 2); QVERIFY(originalHeight > myText->height()); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the // same size as without text wrapping. QCOMPARE(myText->contentWidth(), horizontalFitWidth); @@ -3323,16 +3324,16 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the size with HorizontalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // VerticalFit should reduce the size to the wrapped text within the vertical height. verticalFitHeight = myText->contentHeight(); verticalFitWidth = myText->contentWidth(); @@ -3342,29 +3343,29 @@ void tst_qquicktext::fontSizeMode() // Elide won't affect the height or width of a wrapped text with VerticalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as VerticalFit with wrapping. QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); } void tst_qquicktext::fontSizeModeMultiline_data() @@ -3385,7 +3386,7 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(myText != nullptr); myText->setText(text); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); qreal originalWidth = myText->contentWidth(); qreal originalHeight = myText->contentHeight(); @@ -3400,7 +3401,7 @@ void tst_qquicktext::fontSizeModeMultiline() myText->setFont(font); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Font size reduced to fit within the width of the item. QCOMPARE(myText->lineCount(), 2); qreal horizontalFitWidth = myText->contentWidth(); @@ -3410,7 +3411,7 @@ void tst_qquicktext::fontSizeModeMultiline() // Right eliding will remove the last line myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QCOMPARE(myText->lineCount(), 1); QVERIFY(myText->contentWidth() <= myText->width() + 2); @@ -3418,22 +3419,22 @@ void tst_qquicktext::fontSizeModeMultiline() // Left or middle eliding wont have any effect. myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Font size reduced to fit within the height of the item. qreal verticalFitWidth = myText->contentWidth(); qreal verticalFitHeight = myText->contentHeight(); @@ -3442,58 +3443,58 @@ void tst_qquicktext::fontSizeModeMultiline() // Elide will have no effect. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as VerticalFit with no wrapping. QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::FixedSize); myText->setWrapMode(QQuickText::Wrap); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); originalWidth = myText->contentWidth(); originalHeight = myText->contentHeight(); @@ -3503,7 +3504,7 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(originalHeight > myText->height()); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the // same size as without text wrapping. QCOMPARE(myText->contentWidth(), horizontalFitWidth); @@ -3511,16 +3512,16 @@ void tst_qquicktext::fontSizeModeMultiline() // Text will be elided vertically with HorizontalFit myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QVERIFY(myText->contentHeight() <= myText->height() + 2); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // VerticalFit should reduce the size to the wrapped text within the vertical height. verticalFitHeight = myText->contentHeight(); verticalFitWidth = myText->contentWidth(); @@ -3530,40 +3531,40 @@ void tst_qquicktext::fontSizeModeMultiline() // Elide won't affect the height or width of a wrapped text with VerticalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as VerticalFit with wrapping. QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::FixedSize); myText->setMaximumLineCount(2); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // The original text wrapped should exceed the height of the item. QVERIFY(originalWidth <= myText->width() + 2); QVERIFY(originalHeight > myText->height()); myText->setFontSizeMode(QQuickText::HorizontalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the // same size as without text wrapping. QCOMPARE(myText->contentWidth(), horizontalFitWidth); @@ -3571,16 +3572,16 @@ void tst_qquicktext::fontSizeModeMultiline() // Elide won't affect the size with HorizontalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(myText->truncated()); QVERIFY(myText->contentWidth() <= myText->width() + 2); QVERIFY(myText->contentHeight() <= myText->height() + 2); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::VerticalFit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // VerticalFit should reduce the size to the wrapped text within the vertical height. verticalFitHeight = myText->contentHeight(); verticalFitWidth = myText->contentWidth(); @@ -3590,29 +3591,29 @@ void tst_qquicktext::fontSizeModeMultiline() // Elide won't affect the height or width of a wrapped text with VerticalFit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); myText->setFontSizeMode(QQuickText::Fit); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); // Should be the same as VerticalFit with wrapping. QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); // Elide won't affect the size with Fit. myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QVERIFY(!myText->truncated()); QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); } void tst_qquicktext::multilengthStrings_data() @@ -3637,17 +3638,17 @@ void tst_qquicktext::multilengthStrings() const QString shortText = "fox jumped dog"; myText->setText(longText); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); const qreal longWidth = myText->contentWidth(); const qreal longHeight = myText->contentHeight(); myText->setText(mediumText); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); const qreal mediumWidth = myText->contentWidth(); const qreal mediumHeight = myText->contentHeight(); myText->setText(shortText); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); const qreal shortWidth = myText->contentWidth(); const qreal shortHeight = myText->contentHeight(); @@ -3655,21 +3656,21 @@ void tst_qquicktext::multilengthStrings() myText->setText(longText + QLatin1Char('\x9c') + mediumText + QLatin1Char('\x9c') + shortText); myText->setSize(QSizeF(longWidth, longHeight)); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QCOMPARE(myText->contentWidth(), longWidth); QCOMPARE(myText->contentHeight(), longHeight); QCOMPARE(myText->truncated(), false); myText->setSize(QSizeF(mediumWidth, mediumHeight)); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QCOMPARE(myText->contentWidth(), mediumWidth); QCOMPARE(myText->contentHeight(), mediumHeight); QCOMPARE(myText->truncated(), true); myText->setSize(QSizeF(shortWidth, shortHeight)); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); QCOMPARE(myText->contentWidth(), shortWidth); QCOMPARE(myText->contentHeight(), shortHeight); diff --git a/tests/auto/quick/shared/visualtestutil.h b/tests/auto/quick/shared/visualtestutil.h index 2daf86cd83..74f9dc8cc1 100644 --- a/tests/auto/quick/shared/visualtestutil.h +++ b/tests/auto/quick/shared/visualtestutil.h @@ -100,7 +100,4 @@ namespace QQuickVisualTestUtil bool compareImages(const QImage &ia, const QImage &ib); } -#define QQUICK_VERIFY_POLISH(item) \ - QTRY_COMPARE(QQuickItemPrivate::get(item)->polishScheduled, false) - #endif // QQUICKVISUALTESTUTIL_H diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h b/tests/auto/quicktest/polish-qml/data/tst_polish.qml index bfb489c8f7..d2d5972d43 100644 --- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h +++ b/tests/auto/quicktest/polish-qml/data/tst_polish.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -25,35 +25,36 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QQMLINSPECTORCLIENT_H -#define QQMLINSPECTORCLIENT_H -#include <private/qqmldebugclient_p.h> +import QtQuick 2.13 +import QtTest 1.13 -class QQmlInspectorClient : public QQmlDebugClient -{ - Q_OBJECT +import Test 1.0 -public: - QQmlInspectorClient(QQmlDebugConnection *connection); +TestCase { + id: testCase + name: "polish-qml" + when: windowShown - int setInspectToolEnabled(bool enabled); - int setShowAppOnTop(bool showOnTop); - int setAnimationSpeed(qreal speed); - int select(const QList<int> &objectIds); - int createObject(const QString &qml, int parentId, const QStringList &imports, - const QString &filename); - int moveObject(int childId, int newParentId); - int destroyObject(int objectId); + Component { + id: customItemComponent + CustomItem {} + } -signals: - void responseReceived(int requestId, bool result); + function test_polish() + { + var item = createTemporaryObject(customItemComponent, testCase) + verify(item) -protected: - void messageReceived(const QByteArray &message); + item.polishMe() + verify(isPolishScheduled(item)) + verify(item.isPolishScheduled()) -private: - int m_lastRequestId; -}; + verify(waitForItemPolished(item)) + verify(item.wasUpdatePolishCalled()) -#endif // QQMLINSPECTORCLIENT_H + // TODO: test failure conditions when https://bugreports.qt.io/browse/QTBUG-72351 is fixed +// expectFail("", "Not a valid item") +// isPolishScheduled(null) + } +} diff --git a/tests/auto/quicktest/polish-qml/polish-qml.pro b/tests/auto/quicktest/polish-qml/polish-qml.pro new file mode 100644 index 0000000000..15b913ffe1 --- /dev/null +++ b/tests/auto/quicktest/polish-qml/polish-qml.pro @@ -0,0 +1,12 @@ +CONFIG += qmltestcase +macos:CONFIG -= app_bundle +TARGET = tst_polish-qml + +QT += testlib quick quick-private + +include (../../shared/util.pri) + +SOURCES += tst_polish-qml.cpp + +TESTDATA += \ + $$PWD/data/*.qml diff --git a/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp b/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp new file mode 100644 index 0000000000..e525a8a5af --- /dev/null +++ b/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/qquickview.h> +#include <QtQuickTest/quicktest.h> + +#include "../../shared/util.h" + +class CustomItem : public QQuickItem +{ + Q_OBJECT + +public: + CustomItem() {} + + Q_INVOKABLE void polishMe() { + polish(); + } + + Q_INVOKABLE bool isPolishScheduled() const + { + return QQuickItemPrivate::get(this)->polishScheduled; + } + + Q_INVOKABLE bool wasUpdatePolishCalled() const + { + return updatePolishCalled; + } + + void updatePolish() override + { + updatePolishCalled = true; + } + +private: + bool updatePolishCalled = false; +}; + +class TestSetup : public QObject +{ + Q_OBJECT + +public: + TestSetup() {} + +public slots: + void applicationAvailable() + { + qmlRegisterType<CustomItem>("Test", 1, 0, "CustomItem"); + } +}; + +QUICK_TEST_MAIN_WITH_SETUP(polish-qml, TestSetup) + +#include "tst_polish-qml.moc" diff --git a/tests/auto/quicktest/polish/data/polish.qml b/tests/auto/quicktest/polish/data/polish.qml new file mode 100644 index 0000000000..0ab3afda2e --- /dev/null +++ b/tests/auto/quicktest/polish/data/polish.qml @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QtQuick 2.0 +import Test 1.0 + +CustomItem {} diff --git a/tests/auto/quicktest/polish/polish.pro b/tests/auto/quicktest/polish/polish.pro new file mode 100644 index 0000000000..0dfb4bdf5e --- /dev/null +++ b/tests/auto/quicktest/polish/polish.pro @@ -0,0 +1,12 @@ +CONFIG += qmltestcase +macos:CONFIG -= app_bundle +TARGET = tst_polish + +QT += testlib quick quick-private + +include (../../shared/util.pri) + +SOURCES += tst_polish.cpp + +TESTDATA += \ + $$PWD/data/*.qml diff --git a/tests/auto/quicktest/polish/tst_polish.cpp b/tests/auto/quicktest/polish/tst_polish.cpp new file mode 100644 index 0000000000..3b96002cd2 --- /dev/null +++ b/tests/auto/quicktest/polish/tst_polish.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickitem.h> +#include <QQuickView> +#include <QtQuickTest/quicktest.h> + +#include "../../shared/util.h" + +class CustomItem : public QQuickItem +{ + Q_OBJECT + +public: + CustomItem() {} + + void updatePolish() override + { + updatePolishCalled = true; + } + + bool updatePolishCalled = false; +}; + +class tst_Polish : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_Polish(); + +private slots: + void testPolish(); +}; + +tst_Polish::tst_Polish() +{ + qmlRegisterType<CustomItem>("Test", 1, 0, "CustomItem"); +} + +void tst_Polish::testPolish() +{ + QQuickView view; + view.setSource(testFileUrl("polish.qml")); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + CustomItem *item = qobject_cast<CustomItem*>(view.rootObject()); + QVERIFY(item); + + item->polish(); + QVERIFY(QQuickTest::qIsPolishScheduled(item)); + QVERIFY(!item->updatePolishCalled); + QVERIFY(QQuickTest::qWaitForItemPolished(item)); + QVERIFY(item->updatePolishCalled); +} + +QTEST_MAIN(tst_Polish) + +#include "tst_polish.moc" diff --git a/tests/auto/quicktest/quicktest.pro b/tests/auto/quicktest/quicktest.pro index 0e3f257e33..6d09f76c1d 100644 --- a/tests/auto/quicktest/quicktest.pro +++ b/tests/auto/quicktest/quicktest.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS = \ + polish \ signalspy \ quicktestmainwithsetup \ testfiltering diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 68aacf78ce..de79576d67 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ #include <QByteArray> +#include <QRegExp> #include <QString> #include <QStringList> #include <QTextStream> @@ -344,7 +345,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN for (int i = 0; i < compiledFiles.count(); ++i) { const QString compiledFile = compiledFiles.at(i); const QString ns = symbolNamespaceForPath(compiledFile); - stream << "namespace " << symbolNamespaceForPath(compiledFile) << " { \n"; + stream << "namespace " << ns << " { \n"; stream << " extern const unsigned char qmlData[];\n"; stream << " const QQmlPrivate::CachedQmlUnit unit = {\n"; stream << " reinterpret_cast<const QV4::CompiledData::Unit*>(&qmlData), nullptr, nullptr\n"; diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index f5bd6d2291..565152d5d2 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -76,9 +76,9 @@ namespace { const uint qtQmlMajorVersion = 2; -const uint qtQmlMinorVersion = QT_VERSION_MINOR; +const uint qtQmlMinorVersion = 0; const uint qtQuickMajorVersion = 2; -const uint qtQuickMinorVersion = QT_VERSION_MINOR; +const uint qtQuickMinorVersion = 0; const QString qtQuickQualifiedName = QString::fromLatin1("QtQuick %1.%2") .arg(qtQuickMajorVersion) @@ -1138,8 +1138,7 @@ int main(int argc, char *argv[]) QRegularExpressionMatchIterator i = re.globalMatch(merge[1]); while (i.hasNext()) { QRegularExpressionMatch m = i.next(); - QString d = m.captured(1); - mergeDependencies << m.captured(1); + mergeDependencies << m.captured(1); } mergeComponents = merge [2]; } diff --git a/tools/qmlpreview/qmlpreviewapplication.cpp b/tools/qmlpreview/qmlpreviewapplication.cpp index 02f10831ec..57453e0cb9 100644 --- a/tools/qmlpreview/qmlpreviewapplication.cpp +++ b/tools/qmlpreview/qmlpreviewapplication.cpp @@ -104,11 +104,11 @@ void QmlPreviewApplication::parseArguments() parser.addHelpOption(); parser.addVersionOption(); - parser.addPositionalArgument(QLatin1String("program"), - tr("The program to be started and previewed."), - QLatin1String("[program]")); + parser.addPositionalArgument(QLatin1String("executable"), + tr("The executable to be started and previewed."), + QLatin1String("[executable]")); parser.addPositionalArgument(QLatin1String("parameters"), - tr("Parameters for the program to be started."), + tr("Parameters for the executable to be started."), QLatin1String("[parameters...]")); parser.process(*this); @@ -120,12 +120,12 @@ void QmlPreviewApplication::parseArguments() if (parser.isSet(verbose)) m_verbose = true; - m_programArguments = parser.positionalArguments(); - if (!m_programArguments.isEmpty()) - m_programPath = m_programArguments.takeFirst(); + m_arguments = parser.positionalArguments(); + if (!m_arguments.isEmpty()) + m_executablePath = m_arguments.takeFirst(); - if (m_programPath.isEmpty()) { - logError(tr("You have to specify a program to start.")); + if (m_executablePath.isEmpty()) { + logError(tr("You have to specify an executable to start.")); parser.showHelp(2); } } @@ -143,17 +143,17 @@ void QmlPreviewApplication::run() m_process.reset(new QProcess(this)); QStringList arguments; arguments << QString("-qmljsdebugger=file:%1,block,services:QmlPreview").arg(m_socketFile); - arguments << m_programArguments; + arguments << m_arguments; m_process->setProcessChannelMode(QProcess::MergedChannels); connect(m_process.data(), &QIODevice::readyRead, this, &QmlPreviewApplication::processHasOutput); connect(m_process.data(), static_cast<void(QProcess::*)(int)>(&QProcess::finished), this, [this](int){ processFinished(); }); - logStatus(QString("Starting '%1 %2' ...").arg(m_programPath, arguments.join(QLatin1Char(' ')))); - m_process->start(m_programPath, arguments); + logStatus(QString("Starting '%1 %2' ...").arg(m_executablePath, arguments.join(QLatin1Char(' ')))); + m_process->start(m_executablePath, arguments); if (!m_process->waitForStarted()) { - logError(QString("Could not run '%1': %2").arg(m_programPath, m_process->errorString())); + logError(QString("Could not run '%1': %2").arg(m_executablePath, m_process->errorString())); exit(1); } m_connectTimer.start(); diff --git a/tools/qmlpreview/qmlpreviewapplication.h b/tools/qmlpreview/qmlpreviewapplication.h index 7da4a9ab5c..51a70cbac3 100644 --- a/tools/qmlpreview/qmlpreviewapplication.h +++ b/tools/qmlpreview/qmlpreviewapplication.h @@ -63,8 +63,8 @@ private: bool sendFile(const QString &path); void sendDirectory(const QString &path); - QString m_programPath; - QStringList m_programArguments; + QString m_executablePath; + QStringList m_arguments; QScopedPointer<QProcess> m_process; bool m_verbose; diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index 6732766b46..04ad4b31e2 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -52,8 +52,8 @@ static const char commandTextC[] = " Stop recording if it is running, then output the\n" " data, and finally clear it from memory.\n" "'q', 'quit'\n" - " Terminate the program if started from qmlprofiler,\n" - " and qmlprofiler itself."; + " Terminate the target process if started from\n" + " qmlprofiler, and qmlprofiler itself."; static const char *features[] = { "javascript", @@ -199,11 +199,11 @@ void QmlProfilerApplication::parseArguments() parser.addHelpOption(); parser.addVersionOption(); - parser.addPositionalArgument(QLatin1String("program"), - tr("The program to be started and profiled."), - QLatin1String("[program]")); + parser.addPositionalArgument(QLatin1String("executable"), + tr("The executable to be started and profiled."), + QLatin1String("[executable]")); parser.addPositionalArgument(QLatin1String("parameters"), - tr("Parameters for the program to be started."), + tr("Parameters for the executable to be started."), QLatin1String("[parameters...]")); parser.process(*this); @@ -252,17 +252,17 @@ void QmlProfilerApplication::parseArguments() if (parser.isSet(verbose)) m_verbose = true; - m_programArguments = parser.positionalArguments(); - if (!m_programArguments.isEmpty()) - m_programPath = m_programArguments.takeFirst(); + m_arguments = parser.positionalArguments(); + if (!m_arguments.isEmpty()) + m_executablePath = m_arguments.takeFirst(); - if (m_runMode == LaunchMode && m_programPath.isEmpty()) { - logError(tr("You have to specify either --attach or a program to start.")); + if (m_runMode == LaunchMode && m_executablePath.isEmpty()) { + logError(tr("You have to specify either --attach or an executable to start.")); parser.showHelp(2); } - if (m_runMode == AttachMode && !m_programPath.isEmpty()) { - logError(tr("--attach cannot be used when starting a program.")); + if (m_runMode == AttachMode && !m_executablePath.isEmpty()) { + logError(tr("--attach cannot be used when starting an executable.")); parser.showHelp(3); } } @@ -469,17 +469,17 @@ void QmlProfilerApplication::run() arguments << QString::fromLatin1("-qmljsdebugger=%1:%2,block,services:CanvasFrameRate") .arg(QLatin1String(m_socketFile.isEmpty() ? "port" : "file")) .arg(m_socketFile.isEmpty() ? QString::number(m_port) : m_socketFile); - arguments << m_programArguments; + arguments << m_arguments; m_process->setProcessChannelMode(QProcess::MergedChannels); connect(m_process, &QIODevice::readyRead, this, &QmlProfilerApplication::processHasOutput); connect(m_process, static_cast<void(QProcess::*)(int)>(&QProcess::finished), this, [this](int){ processFinished(); }); - logStatus(QString("Starting '%1 %2' ...").arg(m_programPath, + logStatus(QString("Starting '%1 %2' ...").arg(m_executablePath, arguments.join(QLatin1Char(' ')))); - m_process->start(m_programPath, arguments); + m_process->start(m_executablePath, arguments); if (!m_process->waitForStarted()) { - logError(QString("Could not run '%1': %2").arg(m_programPath, + logError(QString("Could not run '%1': %2").arg(m_executablePath, m_process->errorString())); exit(1); } diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h index 2d00e2b7c5..73b2b231cd 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.h +++ b/tools/qmlprofiler/qmlprofilerapplication.h @@ -91,8 +91,8 @@ private: } m_runMode; // LaunchMode - QString m_programPath; - QStringList m_programArguments; + QString m_executablePath; + QStringList m_arguments; QProcess *m_process; QString m_socketFile; diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index c9e7dbadc9..5190368e20 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -53,8 +53,8 @@ #include <QtWidgets/QApplication> #if QT_CONFIG(filedialog) #include <QtWidgets/QFileDialog> -#endif -#endif +#endif // QT_CONFIG(filedialog) +#endif // QT_WIDGETS_LIB #include <QtCore/QTranslator> #include <QtCore/QLibraryInfo> diff --git a/tools/tools.pro b/tools/tools.pro index d3ec380717..2e2eb831a9 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -28,7 +28,13 @@ qtConfig(thread):!android|android_app { qmlplugindump } } - qtHaveModule(widgets): SUBDIRS += qmleasing + qtHaveModule(widgets) { + QT_FOR_CONFIG += widgets + qtConfig(dialogbuttonbox) { + SUBDIRS += \ + qmleasing + } + } } qtHaveModule(qmltest): SUBDIRS += qmltestrunner qtConfig(private_tests): SUBDIRS += qmljs |