aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-07-21 16:11:16 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-08-04 13:35:25 +0000
commit5652c4163f94aaf4bd9cef994be2ae8e7f4096c5 (patch)
treea42e882963b3e7b328dfd23da275c4e825bfb544 /src/qml
parentf8e5cfcfc26499eef30fc222e24957a753651cbc (diff)
Move debugger-specific services into a common plugin
Change-Id: Icd4e6a6c57bc3ac65cb43d2329d236012b988678 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/debugger.pri6
-rw-r--r--src/qml/debugger/qdebugmessageservice.cpp103
-rw-r--r--src/qml/debugger/qdebugmessageservice_p.h83
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp8
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp827
-rw-r--r--src/qml/debugger/qqmlenginedebugservice_p.h135
-rw-r--r--src/qml/debugger/qv4debugservice.cpp1207
-rw-r--r--src/qml/debugger/qv4debugservice_p.h138
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqmlwatcher.cpp181
-rw-r--r--src/qml/qml/qqmlwatcher_p.h86
11 files changed, 1 insertions, 2775 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index 9734e07a1d..728394916c 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -5,9 +5,6 @@ SOURCES += \
$$PWD/qqmldebugconnector.cpp \
$$PWD/qqmldebugservice.cpp \
$$PWD/qqmldebugserviceinterfaces.cpp \
- $$PWD/qqmlenginedebugservice.cpp \
- $$PWD/qdebugmessageservice.cpp \
- $$PWD/qv4debugservice.cpp \
$$PWD/qqmlabstractprofileradapter.cpp \
$$PWD/qqmlprofiler.cpp
@@ -18,10 +15,7 @@ HEADERS += \
$$PWD/qqmldebugservicefactory_p.h \
$$PWD/qqmldebugserviceinterfaces_p.h \
$$PWD/qqmldebugstatesdelegate_p.h \
- $$PWD/qqmlenginedebugservice_p.h \
$$PWD/qqmldebug.h \
- $$PWD/qdebugmessageservice_p.h \
- $$PWD/qv4debugservice_p.h \
$$PWD/qqmlconfigurabledebugservice_p.h \
$$PWD/qqmlprofilerdefinitions_p.h \
$$PWD/qqmlabstractprofileradapter_p.h \
diff --git a/src/qml/debugger/qdebugmessageservice.cpp b/src/qml/debugger/qdebugmessageservice.cpp
deleted file mode 100644
index 6b0f184951..0000000000
--- a/src/qml/debugger/qdebugmessageservice.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdebugmessageservice_p.h"
-#include <private/qqmldebugconnector_p.h>
-
-#include <QDataStream>
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QDebugMessageService, qmlDebugMessageService)
-
-const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages");
-
-void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
- const QString &buf)
-{
- QQmlDebugConnector::service<QDebugMessageService>()->sendDebugMessage(type, ctxt, buf);
-}
-
-QDebugMessageService::QDebugMessageService(QObject *parent) :
- QQmlDebugService(s_key, 2, parent), oldMsgHandler(0),
- prevState(QQmlDebugService::NotConnected)
-{
- // don't execute stateChanged() in parallel
- QMutexLocker lock(&initMutex);
- if (state() == Enabled) {
- oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
- prevState = Enabled;
- }
-}
-
-QDebugMessageService *QDebugMessageService::instance()
-{
- return qmlDebugMessageService();
-}
-
-void QDebugMessageService::sendDebugMessage(QtMsgType type,
- const QMessageLogContext &ctxt,
- const QString &buf)
-{
- //We do not want to alter the message handling mechanism
- //We just eavesdrop and forward the messages to a port
- //only if a client is connected to it.
- QByteArray message;
- QQmlDebugStream ws(&message, QIODevice::WriteOnly);
- ws << QByteArray("MESSAGE") << type << buf.toUtf8();
- ws << QString::fromLatin1(ctxt.file).toUtf8();
- ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8();
-
- emit messageToClient(name(), message);
- if (oldMsgHandler)
- (*oldMsgHandler)(type, ctxt, buf);
-}
-
-void QDebugMessageService::stateChanged(State state)
-{
- QMutexLocker lock(&initMutex);
-
- if (state != Enabled && prevState == Enabled) {
- QtMessageHandler handler = qInstallMessageHandler(oldMsgHandler);
- // has our handler been overwritten in between?
- if (handler != DebugMessageHandler)
- qInstallMessageHandler(handler);
-
- } else if (state == Enabled && prevState != Enabled) {
- oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
- }
-
- prevState = state;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/debugger/qdebugmessageservice_p.h b/src/qml/debugger/qdebugmessageservice_p.h
deleted file mode 100644
index 3d0d8a79a5..0000000000
--- a/src/qml/debugger/qdebugmessageservice_p.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDEBUGMESSAGESERVICE_P_H
-#define QDEBUGMESSAGESERVICE_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 "qqmldebugservice_p.h"
-
-#include <QtCore/qlogging.h>
-#include <QtCore/qmutex.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDebugMessageServicePrivate;
-
-class QDebugMessageService : public QQmlDebugService
-{
- Q_OBJECT
-public:
- QDebugMessageService(QObject *parent = 0);
-
- static QDebugMessageService *instance();
-
- void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt,
- const QString &buf);
-
-protected:
- static const QString s_key;
-
- void stateChanged(State);
-
-private:
- friend class QQmlDebugConnector;
-
- QtMessageHandler oldMsgHandler;
- QQmlDebugService::State prevState;
- QMutex initMutex;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDEBUGMESSAGESERVICE_P_H
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index 9565f19563..393185bf0d 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -33,9 +33,6 @@
#include "qqmldebugpluginmanager_p.h"
#include "qqmldebugconnector_p.h"
-#include "qdebugmessageservice_p.h"
-#include "qqmlenginedebugservice_p.h"
-#include "qv4debugservice_p.h"
#include "qqmldebugservicefactory_p.h"
#include <QtCore/QPluginLoader>
#include <QtCore/QCoreApplication>
@@ -55,6 +52,7 @@ Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebugServerFactory)
Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugService)
Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory)
Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory)
+Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory)
struct QQmlDebugConnectorParams {
QString pluginKey;
@@ -118,10 +116,6 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
}
params->instance = loadQQmlDebugConnector(QLatin1String("QQmlDebugServer"));
if (params->instance) {
- QQmlEngineDebugServiceImpl::instance();
- QV4DebugServiceImpl::instance();
- QDebugMessageService::instance();
-
foreach (const QJsonObject &object, metaDataForQQmlDebugService()) {
foreach (const QJsonValue &key, object.value(QLatin1String("MetaData")).toObject()
.value(QLatin1String("Keys")).toArray()) {
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp
deleted file mode 100644
index 30d2f32e2c..0000000000
--- a/src/qml/debugger/qqmlenginedebugservice.cpp
+++ /dev/null
@@ -1,827 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlenginedebugservice_p.h"
-
-#include "qqmldebugstatesdelegate_p.h"
-#include <private/qqmlboundsignal_p.h>
-#include <qqmlengine.h>
-#include <private/qqmlmetatype_p.h>
-#include <qqmlproperty.h>
-#include <private/qqmlproperty_p.h>
-#include <private/qqmlbinding_p.h>
-#include <private/qqmlcontext_p.h>
-#include <private/qqmlwatcher_p.h>
-#include <private/qqmlvaluetype_p.h>
-#include <private/qqmlvmemetaobject_p.h>
-#include <private/qqmlexpression_p.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qfileinfo.h>
-#include <private/qmetaobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QQmlEngineDebugServiceImpl, qmlEngineDebugService)
-
-QQmlEngineDebugServiceImpl *QQmlEngineDebugServiceImpl::instance()
-{
- return qmlEngineDebugService();
-}
-
-QQmlEngineDebugServiceImpl::QQmlEngineDebugServiceImpl(QObject *parent) :
- QQmlEngineDebugService(2, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(0)
-{
- QObject::connect(m_watch, SIGNAL(propertyChanged(int,int,QMetaProperty,QVariant)),
- this, SLOT(propertyChanged(int,int,QMetaProperty,QVariant)));
-}
-
-QQmlEngineDebugServiceImpl::~QQmlEngineDebugServiceImpl()
-{
- delete m_statesDelegate;
-}
-
-QDataStream &operator<<(QDataStream &ds,
- const QQmlEngineDebugServiceImpl::QQmlObjectData &data)
-{
- ds << data.url << data.lineNumber << data.columnNumber << data.idString
- << data.objectName << data.objectType << data.objectId << data.contextId
- << data.parentId;
- return ds;
-}
-
-QDataStream &operator>>(QDataStream &ds,
- QQmlEngineDebugServiceImpl::QQmlObjectData &data)
-{
- ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
- >> data.objectName >> data.objectType >> data.objectId >> data.contextId
- >> data.parentId;
- return ds;
-}
-
-QDataStream &operator<<(QDataStream &ds,
- const QQmlEngineDebugServiceImpl::QQmlObjectProperty &data)
-{
- ds << (int)data.type << data.name;
- // check first whether the data can be saved
- // (otherwise we assert in QVariant::operator<<)
- QByteArray buffer;
- QDataStream fakeStream(&buffer, QIODevice::WriteOnly);
- if (QMetaType::save(fakeStream, data.value.type(), data.value.constData()))
- ds << data.value;
- else
- ds << QVariant();
- ds << data.valueTypeName << data.binding << data.hasNotifySignal;
- return ds;
-}
-
-QDataStream &operator>>(QDataStream &ds,
- QQmlEngineDebugServiceImpl::QQmlObjectProperty &data)
-{
- int type;
- ds >> type >> data.name >> data.value >> data.valueTypeName
- >> data.binding >> data.hasNotifySignal;
- data.type = (QQmlEngineDebugServiceImpl::QQmlObjectProperty::Type)type;
- return ds;
-}
-
-static inline bool isSignalPropertyName(const QString &signalName)
-{
- // see QmlCompiler::isSignalPropertyName
- return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) &&
- signalName.at(2).isLetter() && signalName.at(2).isUpper();
-}
-
-static bool hasValidSignal(QObject *object, const QString &propertyName)
-{
- if (!isSignalPropertyName(propertyName))
- return false;
-
- QString signalName = propertyName.mid(2);
- signalName[0] = signalName.at(0).toLower();
-
- int sigIdx = QQmlPropertyPrivate::findSignalByName(object->metaObject(), signalName.toLatin1()).methodIndex();
-
- if (sigIdx == -1)
- return false;
-
- return true;
-}
-
-QQmlEngineDebugServiceImpl::QQmlObjectProperty
-QQmlEngineDebugServiceImpl::propertyData(QObject *obj, int propIdx)
-{
- QQmlObjectProperty rv;
-
- QMetaProperty prop = obj->metaObject()->property(propIdx);
-
- rv.type = QQmlObjectProperty::Unknown;
- rv.valueTypeName = QString::fromUtf8(prop.typeName());
- rv.name = QString::fromUtf8(prop.name());
- rv.hasNotifySignal = prop.hasNotifySignal();
- QQmlAbstractBinding *binding =
- QQmlPropertyPrivate::binding(QQmlProperty(obj, rv.name));
- if (binding)
- rv.binding = binding->expression();
-
- if (QQmlValueTypeFactory::isValueType(prop.userType())) {
- rv.type = QQmlObjectProperty::Basic;
- } else if (QQmlMetaType::isQObject(prop.userType())) {
- rv.type = QQmlObjectProperty::Object;
- } else if (QQmlMetaType::isList(prop.userType())) {
- rv.type = QQmlObjectProperty::List;
- } else if (prop.userType() == QMetaType::QVariant) {
- rv.type = QQmlObjectProperty::Variant;
- }
-
- QVariant value;
- if (rv.type != QQmlObjectProperty::Unknown && prop.userType() != 0) {
- value = prop.read(obj);
- }
- rv.value = valueContents(value);
-
- return rv;
-}
-
-QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
-{
- // We can't send JS objects across the wire, so transform them to variant
- // maps for serialization.
- if (value.userType() == qMetaTypeId<QJSValue>())
- value = value.value<QJSValue>().toVariant();
- const int userType = value.userType();
-
- //QObject * is not streamable.
- //Convert all such instances to a String value
-
- if (value.type() == QVariant::List) {
- QVariantList contents;
- QVariantList list = value.toList();
- int count = list.size();
- contents.reserve(count);
- for (int i = 0; i < count; i++)
- contents << valueContents(list.at(i));
- return contents;
- }
-
- if (value.type() == QVariant::Map) {
- QVariantMap contents;
- QMapIterator<QString, QVariant> i(value.toMap());
- while (i.hasNext()) {
- i.next();
- contents.insert(i.key(), valueContents(i.value()));
- }
- return contents;
- }
-
- if (QQmlValueTypeFactory::isValueType(userType)) {
- const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(userType);
- if (mo) {
- int toStringIndex = mo->indexOfMethod("toString");
- if (toStringIndex != -1) {
- QMetaMethod mm = mo->method(toStringIndex);
- QMetaType info(userType);
- QString s;
- if (info.flags() & QMetaType::IsGadget
- && mm.invokeOnGadget(value.data(), Q_RETURN_ARG(QString, s)))
- return s;
- }
- }
-
- return value;
- }
-
- if (QQmlMetaType::isQObject(userType)) {
- QObject *o = QQmlMetaType::toQObject(value);
- if (o) {
- QString name = o->objectName();
- if (name.isEmpty())
- name = QStringLiteral("<unnamed object>");
- return name;
- }
- }
-
- return QString(QStringLiteral("<unknown value>"));
-}
-
-void QQmlEngineDebugServiceImpl::buildObjectDump(QDataStream &message,
- QObject *object, bool recur, bool dumpProperties)
-{
- message << objectData(object);
-
- QObjectList children = object->children();
-
- int childrenCount = children.count();
- for (int ii = 0; ii < children.count(); ++ii) {
- if (qobject_cast<QQmlContext*>(children[ii]))
- --childrenCount;
- }
-
- message << childrenCount << recur;
-
- QList<QQmlObjectProperty> fakeProperties;
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
- if (qobject_cast<QQmlContext*>(child))
- continue;
- if (recur)
- buildObjectDump(message, child, recur, dumpProperties);
- else
- message << objectData(child);
- }
-
- if (!dumpProperties) {
- message << 0;
- return;
- }
-
- QList<int> propertyIndexes;
- for (int ii = 0; ii < object->metaObject()->propertyCount(); ++ii) {
- if (object->metaObject()->property(ii).isScriptable())
- propertyIndexes << ii;
- }
-
- QQmlData *ddata = QQmlData::get(object);
- if (ddata && ddata->signalHandlers) {
- QQmlBoundSignal *signalHandler = ddata->signalHandlers;
-
- while (signalHandler) {
- QQmlObjectProperty prop;
- prop.type = QQmlObjectProperty::SignalProperty;
- prop.hasNotifySignal = false;
- QQmlBoundSignalExpression *expr = signalHandler->expression();
- if (expr) {
- prop.value = expr->expression();
- QObject *scope = expr->scopeObject();
- if (scope) {
- QString methodName = QString::fromLatin1(QMetaObjectPrivate::signal(scope->metaObject(), signalHandler->signalIndex()).name());
- if (!methodName.isEmpty()) {
- prop.name = QLatin1String("on") + methodName[0].toUpper()
- + methodName.mid(1);
- }
- }
- }
- fakeProperties << prop;
-
- signalHandler = nextSignal(signalHandler);
- }
- }
-
- message << propertyIndexes.size() + fakeProperties.count();
-
- for (int ii = 0; ii < propertyIndexes.size(); ++ii)
- message << propertyData(object, propertyIndexes.at(ii));
-
- for (int ii = 0; ii < fakeProperties.count(); ++ii)
- message << fakeProperties[ii];
-}
-
-void QQmlEngineDebugServiceImpl::prepareDeferredObjects(QObject *obj)
-{
- qmlExecuteDeferred(obj);
-
- QObjectList children = obj->children();
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
- prepareDeferredObjects(child);
- }
-
-}
-
-void QQmlEngineDebugServiceImpl::storeObjectIds(QObject *co)
-{
- QQmlDebugService::idForObject(co);
- QObjectList children = co->children();
- for (int ii = 0; ii < children.count(); ++ii)
- storeObjectIds(children.at(ii));
-}
-
-void QQmlEngineDebugServiceImpl::buildObjectList(QDataStream &message,
- QQmlContext *ctxt,
- const QList<QPointer<QObject> > &instances)
-{
- QQmlContextData *p = QQmlContextData::get(ctxt);
-
- QString ctxtName = ctxt->objectName();
- int ctxtId = QQmlDebugService::idForObject(ctxt);
- if (ctxt->contextObject())
- storeObjectIds(ctxt->contextObject());
-
- message << ctxtName << ctxtId;
-
- int count = 0;
-
- QQmlContextData *child = p->childContexts;
- while (child) {
- ++count;
- child = child->nextChild;
- }
-
- message << count;
-
- child = p->childContexts;
- while (child) {
- buildObjectList(message, child->asQQmlContext(), instances);
- child = child->nextChild;
- }
-
- count = 0;
- for (int ii = 0; ii < instances.count(); ++ii) {
- QQmlData *data = QQmlData::get(instances.at(ii));
- if (data->context == p)
- count ++;
- }
- message << count;
-
- for (int ii = 0; ii < instances.count(); ++ii) {
- QQmlData *data = QQmlData::get(instances.at(ii));
- if (data->context == p)
- message << objectData(instances.at(ii));
- }
-}
-
-void QQmlEngineDebugServiceImpl::buildStatesList(bool cleanList,
- const QList<QPointer<QObject> > &instances)
-{
- if (m_statesDelegate)
- m_statesDelegate->buildStatesList(cleanList, instances);
-}
-
-QQmlEngineDebugServiceImpl::QQmlObjectData
-QQmlEngineDebugServiceImpl::objectData(QObject *object)
-{
- QQmlData *ddata = QQmlData::get(object);
- QQmlObjectData rv;
- if (ddata && ddata->outerContext) {
- rv.url = ddata->outerContext->url();
- rv.lineNumber = ddata->lineNumber;
- rv.columnNumber = ddata->columnNumber;
- } else {
- rv.lineNumber = -1;
- rv.columnNumber = -1;
- }
-
- QQmlContext *context = qmlContext(object);
- if (context) {
- QQmlContextData *cdata = QQmlContextData::get(context);
- if (cdata)
- rv.idString = cdata->findObjectId(object);
- }
-
- rv.objectName = object->objectName();
- rv.objectId = QQmlDebugService::idForObject(object);
- rv.contextId = QQmlDebugService::idForObject(qmlContext(object));
- rv.parentId = QQmlDebugService::idForObject(object->parent());
- QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
- if (type) {
- QString typeName = type->qmlTypeName();
- int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
- rv.objectType = lastSlash < 0 ? typeName : typeName.mid(lastSlash+1);
- } else {
- rv.objectType = QString::fromUtf8(object->metaObject()->className());
- int marker = rv.objectType.indexOf(QLatin1String("_QMLTYPE_"));
- if (marker != -1)
- rv.objectType = rv.objectType.left(marker);
- }
-
- return rv;
-}
-
-void QQmlEngineDebugServiceImpl::messageReceived(const QByteArray &message)
-{
- QMetaObject::invokeMethod(this, "processMessage", Qt::QueuedConnection, Q_ARG(QByteArray, message));
-}
-
-/*!
- Returns a list of objects matching the given filename, line and column.
-*/
-QList<QObject*> QQmlEngineDebugServiceImpl::objectForLocationInfo(const QString &filename,
- int lineNumber, int columnNumber)
-{
- QList<QObject *> objects;
- const QHash<int, QObject *> &hash = objectsForIds();
- for (QHash<int, QObject *>::ConstIterator i = hash.constBegin(); i != hash.constEnd(); ++i) {
- QQmlData *ddata = QQmlData::get(i.value());
- if (ddata && ddata->outerContext) {
- if (QFileInfo(ddata->outerContext->urlString()).fileName() == filename &&
- ddata->lineNumber == lineNumber &&
- ddata->columnNumber >= columnNumber) {
- objects << i.value();
- }
- }
- }
- return objects;
-}
-
-void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
-{
- QQmlDebugStream ds(message);
-
- QByteArray type;
- int queryId;
- ds >> type >> queryId;
-
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
-
- if (type == "LIST_ENGINES") {
- rs << QByteArray("LIST_ENGINES_R");
- rs << queryId << m_engines.count();
-
- for (int ii = 0; ii < m_engines.count(); ++ii) {
- QQmlEngine *engine = m_engines.at(ii);
-
- QString engineName = engine->objectName();
- int engineId = QQmlDebugService::idForObject(engine);
-
- rs << engineName << engineId;
- }
-
- } else if (type == "LIST_OBJECTS") {
- int engineId = -1;
- ds >> engineId;
-
- QQmlEngine *engine =
- qobject_cast<QQmlEngine *>(QQmlDebugService::objectForId(engineId));
-
- rs << QByteArray("LIST_OBJECTS_R") << queryId;
-
- if (engine) {
- QQmlContext *rootContext = engine->rootContext();
- // Clean deleted objects
- QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(rootContext);
- for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
- if (!ctxtPriv->instances.at(ii)) {
- ctxtPriv->instances.removeAt(ii);
- --ii;
- }
- }
- buildObjectList(rs, rootContext, ctxtPriv->instances);
- buildStatesList(true, ctxtPriv->instances);
- }
-
- } else if (type == "FETCH_OBJECT") {
- int objectId;
- bool recurse;
- bool dumpProperties = true;
-
- ds >> objectId >> recurse >> dumpProperties;
-
- QObject *object = QQmlDebugService::objectForId(objectId);
-
- rs << QByteArray("FETCH_OBJECT_R") << queryId;
-
- if (object) {
- if (recurse)
- prepareDeferredObjects(object);
- buildObjectDump(rs, object, recurse, dumpProperties);
- }
-
- } else if (type == "FETCH_OBJECTS_FOR_LOCATION") {
- QString file;
- int lineNumber;
- int columnNumber;
- bool recurse;
- bool dumpProperties = true;
-
- ds >> file >> lineNumber >> columnNumber >> recurse >> dumpProperties;
-
- QList<QObject*> objects = objectForLocationInfo(file, lineNumber, columnNumber);
-
- rs << QByteArray("FETCH_OBJECTS_FOR_LOCATION_R") << queryId
- << objects.count();
-
- foreach (QObject *object, objects) {
- if (recurse)
- prepareDeferredObjects(object);
- buildObjectDump(rs, object, recurse, dumpProperties);
- }
-
- } else if (type == "WATCH_OBJECT") {
- int objectId;
-
- ds >> objectId;
- bool ok = m_watch->addWatch(queryId, objectId);
-
- rs << QByteArray("WATCH_OBJECT_R") << queryId << ok;
-
- } else if (type == "WATCH_PROPERTY") {
- int objectId;
- QByteArray property;
-
- ds >> objectId >> property;
- bool ok = m_watch->addWatch(queryId, objectId, property);
-
- rs << QByteArray("WATCH_PROPERTY_R") << queryId << ok;
-
- } else if (type == "WATCH_EXPR_OBJECT") {
- int debugId;
- QString expr;
-
- ds >> debugId >> expr;
- bool ok = m_watch->addWatch(queryId, debugId, expr);
-
- rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok;
-
- } else if (type == "NO_WATCH") {
- bool ok = m_watch->removeWatch(queryId);
-
- rs << QByteArray("NO_WATCH_R") << queryId << ok;
-
- } else if (type == "EVAL_EXPRESSION") {
- int objectId;
- QString expr;
-
- ds >> objectId >> expr;
- int engineId = -1;
- if (!ds.atEnd())
- ds >> engineId;
-
- QObject *object = QQmlDebugService::objectForId(objectId);
- QQmlContext *context = qmlContext(object);
- if (!context) {
- QQmlEngine *engine = qobject_cast<QQmlEngine *>(
- QQmlDebugService::objectForId(engineId));
- if (engine && m_engines.contains(engine))
- context = engine->rootContext();
- }
- QVariant result;
- if (context) {
- QQmlExpression exprObj(context, object, expr);
- bool undefined = false;
- QVariant value = exprObj.evaluate(&undefined);
- if (undefined)
- result = QString(QStringLiteral("<undefined>"));
- else
- result = valueContents(value);
- } else {
- result = QString(QStringLiteral("<unknown context>"));
- }
-
- rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result;
-
- } else if (type == "SET_BINDING") {
- int objectId;
- QString propertyName;
- QVariant expr;
- bool isLiteralValue;
- QString filename;
- int line;
- ds >> objectId >> propertyName >> expr >> isLiteralValue >>
- filename >> line;
- bool ok = setBinding(objectId, propertyName, expr, isLiteralValue,
- filename, line);
-
- rs << QByteArray("SET_BINDING_R") << queryId << ok;
-
- } else if (type == "RESET_BINDING") {
- int objectId;
- QString propertyName;
- ds >> objectId >> propertyName;
- bool ok = resetBinding(objectId, propertyName);
-
- rs << QByteArray("RESET_BINDING_R") << queryId << ok;
-
- } else if (type == "SET_METHOD_BODY") {
- int objectId;
- QString methodName;
- QString methodBody;
- ds >> objectId >> methodName >> methodBody;
- bool ok = setMethodBody(objectId, methodName, methodBody);
-
- rs << QByteArray("SET_METHOD_BODY_R") << queryId << ok;
-
- }
- emit messageToClient(name(), reply);
-}
-
-bool QQmlEngineDebugServiceImpl::setBinding(int objectId,
- const QString &propertyName,
- const QVariant &expression,
- bool isLiteralValue,
- QString filename,
- int line,
- int column)
-{
- bool ok = true;
- QObject *object = objectForId(objectId);
- QQmlContext *context = qmlContext(object);
-
- if (object && context) {
- QQmlProperty property(object, propertyName, context);
- if (property.isValid()) {
-
- bool inBaseState = true;
- if (m_statesDelegate) {
- m_statesDelegate->updateBinding(context, property, expression, isLiteralValue,
- filename, line, column, &inBaseState);
- }
-
- if (inBaseState) {
- if (isLiteralValue) {
- property.write(expression);
- } else if (hasValidSignal(object, propertyName)) {
- QQmlBoundSignalExpression *qmlExpression = new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(property)->signalIndex(),
- QQmlContextData::get(context), object, expression.toString(),
- filename, line, column);
- QQmlPropertyPrivate::takeSignalExpression(property, qmlExpression);
- } else if (property.isProperty()) {
- QQmlBinding *binding = new QQmlBinding(expression.toString(), object, QQmlContextData::get(context), filename, line, column);
- binding->setTarget(property);
- QQmlPropertyPrivate::setBinding(binding);
- binding->update();
- } else {
- ok = false;
- qWarning() << "QQmlEngineDebugService::setBinding: unable to set property" << propertyName << "on object" << object;
- }
- }
-
- } else {
- // not a valid property
- if (m_statesDelegate)
- ok = m_statesDelegate->setBindingForInvalidProperty(object, propertyName, expression, isLiteralValue);
- if (!ok)
- qWarning() << "QQmlEngineDebugService::setBinding: unable to set property" << propertyName << "on object" << object;
- }
- }
- return ok;
-}
-
-bool QQmlEngineDebugServiceImpl::resetBinding(int objectId, const QString &propertyName)
-{
- QObject *object = objectForId(objectId);
- QQmlContext *context = qmlContext(object);
-
- if (object && context) {
- QString parentProperty = propertyName;
- if (propertyName.indexOf(QLatin1Char('.')) != -1)
- parentProperty = propertyName.left(propertyName.indexOf(QLatin1Char('.')));
-
- if (object->property(parentProperty.toLatin1()).isValid()) {
- QQmlProperty property(object, propertyName);
- QQmlPropertyPrivate::removeBinding(property);
- if (property.isResettable()) {
- // Note: this will reset the property in any case, without regard to states
- // Right now almost no QQuickItem has reset methods for its properties (with the
- // notable exception of QQuickAnchors), so this is not a big issue
- // later on, setBinding does take states into account
- property.reset();
- } else {
- // overwrite with default value
- if (QQmlType *objType = QQmlMetaType::qmlType(object->metaObject())) {
- if (QObject *emptyObject = objType->create()) {
- if (emptyObject->property(parentProperty.toLatin1()).isValid()) {
- QVariant defaultValue = QQmlProperty(emptyObject, propertyName).read();
- if (defaultValue.isValid()) {
- setBinding(objectId, propertyName, defaultValue, true);
- }
- }
- delete emptyObject;
- }
- }
- }
- return true;
- }
-
- if (hasValidSignal(object, propertyName)) {
- QQmlProperty property(object, propertyName, context);
- QQmlPropertyPrivate::setSignalExpression(property, 0);
- return true;
- }
-
- if (m_statesDelegate) {
- m_statesDelegate->resetBindingForInvalidProperty(object, propertyName);
- return true;
- }
-
- return false;
- }
- // object or context null.
- return false;
-}
-
-bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &method, const QString &body)
-{
- QObject *object = objectForId(objectId);
- QQmlContext *context = qmlContext(object);
- if (!object || !context || !context->engine())
- return false;
- QQmlContextData *contextData = QQmlContextData::get(context);
- if (!contextData)
- return false;
-
- QQmlPropertyData dummy;
- QQmlPropertyData *prop =
- QQmlPropertyCache::property(context->engine(), object, method, contextData, dummy);
-
- if (!prop || !prop->isVMEFunction())
- return false;
-
- QMetaMethod metaMethod = object->metaObject()->method(prop->coreIndex);
- QList<QByteArray> paramNames = metaMethod.parameterNames();
-
- QString paramStr;
- for (int ii = 0; ii < paramNames.count(); ++ii) {
- if (ii != 0) paramStr.append(QLatin1Char(','));
- paramStr.append(QString::fromUtf8(paramNames.at(ii)));
- }
-
- QString jsfunction = QLatin1String("(function ") + method + QLatin1Char('(') + paramStr +
- QLatin1String(") {");
- jsfunction += body;
- jsfunction += QLatin1String("\n})");
-
- QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this
-
- int lineNumber = vmeMetaObject->vmeMethodLineNumber(prop->coreIndex);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(object)->handle());
- QV4::Scope scope(v4);
- QV4::ScopedValue v(scope, QQmlJavaScriptExpression::evalFunction(contextData, object, jsfunction, contextData->urlString(), lineNumber));
- vmeMetaObject->setVmeMethod(prop->coreIndex, v);
- return true;
-}
-
-void QQmlEngineDebugServiceImpl::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value)
-{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
-
- rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value);
-
- emit messageToClient(name(), reply);
-}
-
-void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
-{
- Q_ASSERT(engine);
- Q_ASSERT(!m_engines.contains(engine));
-
- m_engines.append(engine);
- emit attachedToEngine(engine);
-}
-
-void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
-{
- Q_ASSERT(engine);
- Q_ASSERT(m_engines.contains(engine));
-
- m_engines.removeAll(engine);
- emit detachedFromEngine(engine);
-}
-
-void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *object)
-{
- Q_ASSERT(engine);
- Q_ASSERT(m_engines.contains(engine));
-
- int engineId = QQmlDebugService::idForObject(engine);
- int objectId = QQmlDebugService::idForObject(object);
- int parentId = QQmlDebugService::idForObject(object->parent());
-
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
-
- //unique queryId -1
- rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId << parentId;
- emit messageToClient(name(), reply);
-}
-
-void QQmlEngineDebugServiceImpl::setStatesDelegate(QQmlDebugStatesDelegate *delegate)
-{
- m_statesDelegate = delegate;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlenginedebugservice_p.h b/src/qml/debugger/qqmlenginedebugservice_p.h
deleted file mode 100644
index 99a98e1f12..0000000000
--- a/src/qml/debugger/qqmlenginedebugservice_p.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLENGINEDEBUGSERVICE_P_H
-#define QQMLENGINEDEBUGSERVICE_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 <private/qqmldebugservice_p.h>
-#include <private/qqmldebugserviceinterfaces_p.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/QPointer>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-class QQmlContext;
-class QQmlWatcher;
-class QDataStream;
-class QQmlDebugStatesDelegate;
-
-class Q_QML_PRIVATE_EXPORT QQmlEngineDebugServiceImpl : public QQmlEngineDebugService
-{
- Q_OBJECT
-public:
- QQmlEngineDebugServiceImpl(QObject * = 0);
- ~QQmlEngineDebugServiceImpl();
-
- struct QQmlObjectData {
- QUrl url;
- int lineNumber;
- int columnNumber;
- QString idString;
- QString objectName;
- QString objectType;
- int objectId;
- int contextId;
- int parentId;
- };
-
- struct QQmlObjectProperty {
- enum Type { Unknown, Basic, Object, List, SignalProperty, Variant };
- Type type;
- QString name;
- QVariant value;
- QString valueTypeName;
- QString binding;
- bool hasNotifySignal;
- };
-
- void engineAboutToBeAdded(QQmlEngine *);
- void engineAboutToBeRemoved(QQmlEngine *);
- void objectCreated(QQmlEngine *, QObject *);
-
- void setStatesDelegate(QQmlDebugStatesDelegate *);
-
- static QQmlEngineDebugServiceImpl *instance();
-
-protected:
- virtual void messageReceived(const QByteArray &);
-
-private Q_SLOTS:
- void processMessage(const QByteArray &msg);
- void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
-
-private:
- void prepareDeferredObjects(QObject *);
- void buildObjectList(QDataStream &, QQmlContext *,
- const QList<QPointer<QObject> > &instances);
- void buildObjectDump(QDataStream &, QObject *, bool, bool);
- void buildStatesList(bool cleanList, const QList<QPointer<QObject> > &instances);
- QQmlObjectData objectData(QObject *);
- QQmlObjectProperty propertyData(QObject *, int);
- QVariant valueContents(QVariant defaultValue) const;
- bool setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, QString filename = QString(), int line = -1, int column = 0);
- bool resetBinding(int objectId, const QString &propertyName);
- bool setMethodBody(int objectId, const QString &method, const QString &body);
- void storeObjectIds(QObject *co);
- QList<QObject *> objectForLocationInfo(const QString &filename, int lineNumber,
- int columnNumber);
-
- QList<QQmlEngine *> m_engines;
- QQmlWatcher *m_watch;
- QQmlDebugStatesDelegate *m_statesDelegate;
-};
-Q_QML_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QQmlEngineDebugServiceImpl::QQmlObjectData &);
-Q_QML_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QQmlEngineDebugServiceImpl::QQmlObjectData &);
-Q_QML_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QQmlEngineDebugServiceImpl::QQmlObjectProperty &);
-Q_QML_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QQmlEngineDebugServiceImpl::QQmlObjectProperty &);
-
-QT_END_NAMESPACE
-
-#endif // QQMLENGINEDEBUGSERVICE_P_H
-
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
deleted file mode 100644
index 94755bd35e..0000000000
--- a/src/qml/debugger/qv4debugservice.cpp
+++ /dev/null
@@ -1,1207 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv4debugservice_p.h"
-#include "qqmlengine.h"
-#include "qv4engine_p.h"
-#include "qv4function_p.h"
-#include "qqmldebugconnector_p.h"
-
-#include <private/qv8engine_p.h>
-
-#include <QtCore/QJsonArray>
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonObject>
-
-const char *const V4_CONNECT = "connect";
-const char *const V4_DISCONNECT = "disconnect";
-const char *const V4_BREAK_ON_SIGNAL = "breakonsignal";
-const char *const V4_PAUSE = "interrupt";
-
-#define NO_PROTOCOL_TRACING
-#ifdef NO_PROTOCOL_TRACING
-# define TRACE_PROTOCOL(x)
-#else
-#include <QtCore/QDebug>
-# define TRACE_PROTOCOL(x) x
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QV4DebugServiceImpl, v4ServiceInstance)
-
-class V8CommandHandler;
-class UnknownV8CommandHandler;
-
-class VariableCollector: public QV4::Debugging::Debugger::Collector
-{
-public:
- VariableCollector(QV4::ExecutionEngine *engine)
- : Collector(engine)
- , destination(0)
- {}
-
- virtual ~VariableCollector() {}
-
- void collectScope(QJsonArray *dest, QV4::Debugging::Debugger *debugger, int frameNr, int scopeNr)
- {
- qSwap(destination, dest);
- bool oldIsProp = isProperty();
- setIsProperty(true);
- debugger->collectArgumentsInContext(this, frameNr, scopeNr);
- debugger->collectLocalsInContext(this, frameNr, scopeNr);
- setIsProperty(oldIsProp);
- qSwap(destination, dest);
- }
-
- void setDestination(QJsonArray *dest)
- { destination = dest; }
-
- QJsonArray retrieveRefsToInclude()
- {
- QJsonArray result;
- qSwap(refsToInclude, result);
- return result;
- }
-
- QJsonValue lookup(int handle, bool addRefs = true)
- {
- if (handle < 0)
- handle = -handle;
-
- if (addRefs)
- foreach (int ref, refsByHandle[handle])
- refsToInclude.append(lookup(ref, false));
- return refs[handle];
- }
-
- QJsonObject makeRef(int refId)
- {
- QJsonObject ref;
- ref[QLatin1String("ref")] = refId;
- return ref;
- }
-
- QJsonObject addFunctionRef(const QString &name)
- {
- const int refId = newRefId();
-
- QJsonObject func;
- func[QLatin1String("handle")] = refId;
- func[QLatin1String("type")] = QStringLiteral("function");
- func[QLatin1String("className")] = QStringLiteral("Function");
- func[QLatin1String("name")] = name;
- insertRef(func, refId);
-
- return makeRef(refId);
- }
-
- QJsonObject addScriptRef(const QString &name)
- {
- const int refId = newRefId();
-
- QJsonObject func;
- func[QLatin1String("handle")] = refId;
- func[QLatin1String("type")] = QStringLiteral("script");
- func[QLatin1String("name")] = name;
- insertRef(func, refId);
-
- return makeRef(refId);
- }
-
- QJsonObject addObjectRef(QJsonObject obj, bool anonymous)
- {
- int ref = newRefId();
-
- if (anonymous)
- ref = -ref;
- obj[QLatin1String("handle")] = ref;
- obj[QLatin1String("type")] = QStringLiteral("object");
- insertRef(obj, ref);
- QSet<int> used;
- qSwap(usedRefs, used);
- refsByHandle.insert(ref, used);
-
- return makeRef(ref);
- }
-
-protected:
- virtual void addUndefined(const QString &name)
- {
- QJsonObject o;
- addHandle(name, o, QStringLiteral("undefined"));
- }
-
- virtual void addNull(const QString &name)
- {
- QJsonObject o;
- addHandle(name, o, QStringLiteral("null"));
- }
-
- virtual void addBoolean(const QString &name, bool value)
- {
- QJsonObject o;
- o[QLatin1String("value")] = value;
- addHandle(name, o, QStringLiteral("boolean"));
- }
-
- virtual void addString(const QString &name, const QString &value)
- {
- QJsonObject o;
- o[QLatin1String("value")] = value;
- addHandle(name, o, QStringLiteral("string"));
- }
-
- virtual void addObject(const QString &name, const QV4::Value &value)
- {
- QV4::Scope scope(engine());
- QV4::ScopedObject obj(scope, value.as<QV4::Object>());
-
- int ref = cachedObjectRef(obj);
- if (ref != -1) {
- addNameRefPair(name, ref);
- } else {
- int ref = newRefId();
- cacheObjectRef(obj, ref);
-
- QJsonArray properties, *prev = &properties;
- QSet<int> used;
- qSwap(usedRefs, used);
- qSwap(destination, prev);
- collect(obj);
- qSwap(destination, prev);
- qSwap(usedRefs, used);
-
- QJsonObject o;
- o[QLatin1String("properties")] = properties;
- addHandle(name, o, QStringLiteral("object"), ref);
- refsByHandle.insert(ref, used);
- }
- }
-
- virtual void addInteger(const QString &name, int value)
- {
- QJsonObject o;
- o[QLatin1String("value")] = value;
- addHandle(name, o, QStringLiteral("number"));
- }
-
- virtual void addDouble(const QString &name, double value)
- {
- QJsonObject o;
- o[QLatin1String("value")] = value;
- addHandle(name, o, QStringLiteral("number"));
- }
-
-private:
- int addHandle(const QString &name, QJsonObject object, const QString &type, int suppliedRef = -1)
- {
- Q_ASSERT(destination);
-
- object[QLatin1String("type")] = type;
-
- QJsonDocument tmp;
- tmp.setObject(object);
- QByteArray key = tmp.toJson(QJsonDocument::Compact);
-
- int ref;
- if (suppliedRef == -1) {
- ref = refCache.value(key, -1);
- if (ref == -1) {
- ref = newRefId();
- object[QLatin1String("handle")] = ref;
- insertRef(object, ref);
- refCache.insert(key, ref);
- }
- } else {
- ref = suppliedRef;
- object[QLatin1String("handle")] = ref;
- insertRef(object, ref);
- refCache.insert(key, ref);
- }
-
- addNameRefPair(name, ref);
- return ref;
- }
-
- void addNameRefPair(const QString &name, int ref)
- {
- QJsonObject nameValuePair;
- nameValuePair[QLatin1String("name")] = name;
- if (isProperty()) {
- nameValuePair[QLatin1String("ref")] = ref;
- } else {
- QJsonObject refObj;
- refObj[QLatin1String("ref")] = ref;
- nameValuePair[QLatin1String("value")] = refObj;
- }
- destination->append(nameValuePair);
- usedRefs.insert(ref);
- }
-
- int newRefId()
- {
- int ref = refs.count();
- refs.insert(ref, QJsonValue());
- return ref;
- }
-
- void insertRef(const QJsonValue &value, int refId)
- {
- if (refId < 0)
- refId = -refId;
-
- refs.insert(refId, value);
- refsToInclude.append(value);
- }
-
- void cacheObjectRef(QV4::Object *obj, int ref)
- {
- objectRefs.insert(obj, ref);
- }
-
- int cachedObjectRef(QV4::Object *obj) const
- {
- return objectRefs.value(obj, -1);
- }
-
-private:
- QJsonArray refsToInclude;
- QHash<int, QJsonValue> refs;
- QHash<QByteArray, int> refCache;
- QJsonArray *destination;
- QSet<int> usedRefs;
- QHash<int, QSet<int> > refsByHandle;
- QHash<QV4::Object *, int> objectRefs;
-};
-
-int QV4DebugServiceImpl::debuggerIndex = 0;
-int QV4DebugServiceImpl::sequence = 0;
-
-class V8CommandHandler
-{
-public:
- V8CommandHandler(const QString &command)
- : cmd(command)
- {}
-
- virtual ~V8CommandHandler()
- {}
-
- QString command() const { return cmd; }
-
- void handle(const QJsonObject &request, QV4DebugServiceImpl *s)
- {
- TRACE_PROTOCOL(qDebug() << "handling command" << command() << "...");
-
- req = request;
- seq = req.value(QStringLiteral("seq"));
- debugService = s;
-
- handleRequest();
- if (!response.isEmpty()) {
- response[QLatin1String("type")] = QStringLiteral("response");
- debugService->send(response);
- }
-
- debugService = 0;
- seq = QJsonValue();
- req = QJsonObject();
- response = QJsonObject();
- }
-
- virtual void handleRequest() = 0;
-
-protected:
- void addCommand() { response.insert(QStringLiteral("command"), cmd); }
- void addRequestSequence() { response.insert(QStringLiteral("request_seq"), seq); }
- void addSuccess(bool success) { response.insert(QStringLiteral("success"), success); }
- void addBody(const QJsonObject &body)
- {
- response.insert(QStringLiteral("body"), body);
- }
-
- void addRunning()
- {
- response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
- }
-
- void addRefs()
- {
- response.insert(QStringLiteral("refs"), debugService->buildRefs());
- }
-
- void createErrorResponse(const QString &msg)
- {
- QJsonValue command = req.value(QStringLiteral("command"));
- response.insert(QStringLiteral("command"), command);
- addRequestSequence();
- addSuccess(false);
- addRunning();
- response.insert(QStringLiteral("message"), msg);
- }
-
- int requestSequenceNr() const
- { return seq.toInt(-1); }
-
-protected:
- QString cmd;
- QJsonObject req;
- QJsonValue seq;
- QV4DebugServiceImpl *debugService;
- QJsonObject response;
-};
-
-class UnknownV8CommandHandler: public V8CommandHandler
-{
-public:
- UnknownV8CommandHandler(): V8CommandHandler(QString()) {}
-
- virtual void handleRequest()
- {
- QString msg = QStringLiteral("unimplemented command \"");
- msg += req.value(QStringLiteral("command")).toString();
- msg += QStringLiteral("\"");
- createErrorResponse(msg);
- }
-};
-
-namespace {
-class V8VersionRequest: public V8CommandHandler
-{
-public:
- V8VersionRequest(): V8CommandHandler(QStringLiteral("version")) {}
-
- virtual void handleRequest()
- {
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- body.insert(QStringLiteral("V8Version"),
- QLatin1String("this is not V8, this is V4 in Qt " QT_VERSION_STR));
- addBody(body);
- }
-};
-
-class V8SetBreakPointRequest: public V8CommandHandler
-{
-public:
- V8SetBreakPointRequest(): V8CommandHandler(QStringLiteral("setbreakpoint")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject args = req.value(QStringLiteral("arguments")).toObject();
- if (args.isEmpty())
- return;
-
- QString type = args.value(QStringLiteral("type")).toString();
- if (type != QStringLiteral("scriptRegExp")) {
- createErrorResponse(QStringLiteral("breakpoint type \"%1\" is not implemented").arg(type));
- return;
- }
-
- QString fileName = args.value(QStringLiteral("target")).toString();
- if (fileName.isEmpty()) {
- createErrorResponse(QStringLiteral("breakpoint has no file name"));
- return;
- }
-
- int line = args.value(QStringLiteral("line")).toInt(-1);
- if (line < 0) {
- createErrorResponse(QStringLiteral("breakpoint has an invalid line number"));
- return;
- }
-
- bool enabled = args.value(QStringLiteral("enabled")).toBool(true);
- QString condition = args.value(QStringLiteral("condition")).toString();
-
- // set the break point:
- int id = debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- body.insert(QStringLiteral("type"), type);
- body.insert(QStringLiteral("breakpoint"), id);
- // It's undocumented, but V8 sends back an actual_locations array too. However, our
- // Debugger currently doesn't tell us when it resolved a breakpoint, so we'll leave them
- // pending until the breakpoint is hit for the first time.
- addBody(body);
- }
-};
-
-class V8ClearBreakPointRequest: public V8CommandHandler
-{
-public:
- V8ClearBreakPointRequest(): V8CommandHandler(QStringLiteral("clearbreakpoint")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject args = req.value(QStringLiteral("arguments")).toObject();
- if (args.isEmpty())
- return;
-
- int id = args.value(QStringLiteral("breakpoint")).toInt(-1);
- if (id < 0) {
- createErrorResponse(QStringLiteral("breakpoint has an invalid number"));
- return;
- }
-
- // remove the break point:
- debugService->debuggerAgent.removeBreakPoint(id);
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- body.insert(QStringLiteral("type"), QStringLiteral("scriptRegExp"));
- body.insert(QStringLiteral("breakpoint"), id);
- addBody(body);
- }
-};
-
-class V8BacktraceRequest: public V8CommandHandler
-{
-public:
- V8BacktraceRequest(): V8CommandHandler(QStringLiteral("backtrace")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
-
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- int fromFrame = arguments.value(QStringLiteral("fromFrame")).toInt(0);
- int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
- // no idea what the bottom property is for, so we'll ignore it.
-
- QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
-
- QJsonArray frameArray;
- QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
- for (int i = fromFrame; i < toFrame && i < frames.size(); ++i)
- frameArray.push_back(debugService->buildFrame(frames[i], i, debugger));
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- if (frameArray.isEmpty()) {
- body.insert(QStringLiteral("totalFrames"), 0);
- } else {
- body.insert(QStringLiteral("fromFrame"), fromFrame);
- body.insert(QStringLiteral("toFrame"), fromFrame + frameArray.size());
- body.insert(QStringLiteral("frames"), frameArray);
- }
- addBody(body);
- addRefs();
- }
-};
-
-class V8FrameRequest: public V8CommandHandler
-{
-public:
- V8FrameRequest(): V8CommandHandler(QStringLiteral("frame")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("number")).toInt(
- debugService->selectedFrame());
-
- QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
- if (frameNr < 0 || frameNr >= frames.size()) {
- createErrorResponse(QStringLiteral("frame command has invalid frame number"));
- return;
- }
-
- debugService->selectFrame(frameNr);
- QJsonObject frame = debugService->buildFrame(frames[frameNr], frameNr, debugger);
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(frame);
- addRefs();
- }
-};
-
-class V8ScopeRequest: public V8CommandHandler
-{
-public:
- V8ScopeRequest(): V8CommandHandler(QStringLiteral("scope")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("frameNumber")).toInt(
- debugService->selectedFrame());
- const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
-
- QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
- if (frameNr < 0 || frameNr >= frames.size()) {
- createErrorResponse(QStringLiteral("scope command has invalid frame number"));
- return;
- }
- if (scopeNr < 0) {
- createErrorResponse(QStringLiteral("scope command has invalid scope number"));
- return;
- }
-
- QJsonObject scope = debugService->buildScope(frameNr, scopeNr, debugger);
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(scope);
- addRefs();
- }
-};
-
-class V8LookupRequest: public V8CommandHandler
-{
-public:
- V8LookupRequest(): V8CommandHandler(QStringLiteral("lookup")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QJsonArray handles = arguments.value(QStringLiteral("handles")).toArray();
-
- QJsonObject body;
- foreach (const QJsonValue &handle, handles)
- body[QString::number(handle.toInt())] = debugService->lookup(handle.toInt());
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(body);
- addRefs();
- }
-};
-
-class V8ContinueRequest: public V8CommandHandler
-{
-public:
- V8ContinueRequest(): V8CommandHandler(QStringLiteral("continue")) {}
-
- virtual void handleRequest()
- {
- // decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
-
- QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
-
- if (arguments.empty()) {
- debugger->resume(QV4::Debugging::Debugger::FullThrottle);
- } else {
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QString stepAction = arguments.value(QStringLiteral("stepaction")).toString();
- const int stepcount = arguments.value(QStringLiteral("stepcount")).toInt(1);
- if (stepcount != 1)
- qWarning() << "Step count other than 1 is not supported.";
-
- if (stepAction == QStringLiteral("in")) {
- debugger->resume(QV4::Debugging::Debugger::StepIn);
- } else if (stepAction == QStringLiteral("out")) {
- debugger->resume(QV4::Debugging::Debugger::StepOut);
- } else if (stepAction == QStringLiteral("next")) {
- debugger->resume(QV4::Debugging::Debugger::StepOver);
- } else {
- createErrorResponse(QStringLiteral("continue command has invalid stepaction"));
- return;
- }
- }
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- }
-};
-
-class V8DisconnectRequest: public V8CommandHandler
-{
-public:
- V8DisconnectRequest(): V8CommandHandler(QStringLiteral("disconnect")) {}
-
- virtual void handleRequest()
- {
- debugService->debuggerAgent.removeAllBreakPoints();
- debugService->debuggerAgent.resumeAll();
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- }
-};
-
-class V8SetExceptionBreakRequest: public V8CommandHandler
-{
-public:
- V8SetExceptionBreakRequest(): V8CommandHandler(QStringLiteral("setexceptionbreak")) {}
-
- virtual void handleRequest()
- {
- bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
-
- //decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QString type = arguments.value(QStringLiteral("type")).toString();
- bool enabled = arguments.value(QStringLiteral("number")).toBool(!wasEnabled);
-
- if (type == QStringLiteral("all")) {
- // that's fine
- } else if (type == QStringLiteral("uncaught")) {
- createErrorResponse(QStringLiteral("breaking only on uncaught exceptions is not supported yet"));
- return;
- } else {
- createErrorResponse(QStringLiteral("invalid type for break on exception"));
- return;
- }
-
- // do it:
- debugService->debuggerAgent.setBreakOnThrow(enabled);
-
- QJsonObject body;
- body[QLatin1String("type")] = type;
- body[QLatin1String("enabled")] = debugService->debuggerAgent.breakOnThrow();
-
- // response:
- addBody(body);
- addRunning();
- addSuccess(true);
- addRequestSequence();
- addCommand();
- }
-};
-
-class V8ScriptsRequest: public V8CommandHandler
-{
-public:
- V8ScriptsRequest(): V8CommandHandler(QStringLiteral("scripts")) {}
-
- virtual void handleRequest()
- {
- //decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- int types = arguments.value(QStringLiteral("types")).toInt(-1);
- if (types < 0 || types > 7) {
- createErrorResponse(QStringLiteral("invalid types value in scripts command"));
- return;
- } else if (types != 4) {
- createErrorResponse(QStringLiteral("unsupported types value in scripts command"));
- return;
- }
-
- // do it:
- debugService->debuggerAgent.firstDebugger()->gatherSources(requestSequenceNr());
-
- // response will be send by
- }
-};
-
-// Request:
-// {
-// "seq": 4,
-// "type": "request",
-// "command": "evaluate",
-// "arguments": {
-// "expression": "a",
-// "frame": 0
-// }
-// }
-//
-// Response:
-// {
-// "body": {
-// "handle": 3,
-// "type": "number",
-// "value": 1
-// },
-// "command": "evaluate",
-// "refs": [],
-// "request_seq": 4,
-// "running": false,
-// "seq": 5,
-// "success": true,
-// "type": "response"
-// }
-//
-// The "value" key in "body" is the result of evaluating the expression in the request.
-class V8EvaluateRequest: public V8CommandHandler
-{
-public:
- V8EvaluateRequest(): V8CommandHandler(QStringLiteral("evaluate")) {}
-
- virtual void handleRequest()
- {
- //decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QString expression = arguments.value(QStringLiteral("expression")).toString();
- const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
-
- QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- Q_ASSERT(debugger->state() == QV4::Debugging::Debugger::Paused);
-
- VariableCollector *collector = debugService->collector();
- QJsonArray dest;
- collector->setDestination(&dest);
- debugger->evaluateExpression(frame, expression, collector);
-
- const int ref = dest.at(0).toObject().value(QStringLiteral("value")).toObject()
- .value(QStringLiteral("ref")).toInt();
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(collector->lookup(ref).toObject());
- addRefs();
- }
-};
-} // anonymous namespace
-
-void QV4DebugServiceImpl::addHandler(V8CommandHandler* handler)
-{
- handlers[handler->command()] = handler;
-}
-
-V8CommandHandler *QV4DebugServiceImpl::v8CommandHandler(const QString &command) const
-{
- V8CommandHandler *handler = handlers.value(command, 0);
- if (handler)
- return handler;
- else
- return unknownV8CommandHandler.data();
-}
-
-QV4DebugServiceImpl::QV4DebugServiceImpl(QObject *parent) :
- QQmlConfigurableDebugService<QV4DebugService>(1, parent),
- debuggerAgent(this), version(1), theSelectedFrame(0),
- unknownV8CommandHandler(new UnknownV8CommandHandler)
-{
- addHandler(new V8VersionRequest);
- addHandler(new V8SetBreakPointRequest);
- addHandler(new V8ClearBreakPointRequest);
- addHandler(new V8BacktraceRequest);
- addHandler(new V8FrameRequest);
- addHandler(new V8ScopeRequest);
- addHandler(new V8LookupRequest);
- addHandler(new V8ContinueRequest);
- addHandler(new V8DisconnectRequest);
- addHandler(new V8SetExceptionBreakRequest);
- addHandler(new V8ScriptsRequest);
- addHandler(new V8EvaluateRequest);
-}
-
-QV4DebugServiceImpl::~QV4DebugServiceImpl()
-{
- qDeleteAll(handlers);
-}
-
-QV4DebugServiceImpl *QV4DebugServiceImpl::instance()
-{
- return v4ServiceInstance();
-}
-
-void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
-{
- QMutexLocker lock(&m_configMutex);
- if (engine) {
- QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
- if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) {
- if (ee) {
- ee->enableDebugger();
- QV4::Debugging::Debugger *debugger = ee->debugger;
- debuggerMap.insert(debuggerIndex++, debugger);
- debuggerAgent.addDebugger(debugger);
- debuggerAgent.moveToThread(server->thread());
- moveToThread(server->thread());
- }
- }
- }
- QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeAdded(engine);
-}
-
-void QV4DebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine)
-{
- QMutexLocker lock(&m_configMutex);
- if (engine){
- const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
- if (ee) {
- QV4::Debugging::Debugger *debugger = ee->debugger;
- typedef QMap<int, QV4::Debugging::Debugger *>::const_iterator DebuggerMapIterator;
- const DebuggerMapIterator end = debuggerMap.constEnd();
- for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) {
- if (i.value() == debugger) {
- debuggerMap.remove(i.key());
- break;
- }
- }
- debuggerAgent.removeDebugger(debugger);
- }
- }
- QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeRemoved(engine);
-}
-
-void QV4DebugServiceImpl::signalEmitted(const QString &signal)
-{
- //This function is only called by QQmlBoundSignal
- //only if there is a slot connected to the signal. Hence, there
- //is no need for additional check.
-
- //Parse just the name and remove the class info
- //Normalize to Lower case.
- QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
-
- foreach (const QString &signal, breakOnSignals) {
- if (signal == signalName) {
- // TODO: pause debugger
- break;
- }
- }
-}
-
-void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
-{
- QMutexLocker lock(&m_configMutex);
-
- QQmlDebugStream ms(message);
- QByteArray header;
- ms >> header;
-
- TRACE_PROTOCOL(qDebug() << "received message with header" << header);
-
- if (header == "V8DEBUG") {
- QByteArray type;
- QByteArray payload;
- ms >> type >> payload;
- TRACE_PROTOCOL(qDebug() << "... type:" << type);
-
- if (type == V4_CONNECT) {
- emit messageToClient(name(), packMessage(type));
- stopWaiting();
- } else if (type == V4_PAUSE) {
- debuggerAgent.pauseAll();
- sendSomethingToSomebody(type);
- } else if (type == V4_BREAK_ON_SIGNAL) {
- QByteArray signal;
- bool enabled;
- ms >> signal >> enabled;
- //Normalize to lower case.
- QString signalName(QString::fromUtf8(signal).toLower());
- if (enabled)
- breakOnSignals.append(signalName);
- else
- breakOnSignals.removeOne(signalName);
- } else if (type == "v8request") {
- handleV8Request(payload);
- } else if (type == V4_DISCONNECT) {
- TRACE_PROTOCOL(qDebug() << "... payload:" << payload.constData());
- handleV8Request(payload);
- } else {
- sendSomethingToSomebody(type, 0);
- }
- }
-}
-
-void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNumber)
-{
- QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
- rs << QByteArray(type)
- << QByteArray::number(version) << QByteArray::number(magicNumber);
- emit messageToClient(name(), packMessage(type, response));
-}
-
-QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService)
- : debugService(debugService)
-{}
-
-QV4::Debugging::Debugger *QV4DebuggerAgent::firstDebugger() const
-{
- // Currently only 1 single engine is supported, so:
- if (m_debuggers.isEmpty())
- return 0;
- else
- return m_debuggers.first();
-}
-
-bool QV4DebuggerAgent::isRunning() const
-{
- // Currently only 1 single engine is supported, so:
- if (QV4::Debugging::Debugger *debugger = firstDebugger())
- return debugger->state() == QV4::Debugging::Debugger::Running;
- else
- return false;
-}
-
-void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::Debugger *debugger, QV4::Debugging::PauseReason reason)
-{
- Q_UNUSED(reason);
-
- debugService->clearHandles(debugger->engine());
-
- QJsonObject event, body, script;
- event.insert(QStringLiteral("type"), QStringLiteral("event"));
-
- switch (reason) {
- case QV4::Debugging::Step:
- case QV4::Debugging::PauseRequest:
- case QV4::Debugging::BreakPoint: {
- event.insert(QStringLiteral("event"), QStringLiteral("break"));
- QVector<QV4::StackFrame> frames = debugger->stackTrace(1);
- if (frames.isEmpty())
- break;
-
- const QV4::StackFrame &topFrame = frames.first();
- body.insert(QStringLiteral("invocationText"), topFrame.function);
- body.insert(QStringLiteral("sourceLine"), topFrame.line - 1);
- if (topFrame.column > 0)
- body.insert(QStringLiteral("sourceColumn"), topFrame.column);
- QJsonArray breakPoints;
- foreach (int breakPointId, breakPointIds(topFrame.source, topFrame.line))
- breakPoints.push_back(breakPointId);
- body.insert(QStringLiteral("breakpoints"), breakPoints);
- script.insert(QStringLiteral("name"), topFrame.source);
- } break;
- case QV4::Debugging::Throwing:
- // TODO: complete this!
- event.insert(QStringLiteral("event"), QStringLiteral("exception"));
- break;
- }
-
- if (!script.isEmpty())
- body.insert(QStringLiteral("script"), script);
- if (!body.isEmpty())
- event.insert(QStringLiteral("body"), body);
- debugService->send(event);
-}
-
-void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources, int requestSequenceNr)
-{
- QJsonArray body;
- foreach (const QString &source, sources) {
- QJsonObject src;
- src[QLatin1String("name")] = source;
- src[QLatin1String("scriptType")] = 4;
- body.append(src);
- }
-
- QJsonObject response;
- response[QLatin1String("success")] = true;
- response[QLatin1String("running")] = debugger->state() == QV4::Debugging::Debugger::Running;
- response[QLatin1String("body")] = body;
- response[QLatin1String("command")] = QStringLiteral("scripts");
- response[QLatin1String("request_seq")] = requestSequenceNr;
- response[QLatin1String("type")] = QStringLiteral("response");
- debugService->send(response);
-}
-
-void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
-{
- TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload.constData());
-
- QJsonDocument request = QJsonDocument::fromJson(payload);
- QJsonObject o = request.object();
- QJsonValue type = o.value(QStringLiteral("type"));
- if (type.toString() == QStringLiteral("request")) {
- QJsonValue command = o.value(QStringLiteral("command"));
- V8CommandHandler *h = v8CommandHandler(command.toString());
- if (h)
- h->handle(o, this);
- }
-}
-
-QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QByteArray &message)
-{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
- static const QByteArray cmd("V8DEBUG");
- rs << cmd << command << message;
- return reply;
-}
-
-void QV4DebugServiceImpl::send(QJsonObject v8Payload)
-{
- v8Payload[QLatin1String("seq")] = sequence++;
- QJsonDocument doc;
- doc.setObject(v8Payload);
-#ifdef NO_PROTOCOL_TRACING
- QByteArray responseData = doc.toJson(QJsonDocument::Compact);
-#else
- QByteArray responseData = doc.toJson(QJsonDocument::Indented);
-#endif
-
- TRACE_PROTOCOL(qDebug() << "sending response for:" << responseData.constData() << endl);
-
- emit messageToClient(name(), packMessage("v8message", responseData));
-}
-
-void QV4DebugServiceImpl::clearHandles(QV4::ExecutionEngine *engine)
-{
- theCollector.reset(new VariableCollector(engine));
-}
-
-QJsonObject QV4DebugServiceImpl::buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::Debugger *debugger)
-{
- QJsonObject frame;
- frame[QLatin1String("index")] = frameNr;
- frame[QLatin1String("debuggerFrame")] = false;
- frame[QLatin1String("func")] = theCollector->addFunctionRef(stackFrame.function);
- frame[QLatin1String("script")] = theCollector->addScriptRef(stackFrame.source);
- frame[QLatin1String("line")] = stackFrame.line - 1;
- if (stackFrame.column >= 0)
- frame[QLatin1String("column")] = stackFrame.column;
-
- QJsonArray properties;
- theCollector->setDestination(&properties);
- if (debugger->collectThisInContext(theCollector.data(), frameNr)) {
- QJsonObject obj;
- obj[QLatin1String("properties")] = properties;
- frame[QLatin1String("receiver")] = theCollector->addObjectRef(obj, false);
- }
-
- QJsonArray scopes;
- // Only type and index are used by Qt Creator, so we keep it easy:
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
- for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
- int type = encodeScopeType(scopeTypes[i]);
- if (type == -1)
- continue;
-
- QJsonObject scope;
- scope[QLatin1String("index")] = i;
- scope[QLatin1String("type")] = type;
- scopes.push_back(scope);
- }
- frame[QLatin1String("scopes")] = scopes;
-
- return frame;
-}
-
-int QV4DebugServiceImpl::encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType)
-{
- switch (scopeType) {
- case QV4::Heap::ExecutionContext::Type_GlobalContext:
- return 0;
- break;
- case QV4::Heap::ExecutionContext::Type_CatchContext:
- return 4;
- break;
- case QV4::Heap::ExecutionContext::Type_WithContext:
- return 2;
- break;
- case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
- case QV4::Heap::ExecutionContext::Type_CallContext:
- return 1;
- break;
- case QV4::Heap::ExecutionContext::Type_QmlContext:
- default:
- return -1;
- }
-}
-
-QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr,
- QV4::Debugging::Debugger *debugger)
-{
- QJsonObject scope;
-
- QJsonArray properties;
- theCollector->collectScope(&properties, debugger, frameNr, scopeNr);
-
- QJsonObject anonymous;
- anonymous[QLatin1String("properties")] = properties;
-
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
- scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]);
- scope[QLatin1String("index")] = scopeNr;
- scope[QLatin1String("frameIndex")] = frameNr;
- scope[QLatin1String("object")] = theCollector->addObjectRef(anonymous, true);
-
- return scope;
-}
-
-QJsonValue QV4DebugServiceImpl::lookup(int refId) const
-{
- return theCollector->lookup(refId);
-}
-
-QJsonArray QV4DebugServiceImpl::buildRefs()
-{
- return theCollector->retrieveRefsToInclude();
-}
-
-VariableCollector *QV4DebugServiceImpl::collector() const
-{
- return theCollector.data();
-}
-
-void QV4DebugServiceImpl::selectFrame(int frameNr)
-{
- theSelectedFrame = frameNr;
-}
-
-int QV4DebugServiceImpl::selectedFrame() const
-{
- return theSelectedFrame;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h
deleted file mode 100644
index fee0e0ac89..0000000000
--- a/src/qml/debugger/qv4debugservice_p.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4DEBUGSERVICE_P_H
-#define QV4DEBUGSERVICE_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 "qqmlconfigurabledebugservice_p.h"
-#include "qqmldebugserviceinterfaces_p.h"
-#include <private/qv4debugging_p.h>
-
-#include <QtCore/QJsonValue>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 { struct ExecutionEngine; }
-
-class QQmlEngine;
-class VariableCollector;
-class V8CommandHandler;
-class UnknownV8CommandHandler;
-class QV4DebugServiceImpl;
-
-class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
-{
- Q_OBJECT
-public:
- QV4DebuggerAgent(QV4DebugServiceImpl *debugService);
- QV4::Debugging::Debugger *firstDebugger() const;
- bool isRunning() const;
-
-public slots:
- virtual void debuggerPaused(QV4::Debugging::Debugger *debugger,
- QV4::Debugging::PauseReason reason);
- virtual void sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources,
- int requestSequenceNr);
-
-private:
- QV4DebugServiceImpl *debugService;
-};
-
-class QV4DebugServiceImpl : public QQmlConfigurableDebugService<QV4DebugService>
-{
- Q_OBJECT
-public:
- explicit QV4DebugServiceImpl(QObject *parent = 0);
- ~QV4DebugServiceImpl();
-
- static QV4DebugServiceImpl *instance();
- void engineAboutToBeAdded(QQmlEngine *engine);
- void engineAboutToBeRemoved(QQmlEngine *engine);
-
- void signalEmitted(const QString &signal);
- void send(QJsonObject v8Payload);
-
- QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::Debugger *debugger);
- QJsonArray buildRefs();
- QJsonValue lookup(int refId) const;
-
- QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::Debugger *debugger);
- int selectedFrame() const;
- void selectFrame(int frameNr);
-
- void clearHandles(QV4::ExecutionEngine *engine);
-
- VariableCollector *collector() const;
- QV4DebuggerAgent debuggerAgent;
-
-protected:
- void messageReceived(const QByteArray &);
- void sendSomethingToSomebody(const char *type, int magicNumber = 1);
-
-private:
- void handleV8Request(const QByteArray &payload);
- static QByteArray packMessage(const QByteArray &command,
- const QByteArray &message = QByteArray());
- void processCommand(const QByteArray &command, const QByteArray &data);
- V8CommandHandler *v8CommandHandler(const QString &command) const;
- int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
-
- QStringList breakOnSignals;
- QMap<int, QV4::Debugging::Debugger *> debuggerMap;
- static int debuggerIndex;
- static int sequence;
- const int version;
-
- QScopedPointer<VariableCollector> theCollector;
- int theSelectedFrame;
-
- void addHandler(V8CommandHandler* handler);
- QHash<QString, V8CommandHandler*> handlers;
- QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV4DEBUGSERVICE_P_H
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 10ae9f0e52..4d84cc82ae 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -23,7 +23,6 @@ SOURCES += \
$$PWD/qqmlvaluetype.cpp \
$$PWD/qqmlaccessors.cpp \
$$PWD/qqmlxmlhttprequest.cpp \
- $$PWD/qqmlwatcher.cpp \
$$PWD/qqmlcleanup.cpp \
$$PWD/qqmlpropertycache.cpp \
$$PWD/qqmlnotifier.cpp \
@@ -91,7 +90,6 @@ HEADERS += \
$$PWD/qqmlvaluetype_p.h \
$$PWD/qqmlaccessors_p.h \
$$PWD/qqmlxmlhttprequest_p.h \
- $$PWD/qqmlwatcher_p.h \
$$PWD/qqmlcleanup_p.h \
$$PWD/qqmlpropertycache_p.h \
$$PWD/qqmlnotifier_p.h \
diff --git a/src/qml/qml/qqmlwatcher.cpp b/src/qml/qml/qqmlwatcher.cpp
deleted file mode 100644
index 9726b6f3b9..0000000000
--- a/src/qml/qml/qqmlwatcher.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlwatcher_p.h"
-
-#include "qqmlexpression.h"
-#include "qqmlcontext.h"
-#include "qqml.h"
-
-#include <private/qqmldebugservice_p.h>
-#include "qqmlproperty_p.h"
-#include "qqmlvaluetype_p.h"
-
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlWatchProxy : public QObject
-{
- Q_OBJECT
-public:
- QQmlWatchProxy(int id,
- QObject *object,
- int debugId,
- const QMetaProperty &prop,
- QQmlWatcher *parent = 0);
-
- QQmlWatchProxy(int id,
- QQmlExpression *exp,
- int debugId,
- QQmlWatcher *parent = 0);
-
-public slots:
- void notifyValueChanged();
-
-private:
- friend class QQmlWatcher;
- int m_id;
- QQmlWatcher *m_watch;
- QObject *m_object;
- int m_debugId;
- QMetaProperty m_property;
-
- QQmlExpression *m_expr;
-};
-
-QQmlWatchProxy::QQmlWatchProxy(int id,
- QQmlExpression *exp,
- int debugId,
- QQmlWatcher *parent)
-: QObject(parent), m_id(id), m_watch(parent), m_object(0), m_debugId(debugId), m_expr(exp)
-{
- QObject::connect(m_expr, SIGNAL(valueChanged()), this, SLOT(notifyValueChanged()));
-}
-
-QQmlWatchProxy::QQmlWatchProxy(int id,
- QObject *object,
- int debugId,
- const QMetaProperty &prop,
- QQmlWatcher *parent)
-: QObject(parent), m_id(id), m_watch(parent), m_object(object), m_debugId(debugId), m_property(prop), m_expr(0)
-{
- static int refreshIdx = -1;
- if(refreshIdx == -1)
- refreshIdx = QQmlWatchProxy::staticMetaObject.indexOfMethod("notifyValueChanged()");
-
- if (prop.hasNotifySignal())
- QQmlPropertyPrivate::connect(m_object, prop.notifySignalIndex(), this, refreshIdx);
-}
-
-void QQmlWatchProxy::notifyValueChanged()
-{
- QVariant v;
- if (m_expr)
- v = m_expr->evaluate();
- else if (QQmlValueTypeFactory::isValueType(m_property.userType()))
- v = m_property.read(m_object);
-
- emit m_watch->propertyChanged(m_id, m_debugId, m_property, v);
-}
-
-
-QQmlWatcher::QQmlWatcher(QObject *parent)
- : QObject(parent)
-{
-}
-
-bool QQmlWatcher::addWatch(int id, quint32 debugId)
-{
- QObject *object = QQmlDebugService::objectForId(debugId);
- if (object) {
- int propCount = object->metaObject()->propertyCount();
- for (int ii=0; ii<propCount; ii++)
- addPropertyWatch(id, object, debugId, object->metaObject()->property(ii));
- return true;
- }
- return false;
-}
-
-bool QQmlWatcher::addWatch(int id, quint32 debugId, const QByteArray &property)
-{
- QObject *object = QQmlDebugService::objectForId(debugId);
- if (object) {
- int index = object->metaObject()->indexOfProperty(property.constData());
- if (index >= 0) {
- addPropertyWatch(id, object, debugId, object->metaObject()->property(index));
- return true;
- }
- }
- return false;
-}
-
-bool QQmlWatcher::addWatch(int id, quint32 objectId, const QString &expr)
-{
- QObject *object = QQmlDebugService::objectForId(objectId);
- QQmlContext *context = qmlContext(object);
- if (context) {
- QQmlExpression *exprObj = new QQmlExpression(context, object, expr);
- exprObj->setNotifyOnValueChanged(true);
- QQmlWatchProxy *proxy = new QQmlWatchProxy(id, exprObj, objectId, this);
- exprObj->setParent(proxy);
- m_proxies[id].append(proxy);
- proxy->notifyValueChanged();
- return true;
- }
- return false;
-}
-
-bool QQmlWatcher::removeWatch(int id)
-{
- if (!m_proxies.contains(id))
- return false;
-
- QList<QPointer<QQmlWatchProxy> > proxies = m_proxies.take(id);
- qDeleteAll(proxies);
- return true;
-}
-
-void QQmlWatcher::addPropertyWatch(int id, QObject *object, quint32 debugId, const QMetaProperty &property)
-{
- QQmlWatchProxy *proxy = new QQmlWatchProxy(id, object, debugId, property, this);
- m_proxies[id].append(proxy);
-
- proxy->notifyValueChanged();
-}
-
-QT_END_NAMESPACE
-
-#include <qqmlwatcher.moc>
diff --git a/src/qml/qml/qqmlwatcher_p.h b/src/qml/qml/qqmlwatcher_p.h
deleted file mode 100644
index a7bb3c3418..0000000000
--- a/src/qml/qml/qqmlwatcher_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLWATCHER_P_H
-#define QQMLWATCHER_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/qobject.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qset.h>
-#include <QtCore/qpointer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlWatchProxy;
-class QQmlExpression;
-class QQmlContext;
-class QMetaProperty;
-
-class QQmlWatcher : public QObject
-{
- Q_OBJECT
-public:
- QQmlWatcher(QObject * = 0);
-
- bool addWatch(int id, quint32 objectId);
- bool addWatch(int id, quint32 objectId, const QByteArray &property);
- bool addWatch(int id, quint32 objectId, const QString &expr);
-
- bool removeWatch(int id);
-
-Q_SIGNALS:
- void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
-
-private:
- friend class QQmlWatchProxy;
- void addPropertyWatch(int id, QObject *object, quint32 objectId, const QMetaProperty &property);
-
- QHash<int, QList<QPointer<QQmlWatchProxy> > > m_proxies;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLWATCHER_P_H