aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-07-16 14:12:04 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-07-31 11:31:09 +0000
commite061150cc54255726b8cda8cc928d3ed03ea8093 (patch)
treeea43c36b901831f3037b2fc5f9d141b868493ccd /src/qml
parent0768d0dff9b2dc647da480bd73f5f25c84fdb427 (diff)
Remove pimpl from all classes derived from QQmlDebugService
There is no point in using pimpl for purely internal classes, especially when we move them to their own plugins. Change-Id: I2ee8bf2ded2242d91bab89f589a131dc3bcc9a55 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/debugger.pri2
-rw-r--r--src/qml/debugger/qdebugmessageservice.cpp45
-rw-r--r--src/qml/debugger/qdebugmessageservice_p.h6
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice.cpp39
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h16
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p_p.h71
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp1
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp32
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h3
-rw-r--r--src/qml/debugger/qqmldebugservice_p_p.h70
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp22
-rw-r--r--src/qml/debugger/qv4debugservice.cpp501
-rw-r--r--src/qml/debugger/qv4debugservice_p.h63
13 files changed, 343 insertions, 528 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index cbb1646ff6..b3e3b3fc90 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -20,7 +20,6 @@ HEADERS += \
$$PWD/qqmldebugconnector_p.h \
$$PWD/qqmldebugpluginmanager_p.h \
$$PWD/qqmldebugservice_p.h \
- $$PWD/qqmldebugservice_p_p.h \
$$PWD/qqmlprofilerservice_p.h \
$$PWD/qqmldebugserver_p.h \
$$PWD/qqmldebugserverconnection_p.h \
@@ -32,7 +31,6 @@ HEADERS += \
$$PWD/qdebugmessageservice_p.h \
$$PWD/qv4debugservice_p.h \
$$PWD/qqmlconfigurabledebugservice_p.h \
- $$PWD/qqmlconfigurabledebugservice_p_p.h \
$$PWD/qqmlenginecontrolservice_p.h \
$$PWD/qqmlprofilerdefinitions_p.h \
$$PWD/qqmlabstractprofileradapter_p.h \
diff --git a/src/qml/debugger/qdebugmessageservice.cpp b/src/qml/debugger/qdebugmessageservice.cpp
index 88ef9eb96c..3e5cec54b1 100644
--- a/src/qml/debugger/qdebugmessageservice.cpp
+++ b/src/qml/debugger/qdebugmessageservice.cpp
@@ -32,10 +32,8 @@
****************************************************************************/
#include "qdebugmessageservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include <QDataStream>
-#include <QMutex>
QT_BEGIN_NAMESPACE
@@ -47,29 +45,15 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
QDebugMessageService::instance()->sendDebugMessage(type, ctxt, buf);
}
-class QDebugMessageServicePrivate : public QQmlDebugServicePrivate
-{
-public:
- QDebugMessageServicePrivate() : QQmlDebugServicePrivate(QStringLiteral("DebugMessages"), 2),
- oldMsgHandler(0), prevState(QQmlDebugService::NotConnected)
- {
- }
-
- QtMessageHandler oldMsgHandler;
- QQmlDebugService::State prevState;
- QMutex initMutex;
-};
-
QDebugMessageService::QDebugMessageService(QObject *parent) :
- QQmlDebugService(*(new QDebugMessageServicePrivate), parent)
+ QQmlDebugService(QStringLiteral("DebugMessages"), 2, parent), oldMsgHandler(0),
+ prevState(QQmlDebugService::NotConnected)
{
- Q_D(QDebugMessageService);
-
// don't execute stateChanged() in parallel
- QMutexLocker lock(&d->initMutex);
+ QMutexLocker lock(&initMutex);
if (state() == Enabled) {
- d->oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
- d->prevState = Enabled;
+ oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
+ prevState = Enabled;
}
}
@@ -82,8 +66,6 @@ void QDebugMessageService::sendDebugMessage(QtMsgType type,
const QMessageLogContext &ctxt,
const QString &buf)
{
- Q_D(QDebugMessageService);
-
//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.
@@ -94,26 +76,25 @@ void QDebugMessageService::sendDebugMessage(QtMsgType type,
ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8();
emit messageToClient(name(), message);
- if (d->oldMsgHandler)
- (*d->oldMsgHandler)(type, ctxt, buf);
+ if (oldMsgHandler)
+ (*oldMsgHandler)(type, ctxt, buf);
}
void QDebugMessageService::stateChanged(State state)
{
- Q_D(QDebugMessageService);
- QMutexLocker lock(&d->initMutex);
+ QMutexLocker lock(&initMutex);
- if (state != Enabled && d->prevState == Enabled) {
- QtMessageHandler handler = qInstallMessageHandler(d->oldMsgHandler);
+ 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 && d->prevState != Enabled) {
- d->oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
+ } else if (state == Enabled && prevState != Enabled) {
+ oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
}
- d->prevState = state;
+ prevState = state;
}
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qdebugmessageservice_p.h b/src/qml/debugger/qdebugmessageservice_p.h
index 694cd0e64c..55e92d437f 100644
--- a/src/qml/debugger/qdebugmessageservice_p.h
+++ b/src/qml/debugger/qdebugmessageservice_p.h
@@ -48,6 +48,7 @@
#include "qqmldebugservice_p.h"
#include <QtCore/qlogging.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -68,8 +69,9 @@ protected:
void stateChanged(State);
private:
- Q_DISABLE_COPY(QDebugMessageService)
- Q_DECLARE_PRIVATE(QDebugMessageService)
+ QtMessageHandler oldMsgHandler;
+ QQmlDebugService::State prevState;
+ QMutex initMutex;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice.cpp b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
index 9382cea42e..679fa04abe 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice.cpp
+++ b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
@@ -32,48 +32,32 @@
****************************************************************************/
#include "qqmlconfigurabledebugservice_p.h"
-#include "qqmlconfigurabledebugservice_p_p.h"
#include "qqmldebugconnector_p.h"
QT_BEGIN_NAMESPACE
QQmlConfigurableDebugService::QQmlConfigurableDebugService(const QString &name, float version,
QObject *parent) :
- QQmlDebugService((*new QQmlConfigurableDebugServicePrivate(name, version)), parent)
+ QQmlDebugService(name, version, parent), m_configMutex(QMutex::Recursive)
{
init();
}
-QQmlConfigurableDebugService::QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd,
- QObject *parent) :
- QQmlDebugService(dd, parent)
-{
- init();
-}
-
-QMutex *QQmlConfigurableDebugService::configMutex()
-{
- Q_D(QQmlConfigurableDebugService);
- return &d->configMutex;
-}
-
void QQmlConfigurableDebugService::init()
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
+ QMutexLocker lock(&m_configMutex);
// If we're not enabled or not blocking, don't wait for configuration
- d->waitingForConfiguration = (state() == Enabled &&
- QQmlDebugConnector::instance()->blockingMode());
+ m_waitingForConfiguration = (state() == Enabled &&
+ QQmlDebugConnector::instance()->blockingMode());
}
void QQmlConfigurableDebugService::stopWaiting()
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
- d->waitingForConfiguration = false;
- foreach (QQmlEngine *engine, d->waitingEngines)
+ QMutexLocker lock(&m_configMutex);
+ m_waitingForConfiguration = false;
+ foreach (QQmlEngine *engine, m_waitingEngines)
emit attachedToEngine(engine);
- d->waitingEngines.clear();
+ m_waitingEngines.clear();
}
void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState)
@@ -86,10 +70,9 @@ void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState
void QQmlConfigurableDebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
- if (d->waitingForConfiguration)
- d->waitingEngines.append(engine);
+ QMutexLocker lock(&m_configMutex);
+ if (m_waitingForConfiguration)
+ m_waitingEngines.append(engine);
else
emit attachedToEngine(engine);
}
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index c7afcb94dd..28f0f4dfe2 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -47,31 +47,25 @@
//
#include "qqmldebugservice_p.h"
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
-class QMutex;
-class QQmlConfigurableDebugServicePrivate;
class QQmlConfigurableDebugService : public QQmlDebugService
{
Q_OBJECT
-public:
- QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0);
-
protected:
- QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd, QObject *parent = 0);
+ QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0);
- QMutex *configMutex();
void stopWaiting();
void init();
void stateChanged(State);
void engineAboutToBeAdded(QQmlEngine *);
- virtual ~QQmlConfigurableDebugService() {}
-private:
- Q_DISABLE_COPY(QQmlConfigurableDebugService)
- Q_DECLARE_PRIVATE(QQmlConfigurableDebugService)
+ QMutex m_configMutex;
+ QList<QQmlEngine *> m_waitingEngines;
+ bool m_waitingForConfiguration;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
deleted file mode 100644
index fcdefe3954..0000000000
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
+++ /dev/null
@@ -1,71 +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 QQMLCONFIGURABLEDEBUGSERVICE_P_H
-#define QQMLCONFIGURABLEDEBUGSERVICE_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 "qqmldebugservice_p_p.h"
-
-#include <QMutex>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-
-class QQmlConfigurableDebugServicePrivate : public QQmlDebugServicePrivate
-{
- Q_DECLARE_PUBLIC(QQmlConfigurableDebugService)
-public:
- QQmlConfigurableDebugServicePrivate(const QString &name, float version) :
- QQmlDebugServicePrivate(name, version), configMutex(QMutex::Recursive) {}
-
- QMutex configMutex;
- QList<QQmlEngine *> waitingEngines;
- bool waitingForConfiguration;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLCONFIGURABLEDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp
index a2cb8fd5a1..711550efce 100644
--- a/src/qml/debugger/qqmldebugserver.cpp
+++ b/src/qml/debugger/qqmldebugserver.cpp
@@ -34,7 +34,6 @@
#include "qqmldebugserver_p.h"
#include "qqmldebugserverconnection_p.h"
#include "qqmldebugservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index edebf7a8cb..3a69799da8 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qqmldebugservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include "qqmldebugconnector_p.h"
#include <private/qqmldata_p.h>
#include <private/qqmlcontext_p.h>
@@ -43,6 +42,19 @@
QT_BEGIN_NAMESPACE
+class QQmlDebugServer;
+
+class QQmlDebugServicePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlDebugService)
+public:
+ QQmlDebugServicePrivate(const QString &name, float version);
+
+ const QString name;
+ const float version;
+ QQmlDebugService::State state;
+};
+
QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float version) :
name(name), version(version), state(QQmlDebugService::NotConnected)
{
@@ -51,33 +63,17 @@ QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float vers
QQmlDebugService::QQmlDebugService(const QString &name, float version, QObject *parent)
: QObject(*(new QQmlDebugServicePrivate(name, version)), parent)
{
- registerService();
-}
-
-QQmlDebugService::QQmlDebugService(QQmlDebugServicePrivate &dd, QObject *parent)
- : QObject(dd, parent)
-{
- registerService();
-}
-
-/**
- Registers the service. This should be called in the constructor of the inherited class. From
- then on the service might get asynchronous calls to messageReceived().
- */
-QQmlDebugService::State QQmlDebugService::registerService()
-{
Q_D(QQmlDebugService);
QQmlDebugConnector *server = QQmlDebugConnector::instance();
if (!server)
- return NotConnected;
+ return;
if (server->service(d->name)) {
qWarning() << "QQmlDebugService: Conflicting plugin name" << d->name;
} else {
server->addService(this);
}
- return state();
}
QQmlDebugService::~QQmlDebugService()
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 311ce3e355..3d692133cc 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -87,9 +87,6 @@ public:
protected:
explicit QQmlDebugService(const QString &, float version, QObject *parent = 0);
- QQmlDebugService(QQmlDebugServicePrivate &dd, QObject *parent = 0);
-
- State registerService();
signals:
void attachedToEngine(QQmlEngine *);
diff --git a/src/qml/debugger/qqmldebugservice_p_p.h b/src/qml/debugger/qqmldebugservice_p_p.h
deleted file mode 100644
index e1e93e5e0c..0000000000
--- a/src/qml/debugger/qqmldebugservice_p_p.h
+++ /dev/null
@@ -1,70 +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 QQMLDEBUGSERVICE_P_H
-#define QQMLDEBUGSERVICE_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/qglobal.h>
-#include <private/qobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlDebugServer;
-
-class QQmlDebugServicePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQmlDebugService)
-public:
- QQmlDebugServicePrivate(const QString &name, float version);
-
- const QString name;
- const float version;
- QQmlDebugService::State state;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index 62eae0ddd8..dfd9a0cd3b 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -63,7 +63,7 @@ QQmlProfilerService::~QQmlProfilerService()
void QQmlProfilerService::dataReady(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
bool dataComplete = true;
for (QMultiMap<qint64, QQmlAbstractProfilerAdapter *>::iterator i(m_startTimes.begin()); i != m_startTimes.end();) {
if (i.value() == profiler) {
@@ -104,7 +104,7 @@ void QQmlProfilerService::engineAboutToBeAdded(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine));
QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle()));
addEngineProfiler(qmlAdapter, engine);
@@ -118,7 +118,7 @@ void QQmlProfilerService::engineAdded(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine))
profiler->stopWaiting();
}
@@ -128,7 +128,7 @@ void QQmlProfilerService::engineAboutToBeRemoved(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
bool isRunning = false;
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
if (profiler->isRunning())
@@ -148,7 +148,7 @@ void QQmlProfilerService::engineRemoved(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
removeProfilerFromStartTimes(profiler);
delete profiler;
@@ -165,7 +165,7 @@ void QQmlProfilerService::addEngineProfiler(QQmlAbstractProfilerAdapter *profile
void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
profiler->synchronize(m_timer);
m_globalProfilers.append(profiler);
// Global profiler, not connected to a specific engine.
@@ -181,7 +181,7 @@ void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profile
void QQmlProfilerService::removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
removeProfilerFromStartTimes(profiler);
m_globalProfilers.removeOne(profiler);
delete profiler;
@@ -208,7 +208,7 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile
*/
void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QByteArray message;
QQmlDebugStream d(&message, QIODevice::WriteOnly);
@@ -257,7 +257,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features)
*/
void QQmlProfilerService::stopProfiling(QQmlEngine *engine)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QList<QQmlAbstractProfilerAdapter *> stopping;
QList<QQmlAbstractProfilerAdapter *> reporting;
@@ -339,7 +339,7 @@ void QQmlProfilerService::sendMessages()
void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
if (state() == newState)
return;
@@ -353,7 +353,7 @@ void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState
void QQmlProfilerService::messageReceived(const QByteArray &message)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QByteArray rwData = message;
QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
index 81d4c7b70a..19c06bffeb 100644
--- a/src/qml/debugger/qv4debugservice.cpp
+++ b/src/qml/debugger/qv4debugservice.cpp
@@ -32,9 +32,7 @@
****************************************************************************/
#include "qv4debugservice_p.h"
-#include "qqmlconfigurabledebugservice_p_p.h"
#include "qqmlengine.h"
-#include "qv4debugging_p.h"
#include "qv4engine_p.h"
#include "qv4function_p.h"
#include "qqmldebugconnector_p.h"
@@ -44,7 +42,6 @@
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
-#include <QtCore/QJsonValue>
const char *const V4_CONNECT = "connect";
const char *const V4_DISCONNECT = "disconnect";
@@ -63,41 +60,6 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QV4DebugService, v4ServiceInstance)
-class QV4DebugServicePrivate;
-
-class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
-{
-public:
- QV4DebuggerAgent(QV4DebugServicePrivate *debugServicePrivate)
- : debugServicePrivate(debugServicePrivate)
- {}
-
- QV4::Debugging::Debugger *firstDebugger() const
- {
- // Currently only 1 single engine is supported, so:
- if (m_debuggers.isEmpty())
- return 0;
- else
- return m_debuggers.first();
- }
-
- bool 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;
- }
-
-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:
- QV4DebugServicePrivate *debugServicePrivate;
-};
-
class V8CommandHandler;
class UnknownV8CommandHandler;
@@ -343,164 +305,8 @@ private:
QHash<QV4::Object *, int> objectRefs;
};
-class QV4DebugServicePrivate : public QQmlConfigurableDebugServicePrivate
-{
- Q_DECLARE_PUBLIC(QV4DebugService)
-
-public:
- QV4DebugServicePrivate();
- ~QV4DebugServicePrivate() { qDeleteAll(handlers); }
-
- static QByteArray packMessage(const QByteArray &command, const QByteArray &message = QByteArray())
- {
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
- static const QByteArray cmd("V8DEBUG");
- rs << cmd << command << message;
- return reply;
- }
-
- void 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 q_func()->messageToClient(name, packMessage("v8message", responseData));
- }
-
- void processCommand(const QByteArray &command, const QByteArray &data);
-
- QV4DebuggerAgent debuggerAgent;
-
- QStringList breakOnSignals;
- QMap<int, QV4::Debugging::Debugger *> debuggerMap;
- static int debuggerIndex;
- static int sequence;
- const int version;
-
- V8CommandHandler *v8CommandHandler(const QString &command) const;
-
- void clearHandles(QV4::ExecutionEngine *engine)
- {
- theCollector.reset(new VariableCollector(engine));
- }
-
- QJsonObject 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 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 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 lookup(int refId) const { return theCollector->lookup(refId); }
-
- QJsonArray buildRefs()
- {
- return theCollector->retrieveRefsToInclude();
- }
-
- VariableCollector *collector() const
- {
- return theCollector.data();
- }
-
- void selectFrame(int frameNr)
- { theSelectedFrame = frameNr; }
-
- int selectedFrame() const
- { return theSelectedFrame; }
-
-private:
- QScopedPointer<VariableCollector> theCollector;
- int theSelectedFrame;
-
- void addHandler(V8CommandHandler* handler);
- QHash<QString, V8CommandHandler*> handlers;
- QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler;
-};
-
-int QV4DebugServicePrivate::debuggerIndex = 0;
-int QV4DebugServicePrivate::sequence = 0;
+int QV4DebugService::debuggerIndex = 0;
+int QV4DebugService::sequence = 0;
class V8CommandHandler
{
@@ -514,22 +320,20 @@ public:
QString command() const { return cmd; }
- void handle(const QJsonObject &request, QQmlDebugService *s, QV4DebugServicePrivate *p)
+ void handle(const QJsonObject &request, QV4DebugService *s)
{
TRACE_PROTOCOL(qDebug() << "handling command" << command() << "...");
req = request;
seq = req.value(QStringLiteral("seq"));
debugService = s;
- debugServicePrivate = p;
handleRequest();
if (!response.isEmpty()) {
response[QLatin1String("type")] = QStringLiteral("response");
- debugServicePrivate->send(response);
+ debugService->send(response);
}
- debugServicePrivate = 0;
debugService = 0;
seq = QJsonValue();
req = QJsonObject();
@@ -549,12 +353,12 @@ protected:
void addRunning()
{
- response.insert(QStringLiteral("running"), debugServicePrivate->debuggerAgent.isRunning());
+ response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
}
void addRefs()
{
- response.insert(QStringLiteral("refs"), debugServicePrivate->buildRefs());
+ response.insert(QStringLiteral("refs"), debugService->buildRefs());
}
void createErrorResponse(const QString &msg)
@@ -574,8 +378,7 @@ protected:
QString cmd;
QJsonObject req;
QJsonValue seq;
- QQmlDebugService *debugService;
- QV4DebugServicePrivate *debugServicePrivate;
+ QV4DebugService *debugService;
QJsonObject response;
};
@@ -646,7 +449,7 @@ public:
QString condition = args.value(QStringLiteral("condition")).toString();
// set the break point:
- int id = debugServicePrivate->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
+ int id = debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
// response:
addCommand();
@@ -682,7 +485,7 @@ public:
}
// remove the break point:
- debugServicePrivate->debuggerAgent.removeBreakPoint(id);
+ debugService->debuggerAgent.removeBreakPoint(id);
// response:
addCommand();
@@ -710,12 +513,12 @@ public:
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 = debugServicePrivate->debuggerAgent.firstDebugger();
+ 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(debugServicePrivate->buildFrame(frames[i], i, debugger));
+ frameArray.push_back(debugService->buildFrame(frames[i], i, debugger));
// response:
addCommand();
@@ -744,17 +547,18 @@ public:
{
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("number")).toInt(debugServicePrivate->selectedFrame());
+ const int frameNr = arguments.value(QStringLiteral("number")).toInt(
+ debugService->selectedFrame());
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ 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;
}
- debugServicePrivate->selectFrame(frameNr);
- QJsonObject frame = debugServicePrivate->buildFrame(frames[frameNr], frameNr, debugger);
+ debugService->selectFrame(frameNr);
+ QJsonObject frame = debugService->buildFrame(frames[frameNr], frameNr, debugger);
// response:
addCommand();
@@ -775,10 +579,11 @@ public:
{
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("frameNumber")).toInt(debugServicePrivate->selectedFrame());
+ const int frameNr = arguments.value(QStringLiteral("frameNumber")).toInt(
+ debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ 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"));
@@ -789,7 +594,7 @@ public:
return;
}
- QJsonObject scope = debugServicePrivate->buildScope(frameNr, scopeNr, debugger);
+ QJsonObject scope = debugService->buildScope(frameNr, scopeNr, debugger);
// response:
addCommand();
@@ -814,7 +619,7 @@ public:
QJsonObject body;
foreach (const QJsonValue &handle, handles)
- body[QString::number(handle.toInt())] = debugServicePrivate->lookup(handle.toInt());
+ body[QString::number(handle.toInt())] = debugService->lookup(handle.toInt());
// response:
addCommand();
@@ -836,7 +641,7 @@ public:
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
if (arguments.empty()) {
debugger->resume(QV4::Debugging::Debugger::FullThrottle);
@@ -874,8 +679,8 @@ public:
virtual void handleRequest()
{
- debugServicePrivate->debuggerAgent.removeAllBreakPoints();
- debugServicePrivate->debuggerAgent.resumeAll();
+ debugService->debuggerAgent.removeAllBreakPoints();
+ debugService->debuggerAgent.resumeAll();
// response:
addCommand();
@@ -892,7 +697,7 @@ public:
virtual void handleRequest()
{
- bool wasEnabled = debugServicePrivate->debuggerAgent.breakOnThrow();
+ bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
//decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
@@ -910,11 +715,11 @@ public:
}
// do it:
- debugServicePrivate->debuggerAgent.setBreakOnThrow(enabled);
+ debugService->debuggerAgent.setBreakOnThrow(enabled);
QJsonObject body;
body[QLatin1String("type")] = type;
- body[QLatin1String("enabled")] = debugServicePrivate->debuggerAgent.breakOnThrow();
+ body[QLatin1String("enabled")] = debugService->debuggerAgent.breakOnThrow();
// response:
addBody(body);
@@ -944,7 +749,7 @@ public:
}
// do it:
- debugServicePrivate->debuggerAgent.firstDebugger()->gatherSources(requestSequenceNr());
+ debugService->debuggerAgent.firstDebugger()->gatherSources(requestSequenceNr());
// response will be send by
}
@@ -990,10 +795,10 @@ public:
QString expression = arguments.value(QStringLiteral("expression")).toString();
const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
Q_ASSERT(debugger->state() == QV4::Debugging::Debugger::Paused);
- VariableCollector *collector = debugServicePrivate->collector();
+ VariableCollector *collector = debugService->collector();
QJsonArray dest;
collector->setDestination(&dest);
debugger->evaluateExpression(frame, expression, collector);
@@ -1012,8 +817,22 @@ public:
};
} // anonymous namespace
-QV4DebugServicePrivate::QV4DebugServicePrivate() :
- QQmlConfigurableDebugServicePrivate(QStringLiteral("V8Debugger"), 1), debuggerAgent(this),
+void QV4DebugService::addHandler(V8CommandHandler* handler)
+{
+ handlers[handler->command()] = handler;
+}
+
+V8CommandHandler *QV4DebugService::v8CommandHandler(const QString &command) const
+{
+ V8CommandHandler *handler = handlers.value(command, 0);
+ if (handler)
+ return handler;
+ else
+ return unknownV8CommandHandler.data();
+}
+
+QV4DebugService::QV4DebugService(QObject *parent) :
+ QQmlConfigurableDebugService(QStringLiteral("V8Debugger"), 1, parent), debuggerAgent(this),
version(1), theSelectedFrame(0), unknownV8CommandHandler(new UnknownV8CommandHandler)
{
addHandler(new V8VersionRequest);
@@ -1030,26 +849,9 @@ QV4DebugServicePrivate::QV4DebugServicePrivate() :
addHandler(new V8EvaluateRequest);
}
-void QV4DebugServicePrivate::addHandler(V8CommandHandler* handler)
-{
- handlers[handler->command()] = handler;
-}
-
-V8CommandHandler *QV4DebugServicePrivate::v8CommandHandler(const QString &command) const
-{
- V8CommandHandler *handler = handlers.value(command, 0);
- if (handler)
- return handler;
- else
- return unknownV8CommandHandler.data();
-}
-
-QV4DebugService::QV4DebugService(QObject *parent)
- : QQmlConfigurableDebugService(*(new QV4DebugServicePrivate()), parent)
-{}
-
QV4DebugService::~QV4DebugService()
{
+ qDeleteAll(handlers);
}
QV4DebugService *QV4DebugService::instance()
@@ -1059,17 +861,16 @@ QV4DebugService *QV4DebugService::instance()
void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ 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;
- d->debuggerMap.insert(d->debuggerIndex++, debugger);
- d->debuggerAgent.addDebugger(debugger);
- d->debuggerAgent.moveToThread(server->thread());
+ debuggerMap.insert(debuggerIndex++, debugger);
+ debuggerAgent.addDebugger(debugger);
+ debuggerAgent.moveToThread(server->thread());
moveToThread(server->thread());
}
}
@@ -1079,21 +880,20 @@ void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine)
void QV4DebugService::engineAboutToBeRemoved(QQmlEngine *engine)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ 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 = d->debuggerMap.constEnd();
- for (DebuggerMapIterator i = d->debuggerMap.constBegin(); i != end; ++i) {
+ const DebuggerMapIterator end = debuggerMap.constEnd();
+ for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) {
if (i.value() == debugger) {
- d->debuggerMap.remove(i.key());
+ debuggerMap.remove(i.key());
break;
}
}
- d->debuggerAgent.removeDebugger(debugger);
+ debuggerAgent.removeDebugger(debugger);
}
}
QQmlConfigurableDebugService::engineAboutToBeRemoved(engine);
@@ -1104,13 +904,12 @@ void QV4DebugService::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.
- Q_D(QV4DebugService);
//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, d->breakOnSignals) {
+ foreach (const QString &signal, breakOnSignals) {
if (signal == signalName) {
// TODO: pause debugger
break;
@@ -1120,8 +919,7 @@ void QV4DebugService::signalEmitted(const QString &signal)
void QV4DebugService::messageReceived(const QByteArray &message)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QQmlDebugStream ms(message);
QByteArray header;
@@ -1136,10 +934,10 @@ void QV4DebugService::messageReceived(const QByteArray &message)
TRACE_PROTOCOL(qDebug() << "... type:" << type);
if (type == V4_CONNECT) {
- emit messageToClient(name(), d->packMessage(type));
+ emit messageToClient(name(), packMessage(type));
stopWaiting();
} else if (type == V4_PAUSE) {
- d->debuggerAgent.pauseAll();
+ debuggerAgent.pauseAll();
sendSomethingToSomebody(type);
} else if (type == V4_BREAK_ON_SIGNAL) {
QByteArray signal;
@@ -1148,9 +946,9 @@ void QV4DebugService::messageReceived(const QByteArray &message)
//Normalize to lower case.
QString signalName(QString::fromUtf8(signal).toLower());
if (enabled)
- d->breakOnSignals.append(signalName);
+ breakOnSignals.append(signalName);
else
- d->breakOnSignals.removeOne(signalName);
+ breakOnSignals.removeOne(signalName);
} else if (type == "v8request") {
handleV8Request(payload);
} else if (type == V4_DISCONNECT) {
@@ -1164,20 +962,40 @@ void QV4DebugService::messageReceived(const QByteArray &message)
void QV4DebugService::sendSomethingToSomebody(const char *type, int magicNumber)
{
- Q_D(QV4DebugService);
-
QByteArray response;
QQmlDebugStream rs(&response, QIODevice::WriteOnly);
rs << QByteArray(type)
- << QByteArray::number(d->version) << QByteArray::number(magicNumber);
- emit messageToClient(name(), d->packMessage(type, response));
+ << QByteArray::number(version) << QByteArray::number(magicNumber);
+ emit messageToClient(name(), packMessage(type, response));
+}
+
+QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugService *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);
- debugServicePrivate->clearHandles(debugger->engine());
+ debugService->clearHandles(debugger->engine());
QJsonObject event, body, script;
event.insert(QStringLiteral("type"), QStringLiteral("event"));
@@ -1212,7 +1030,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::Debugger *debugger, QV4::D
body.insert(QStringLiteral("script"), script);
if (!body.isEmpty())
event.insert(QStringLiteral("body"), body);
- debugServicePrivate->send(event);
+ debugService->send(event);
}
void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources, int requestSequenceNr)
@@ -1232,13 +1050,11 @@ void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::Debugger *debugger, QStr
response[QLatin1String("command")] = QStringLiteral("scripts");
response[QLatin1String("request_seq")] = requestSequenceNr;
response[QLatin1String("type")] = QStringLiteral("response");
- debugServicePrivate->send(response);
+ debugService->send(response);
}
void QV4DebugService::handleV8Request(const QByteArray &payload)
{
- Q_D(QV4DebugService);
-
TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload.constData());
QJsonDocument request = QJsonDocument::fromJson(payload);
@@ -1246,10 +1062,145 @@ void QV4DebugService::handleV8Request(const QByteArray &payload)
QJsonValue type = o.value(QStringLiteral("type"));
if (type.toString() == QStringLiteral("request")) {
QJsonValue command = o.value(QStringLiteral("command"));
- V8CommandHandler *h = d->v8CommandHandler(command.toString());
+ V8CommandHandler *h = v8CommandHandler(command.toString());
if (h)
- h->handle(o, this, d);
+ h->handle(o, this);
+ }
+}
+
+QByteArray QV4DebugService::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 QV4DebugService::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 QV4DebugService::clearHandles(QV4::ExecutionEngine *engine)
+{
+ theCollector.reset(new VariableCollector(engine));
+}
+
+QJsonObject QV4DebugService::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 QV4DebugService::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 QV4DebugService::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 QV4DebugService::lookup(int refId) const
+{
+ return theCollector->lookup(refId);
+}
+
+QJsonArray QV4DebugService::buildRefs()
+{
+ return theCollector->retrieveRefsToInclude();
+}
+
+VariableCollector *QV4DebugService::collector() const
+{
+ return theCollector.data();
+}
+
+void QV4DebugService::selectFrame(int frameNr)
+{
+ theSelectedFrame = frameNr;
+}
+
+int QV4DebugService::selectedFrame() const
+{
+ return theSelectedFrame;
}
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h
index f7b38b11b6..b824b47b23 100644
--- a/src/qml/debugger/qv4debugservice_p.h
+++ b/src/qml/debugger/qv4debugservice_p.h
@@ -46,12 +46,38 @@
//
#include "qqmlconfigurabledebugservice_p.h"
+#include <private/qv4debugging_p.h>
+
+#include <QtCore/QJsonValue>
QT_BEGIN_NAMESPACE
namespace QV4 { struct ExecutionEngine; }
+
class QQmlEngine;
-class QV4DebugServicePrivate;
+class VariableCollector;
+class V8CommandHandler;
+class UnknownV8CommandHandler;
+class QV4DebugService;
+
+class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
+{
+ Q_OBJECT
+public:
+ QV4DebuggerAgent(QV4DebugService *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:
+ QV4DebugService *debugService;
+};
+
class QV4DebugService : public QQmlConfigurableDebugService
{
@@ -65,6 +91,21 @@ public:
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 &);
@@ -72,10 +113,24 @@ protected:
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);
-private:
- Q_DISABLE_COPY(QV4DebugService)
- Q_DECLARE_PRIVATE(QV4DebugService)
+ 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