Commit ab574ba8 authored by Aurindam Jana's avatar Aurindam Jana

Delegate javascript debugging to Script and V8 debugger clients.

The appropriate client handles the debugging based on the service available at the server side.

Change-Id: I46b66036f700fc7e45e8b38cef7f1ce1445b1122
Reviewed-on: http://codereview.qt.nokia.com/2497Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent 99926510
......@@ -88,7 +88,7 @@ public:
Status status() const;
void sendMessage(const QByteArray &);
virtual void sendMessage(const QByteArray &);
protected:
virtual void statusChanged(Status);
......
......@@ -1349,7 +1349,7 @@ void CodaGdbAdapter::handleReadRegisters(const CodaCommandResult &result)
logMessage("ERROR: " + result.errorString(), LogError);
return;
}
if (result.values.isEmpty() || result.values.front().type() != JsonValue::String) {
if (result.values.isEmpty() || result.values.front().type() != Json::JsonValue::String) {
logMessage(_("Format error in register message: ") + result.toString(),
LogError);
return;
......
include($$PWD/../../../libs/qmljsdebugclient/qmljsdebugclient-lib.pri)
include($$PWD/../../../shared/json/json.pri)
DEFINES += JSON_INCLUDE_PRI
HEADERS += \
$$PWD/qmlengine.h \
......@@ -6,10 +8,15 @@ HEADERS += \
$$PWD/qmldebuggerclient.h \
$$PWD/qmljsprivateapi.h \
$$PWD/qmlcppengine.h \
$$PWD/scriptconsole.h
$$PWD/scriptconsole.h \
$$PWD/qscriptdebuggerclient.h \
$$PWD/qmlv8debuggerclient.h
SOURCES += \
$$PWD/qmlengine.cpp \
$$PWD/qmladapter.cpp \
$$PWD/qmldebuggerclient.cpp \
$$PWD/qmlcppengine.cpp \
$$PWD/scriptconsole.cpp
$$PWD/scriptconsole.cpp \
$$PWD/qscriptdebuggerclient.cpp \
$$PWD/qmlv8debuggerclient.cpp
......@@ -33,10 +33,11 @@
#include "qmladapter.h"
#include "debuggerstartparameters.h"
#include "qmldebuggerclient.h"
#include "qscriptdebuggerclient.h"
#include "qmlv8debuggerclient.h"
#include "qmljsprivateapi.h"
#include "debuggerengine.h"
#include "qmlengine.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
......@@ -61,13 +62,13 @@ public:
}
QWeakPointer<DebuggerEngine> m_engine;
Internal::QmlDebuggerClient *m_qmlClient;
QmlDebuggerClient *m_qmlClient;
QTimer m_connectionTimer;
int m_connectionAttempts;
int m_maxConnectionAttempts;
QDeclarativeDebugConnection *m_conn;
QList<QByteArray> sendBuffer;
QHash<QString, QmlDebuggerClient*> debugClients;
};
} // namespace Internal
......@@ -149,16 +150,6 @@ void QmlAdapter::connectToViewer()
}
}
void QmlAdapter::sendMessage(const QByteArray &msg)
{
if (d->m_qmlClient->status() == QDeclarativeDebugClient::Enabled) {
flushSendBuffer();
d->m_qmlClient->sendMessage(msg);
} else {
d->sendBuffer.append(msg);
}
}
void QmlAdapter::connectionErrorOccurred(QAbstractSocket::SocketError socketError)
{
showConnectionStatusMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
......@@ -177,8 +168,10 @@ void QmlAdapter::clientStatusChanged(QDeclarativeDebugClient::Status status)
logServiceStatusChange(serviceName, status);
if (status == QDeclarativeDebugClient::Enabled)
flushSendBuffer();
if (status == QDeclarativeDebugClient::Enabled) {
d->m_qmlClient = d->debugClients.value(serviceName);
d->m_qmlClient->flushSendBuffer();
}
}
void QmlAdapter::connectionStateChanged()
......@@ -202,7 +195,8 @@ void QmlAdapter::connectionStateChanged()
showConnectionStatusMessage(tr("connected.\n"));
if (!d->m_qmlClient)
createDebuggerClient();
createDebuggerClients();
//reloadEngines();
emit connected();
break;
......@@ -216,16 +210,23 @@ void QmlAdapter::connectionStateChanged()
}
}
void QmlAdapter::createDebuggerClient()
void QmlAdapter::createDebuggerClients()
{
d->m_qmlClient = new Internal::QmlDebuggerClient(d->m_conn);
connect(d->m_qmlClient, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
Internal::QScriptDebuggerClient *client1 = new Internal::QScriptDebuggerClient(d->m_conn);
connect(client1, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
connect(d->m_engine.data(), SIGNAL(sendMessage(QByteArray)),
this, SLOT(sendMessage(QByteArray)));
connect(d->m_qmlClient, SIGNAL(messageWasReceived(QByteArray)),
d->m_engine.data(), SLOT(messageReceived(QByteArray)));
Internal::QmlV8DebuggerClient *client2 = new Internal::QmlV8DebuggerClient(d->m_conn);
connect(client2, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
d->debugClients.insert(client1->name(),client1);
d->debugClients.insert(client2->name(),client2);
client1->setEngine((Internal::QmlEngine*)(d->m_engine.data()));
client2->setEngine((Internal::QmlEngine*)(d->m_engine.data()));
//engine->startSuccessful(); // FIXME: AAA: port to new debugger states
}
......@@ -243,13 +244,13 @@ QDeclarativeDebugConnection *QmlAdapter::connection() const
void QmlAdapter::showConnectionStatusMessage(const QString &message)
{
if (!d->m_engine.isNull())
d->m_engine.data()->showMessage(QLatin1String("QmlJSDebugger: ") + message, LogStatus);
d->m_engine.data()->showMessage(QLatin1String("QmlDebugger: ") + message, LogStatus);
}
void QmlAdapter::showConnectionErrorMessage(const QString &message)
{
if (!d->m_engine.isNull())
d->m_engine.data()->showMessage(QLatin1String("QmlJSDebugger: ") + message, LogError);
d->m_engine.data()->showMessage(QLatin1String("QmlDebugger: ") + message, LogError);
}
bool QmlAdapter::disableJsDebugging(bool block)
......@@ -271,6 +272,15 @@ bool QmlAdapter::disableJsDebugging(bool block)
return isBlocked;
}
Internal::QmlDebuggerClient *QmlAdapter::activeDebuggerClient()
{
return d->m_qmlClient;
}
QHash<QString, Internal::QmlDebuggerClient*> QmlAdapter::debuggerClients()
{
return d->debugClients;
}
void QmlAdapter::logServiceStatusChange(const QString &service,
QDeclarativeDebugClient::Status newStatus)
{
......@@ -298,12 +308,4 @@ void QmlAdapter::logServiceActivity(const QString &service, const QString &logMe
d->m_engine.data()->showMessage(QString("%1 %2").arg(service, logMessage), LogDebug);
}
void QmlAdapter::flushSendBuffer()
{
QTC_ASSERT(d->m_qmlClient->status() == QDeclarativeDebugClient::Enabled, return);
foreach (const QByteArray &msg, d->sendBuffer)
d->m_qmlClient->sendMessage(msg);
d->sendBuffer.clear();
}
} // namespace Debugger
......@@ -70,6 +70,9 @@ public:
bool disableJsDebugging(bool block);
Internal::QmlDebuggerClient *activeDebuggerClient();
QHash<QString, Internal::QmlDebuggerClient*> debuggerClients();
public slots:
void logServiceStatusChange(const QString &service, QDeclarativeDebugClient::Status newStatus);
void logServiceActivity(const QString &service, const QString &logMessage);
......@@ -82,7 +85,6 @@ signals:
void serviceConnectionError(const QString serviceName);
private slots:
void sendMessage(const QByteArray &msg);
void connectionErrorOccurred(QAbstractSocket::SocketError socketError);
void clientStatusChanged(QDeclarativeDebugClient::Status status);
void connectionStateChanged();
......@@ -90,10 +92,9 @@ private slots:
private:
void connectToViewer();
void createDebuggerClient();
void createDebuggerClients();
void showConnectionStatusMessage(const QString &message);
void showConnectionErrorMessage(const QString &message);
void flushSendBuffer();
private:
QScopedPointer<Internal::QmlAdapterPrivate> d;
......
......@@ -37,13 +37,21 @@
namespace Debugger {
namespace Internal {
QmlDebuggerClient::QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client)
: QDeclarativeDebugClient(QLatin1String("JSDebugger"), client)
class QmlDebuggerClientPrivate
{
public:
QList<QByteArray> sendBuffer;
};
QmlDebuggerClient::QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client, QLatin1String clientName)
: QDeclarativeDebugClient(clientName, client),
d(new QmlDebuggerClientPrivate())
{
}
QmlDebuggerClient::~QmlDebuggerClient()
{
delete d;
}
void QmlDebuggerClient::statusChanged(Status status)
......@@ -51,9 +59,21 @@ void QmlDebuggerClient::statusChanged(Status status)
emit newStatus(status);
}
void QmlDebuggerClient::messageReceived(const QByteArray &data)
void QmlDebuggerClient::sendMessage(const QByteArray &msg)
{
if (status() == Enabled) {
QDeclarativeDebugClient::sendMessage(msg);
} else {
d->sendBuffer.append(msg);
}
}
void QmlDebuggerClient::flushSendBuffer()
{
emit messageWasReceived(data);
QTC_ASSERT(status() == QDeclarativeDebugClient::Enabled, return);
foreach (const QByteArray &msg, d->sendBuffer)
QDeclarativeDebugClient::sendMessage(msg);
d->sendBuffer.clear();
}
} // Internal
......
......@@ -30,32 +30,70 @@
**
**************************************************************************/
#ifndef QMLJSDEBUGGERCLIENT_H
#define QMLJSDEBUGGERCLIENT_H
#ifndef QMLDEBUGGERCLIENT_H
#define QMLDEBUGGERCLIENT_H
#include "qmljsprivateapi.h"
namespace Debugger {
namespace Internal {
class WatchData;
class BreakHandler;
class BreakpointModelId;
class QmlEngine;
class QmlDebuggerClientPrivate;
class QmlDebuggerClient : public QDeclarativeDebugClient
{
Q_OBJECT
public:
QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection *client);
QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client, QLatin1String clientName);
virtual ~QmlDebuggerClient();
virtual void executeStep() = 0;
virtual void executeStepOut() = 0;
virtual void executeNext() = 0;
virtual void executeStepI() = 0;
virtual void continueInferior() = 0;
virtual void interruptInferior() = 0;
virtual void activateFrame(int index) = 0;
virtual void insertBreakpoints(BreakHandler *handler, BreakpointModelId *id) = 0;
virtual void removeBreakpoints(BreakpointModelId *id) = 0;
virtual void setBreakpoints() = 0;
virtual void assignValueInDebugger(const QByteArray expr, const quint64 &id,
const QString &property, const QString value) = 0;
virtual void updateWatchData(const WatchData *data) = 0;
virtual void executeDebuggerCommand(const QString &command) = 0;
virtual void synchronizeWatchers(const QStringList &watchers) = 0;
virtual void expandObject(const QByteArray &iname, quint64 objectId) = 0;
virtual void sendPing() = 0;
virtual void setEngine(QmlEngine *engine) = 0;
void flushSendBuffer();
signals:
void newStatus(QDeclarativeDebugClient::Status status);
void messageWasReceived(const QByteArray &data);
protected:
virtual void statusChanged(Status status);
virtual void messageReceived(const QByteArray &data);
void sendMessage(const QByteArray &msg);
private:
QmlDebuggerClientPrivate *d;
friend class QmlDebuggerClientPrivate;
};
} // Internal
} // QmlJSInspector
} // Debugger
#endif // QMLJSDEBUGGERCLIENT_H
#endif // QMLDEBUGGERCLIENT_H
This diff is collapsed.
......@@ -49,6 +49,11 @@ class QmlEngine : public DebuggerEngine
Q_OBJECT
public:
enum LogDirection {
LogSend,
LogReceive
};
QmlEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
~QmlEngine();
......@@ -62,9 +67,12 @@ public:
int timeout = -1) const;
void filterApplicationMessage(const QString &msg, int channel);
virtual bool acceptsWatchesWhileRunning() const;
QString toFileInProject(const QUrl &fileUrl);
void inferiorSpontaneousStop();
void logMessage(LogDirection direction, const QString &str);
public slots:
void messageReceived(const QByteArray &message);
void disconnected();
private slots:
......@@ -120,7 +128,6 @@ private:
unsigned int debuggerCapabilities() const;
signals:
void sendMessage(const QByteArray &msg);
void tooltipRequested(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
......@@ -135,9 +142,6 @@ private slots:
void synchronizeWatchers();
private:
void expandObject(const QByteArray &iname, quint64 objectId);
void sendPing();
void closeConnection();
void startApplicationLauncher();
void stopApplicationLauncher();
......@@ -148,13 +152,6 @@ private:
const QString &oldBasePath, const QString &newBasePath) const;
QString qmlImportPath() const;
enum LogDirection {
LogSend,
LogReceive
};
void logMessage(LogDirection direction, const QString &str);
QString toFileInProject(const QUrl &fileUrl);
private:
friend class QmlCppEngine;
QmlEnginePrivate *d;
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "qmlv8debuggerclient.h"
#include "watchdata.h"
#include "watchhandler.h"
#include "breakpoint.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "qmlengine.h"
#include "stackhandler.h"
#include "debuggercore.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <QtCore/QVariant>
#include <QtCore/QFileInfo>
#include <QtGui/QTextDocument>
#include <QtGui/QMessageBox>
#define INITIALPARAMS "seq" << ':' << ++d->sequence << ',' << "type" << ':' << "request"
using namespace Json;
namespace Debugger {
namespace Internal {
class QmlV8DebuggerClientPrivate
{
public:
explicit QmlV8DebuggerClientPrivate(QmlV8DebuggerClient *) :
sequence(0), ping(0), engine(0)
{
}
int sequence;
int ping;
QmlEngine *engine;
QHash<BreakpointModelId,int> breakpoints;
QHash<int,BreakpointModelId> breakpointsSync;
QHash<int,QByteArray> locals;
QHash<int,QByteArray> watches;
QByteArray frames;
};
QmlV8DebuggerClient::QmlV8DebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client)
: QmlDebuggerClient(client, QLatin1String("V8Debugger")),
d(new QmlV8DebuggerClientPrivate(this))
{
}
QmlV8DebuggerClient::~QmlV8DebuggerClient()
{
delete d;
}
QByteArray QmlV8DebuggerClient::packMessage(QByteArray& message)
{
QByteArray reply;
QDataStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "V8DEBUG";
rs << cmd << message;
return reply;
}
void QmlV8DebuggerClient::executeStep()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "continue";
JsonInputStream(request) << ',' << "arguments" << ':';
JsonInputStream(request) << '{' << "stepaction" << ':' << "in";
JsonInputStream(request) << '}';
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::executeStepOut()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "continue";
JsonInputStream(request) << ',' << "arguments" << ':';
JsonInputStream(request) << '{' << "stepaction" << ':' << "out";
JsonInputStream(request) << '}';
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::executeNext()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "continue";
JsonInputStream(request) << ',' << "arguments" << ':';
JsonInputStream(request) << '{' << "stepaction" << ':' << "next";
JsonInputStream(request) << '}';
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::executeStepI()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "continue";
JsonInputStream(request) << ',' << "arguments" << ':';
JsonInputStream(request) << '{' << "stepaction" << ':' << "in";
JsonInputStream(request) << '}';
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::continueInferior()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "continue";
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::interruptInferior()
{
QByteArray request;
JsonInputStream(request) << '{' << INITIALPARAMS ;
JsonInputStream(request) << ',' << "command" << ':' << "interrupt";
JsonInputStream(request) << '}';
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::activateFrame(int index)
{
setLocals(index);
}
void QmlV8DebuggerClient::insertBreakpoints(BreakHandler *handler, BreakpointModelId *id)