summaryrefslogtreecommitdiff
path: root/src/plugins/debugger
diff options
context:
space:
mode:
authorhjk <qtc-committer@nokia.com>2010-06-25 14:08:53 +0200
committerhjk <qtc-committer@nokia.com>2010-06-25 14:09:35 +0200
commite2159536b02209516d6c38b8a9b6596001dd4af9 (patch)
tree317fb34ecbc7fadff4d6fe15879f587501146aaf /src/plugins/debugger
parent112b713343ddaff25b0a60878319b9e1d228577e (diff)
downloadqt-creator-e2159536b02209516d6c38b8a9b6596001dd4af9.tar.gz
debugger: incorporate ogoffart's first shot at qml debugging
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r--src/plugins/debugger/debugger.pri2
-rw-r--r--src/plugins/debugger/debuggerengine.h4
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp223
-rw-r--r--src/plugins/debugger/qml/qmlengine.h19
-rw-r--r--src/plugins/debugger/watchhandler.h3
5 files changed, 231 insertions, 20 deletions
diff --git a/src/plugins/debugger/debugger.pri b/src/plugins/debugger/debugger.pri
index e8ed70aa9e..52045952fd 100644
--- a/src/plugins/debugger/debugger.pri
+++ b/src/plugins/debugger/debugger.pri
@@ -1,3 +1,5 @@
include(debugger_dependencies.pri)
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
LIBS *= -l$$qtLibraryTarget(Debugger)
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 8462d318ff..51dbfe3624 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -112,8 +112,8 @@ class WatchHandler;
class DebuggerEnginePrivate;
-
-class DebuggerEngine : public QObject
+// FIXME: DEBUGGER_EXPORT?
+class DEBUGGER_EXPORT DebuggerEngine : public QObject
{
Q_OBJECT
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index fc3a1c1ba1..6767fa7538 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -204,18 +204,25 @@ void QmlEngine::startDebugger()
qDebug() << "STARTING QML ENGINE";
setState(InferiorRunningRequested);
showStatusMessage(tr("Running requested..."), 5000);
- const DebuggerStartParameters &sp = startParameters();
+/* const DebuggerStartParameters &sp = startParameters();
const int pos = sp.remoteChannel.indexOf(QLatin1Char(':'));
const QString host = sp.remoteChannel.left(pos);
const quint16 port = sp.remoteChannel.mid(pos + 1).toInt();
//QTimer::singleShot(0, this, SLOT(runInferior()));
- m_socket->connectToHost(host, port);
+ m_socket->connectToHost(host, port); */
startSuccessful();
+ setState(InferiorRunning); // FIXME
}
void QmlEngine::continueInferior()
{
SDEBUG("QmlEngine::continueInferior()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("CONTINUE");
+ sendMessage(reply);
+ setState(InferiorRunningRequested);
+ setState(InferiorRunning);
}
void QmlEngine::runInferior()
@@ -224,32 +231,59 @@ void QmlEngine::runInferior()
void QmlEngine::interruptInferior()
{
- XSDEBUG("QmlEngine::interruptInferior()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("INTERRUPT");
+ sendMessage(reply);
}
void QmlEngine::executeStep()
{
- //SDEBUG("QmlEngine::executeStep()");
+ SDEBUG("QmlEngine::executeStep()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("STEPINTO");
+ sendMessage(reply);
+ setState(InferiorRunningRequested);
+ setState(InferiorRunning);
}
void QmlEngine::executeStepI()
{
- //SDEBUG("QmlEngine::executeStepI()");
+ SDEBUG("QmlEngine::executeStepI()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("STEPINTO");
+ sendMessage(reply);
+ setState(InferiorRunningRequested);
+ setState(InferiorRunning);
}
void QmlEngine::executeStepOut()
{
- //SDEBUG("QmlEngine::executeStepOut()");
+ SDEBUG("QmlEngine::executeStepOut()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("STEPOUT");
+ sendMessage(reply);
+ setState(InferiorRunningRequested);
+ setState(InferiorRunning);
}
void QmlEngine::executeNext()
{
- //SDEBUG("QmlEngine::nextExec()");
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("STEPOVER");
+ sendMessage(reply);
+ setState(InferiorRunningRequested);
+ setState(InferiorRunning);
+ SDEBUG("QmlEngine::nextExec()");
}
void QmlEngine::executeNextI()
{
- //SDEBUG("QmlEngine::executeNextI()");
+ SDEBUG("QmlEngine::executeNextI()");
}
void QmlEngine::executeRunToLine(const QString &fileName, int lineNumber)
@@ -275,6 +309,8 @@ void QmlEngine::executeJumpToLine(const QString &fileName, int lineNumber)
void QmlEngine::activateFrame(int index)
{
Q_UNUSED(index)
+ qDebug() << Q_FUNC_INFO << index;
+ gotoLocation(stackHandler()->frames().value(index), true);
}
void QmlEngine::selectThread(int index)
@@ -284,6 +320,22 @@ void QmlEngine::selectThread(int index)
void QmlEngine::attemptBreakpointSynchronization()
{
+ BreakHandler *handler = breakHandler();
+ //bool updateNeeded = false;
+ QSet< QPair<QString, qint32> > breakList;
+ for (int index = 0; index != handler->size(); ++index) {
+ BreakpointData *data = handler->at(index);
+ breakList << qMakePair(data->fileName, data->lineNumber.toInt());
+ }
+
+ {
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("BREAKPOINTS");
+ rs << breakList;
+ //qDebug() << Q_FUNC_INFO << breakList;
+ sendMessage(reply);
+ }
}
void QmlEngine::loadSymbols(const QString &moduleName)
@@ -521,10 +573,26 @@ void QmlEngine::updateLocals()
{
}
-void QmlEngine::updateWatchData(const WatchData &)
+void QmlEngine::updateWatchData(const WatchData &data)
{
//watchHandler()->rebuildModel();
showStatusMessage(tr("Stopped."), 5000);
+
+ if (!data.name.isEmpty()) {
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("EXEC");
+ rs << data.iname << data.name;
+ sendMessage(reply);
+ }
+
+ {
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("WATCH_EXPRESSIONS");
+ rs << watchHandler()->watchedExpressions();
+ sendMessage(reply);
+ }
}
void QmlEngine::updateSubItem(const WatchData &data0)
@@ -538,5 +606,142 @@ DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp)
return new QmlEngine(sp);
}
+unsigned QmlEngine::debuggerCapabilities() const
+{
+ return AddWatcherCapability;
+ /*ReverseSteppingCapability | SnapshotCapability
+ | AutoDerefPointersCapability | DisassemblerCapability
+ | RegisterCapability | ShowMemoryCapability
+ | JumpToLineCapability | ReloadModuleCapability
+ | ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability
+ | ReturnFromFunctionCapability
+ | CreateFullBacktraceCapability
+ | WatchpointCapability
+ | AddWatcherCapability;*/
+}
+
+static void updateWatchDataFromVariant(const QVariant &value, WatchData &data)
+{
+ switch (value.userType()) {
+ case QVariant::Bool:
+ data.setType(QLatin1String("Bool"), false);
+ data.setValue(value.toBool() ? QLatin1String("true") : QLatin1String("false"));
+ data.setHasChildren(false);
+ break;
+ case QVariant::Date:
+ case QVariant::DateTime:
+ case QVariant::Time:
+ data.setType(QLatin1String("Date"), false);
+ data.setValue(value.toDateTime().toString());
+ data.setHasChildren(false);
+ break;
+ /*} else if (ob.isError()) {
+ data.setType(QLatin1String("Error"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (ob.isFunction()) {
+ data.setType(QLatin1String("Function"), false);
+ data.setValue(QString(QLatin1Char(' ')));*/
+ case QVariant::Invalid:{
+ const QString nullValue = QLatin1String("<null>");
+ data.setType(nullValue, false);
+ data.setValue(nullValue);
+ break;}
+ case QVariant::UInt:
+ case QVariant::Int:
+ case QVariant::Double:
+ //FIXME FLOAT
+ data.setType(QLatin1String("Number"), false);
+ data.setValue(QString::number(value.toDouble()));
+ data.setHasChildren(false);
+ break;
+/* } else if (ob.isObject()) {
+ data.setType(QLatin1String("Object"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (ob.isQMetaObject()) {
+ data.setType(QLatin1String("QMetaObject"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (ob.isQObject()) {
+ data.setType(QLatin1String("QObject"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (ob.isRegExp()) {
+ data.setType(QLatin1String("RegExp"), false);
+ data.setValue(ob.toRegExp().pattern());
+ } else if (ob.isString()) {*/
+ case QVariant::String:
+ data.setType(QLatin1String("String"), false);
+ data.setValue(value.toString());
+/* } else if (ob.isVariant()) {
+ data.setType(QLatin1String("Variant"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (ob.isUndefined()) {
+ data.setType(QLatin1String("<undefined>"), false);
+ data.setValue(QLatin1String("<unknown>"));
+ data.setHasChildren(false);
+ } else {*/
+ default:{
+ const QString unknown = QLatin1String("<unknown>");
+ data.setType(unknown, false);
+ data.setValue(unknown);
+ data.setHasChildren(false);
+ }
+ }
+}
+
+void QmlEngine::messageReceived(const QByteArray &message)
+{
+ QByteArray rwData = message;
+ QDataStream stream(&rwData, QIODevice::ReadOnly);
+
+ QByteArray command;
+ stream >> command;
+
+ if(command == "STOPPED") {
+ QList<QPair<QString, QPair<QString, qint32> > > backtrace;
+ QList<QPair<QString, QVariant> > watches;
+ stream >> backtrace >> watches;
+
+ QList<StackFrame> stackFrames;
+ typedef QPair<QString, QPair<QString, qint32> > Iterator;
+ foreach (const Iterator &it, backtrace) {
+ StackFrame frame;
+ frame.file = it.second.first;
+ frame.line = it.second.second;
+ frame.function = it.first;
+ stackFrames << frame;
+ }
+
+ gotoLocation(stackFrames.value(0), true);
+ stackHandler()->setFrames(stackFrames);
+
+ watchHandler()->beginCycle();
+
+ typedef QPair<QString, QVariant > Iterator2;
+ foreach (const Iterator2 &it, watches) {
+ WatchData data;
+ data.name = it.first;
+ data.exp = it.first.toUtf8();
+ data.iname = watchHandler()->watcherName(data.exp);
+ updateWatchDataFromVariant(it.second, data);
+ watchHandler()->insertData(data);
+ }
+
+ watchHandler()->endCycle();
+
+ setState(InferiorStopping);
+ setState(InferiorStopped);
+ } else if (command == "RESULT") {
+ WatchData data;
+ QVariant variant;
+ stream >> data.iname >> data.name >> variant;
+ data.exp = data.name.toUtf8();
+ updateWatchDataFromVariant(variant, data);
+ qDebug() << Q_FUNC_INFO << this << data.name << data.iname << variant;
+ watchHandler()->insertData(data);
+ } else {
+ qDebug() << Q_FUNC_INFO << "Unknown command: " << command;
+ }
+
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index eec0e7d310..5fc3c3ca86 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -30,14 +30,13 @@
#ifndef DEBUGGER_QMLENGINE_H
#define DEBUGGER_QMLENGINE_H
+#include "debuggerengine.h"
+
#include <QtCore/QByteArray>
#include <QtCore/QHash>
-#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QPoint>
-#include <QtCore/QProcess>
#include <QtCore/QQueue>
-#include <QtCore/QSet>
#include <QtCore/QTimer>
#include <QtCore/QVariant>
@@ -47,9 +46,6 @@ QT_BEGIN_NAMESPACE
class QTcpSocket;
QT_END_NAMESPACE
-#include "debuggerengine.h"
-
-
namespace Debugger {
namespace Internal {
@@ -57,7 +53,7 @@ class ScriptAgent;
class WatchData;
class QmlResponse;
-class QmlEngine : public DebuggerEngine
+class DEBUGGER_EXPORT QmlEngine : public DebuggerEngine
{
Q_OBJECT
@@ -65,6 +61,9 @@ public:
explicit QmlEngine(const DebuggerStartParameters &startParameters);
~QmlEngine();
+ void messageReceived(const QByteArray &message);
+ using DebuggerEngine::setState;
+
private:
// DebuggerEngine implementation
void executeStep();
@@ -118,7 +117,8 @@ private:
void handleRunControlGetChildren(const QmlResponse &response, const QVariant &);
void handleSysMonitorGetChildren(const QmlResponse &response, const QVariant &);
-private:
+ unsigned int debuggerCapabilities() const;
+
Q_SLOT void startDebugging();
typedef void (QmlEngine::*QmlCommandCallback)
@@ -159,6 +159,9 @@ private:
QTcpSocket *m_socket;
QByteArray m_inbuffer;
QList<QByteArray> m_services;
+
+signals:
+ void sendMessage(const QByteArray &);
};
} // namespace Internal
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 145a67c8cc..29d7cc2ecf 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -176,6 +176,8 @@ public:
void addTypeFormats(const QString &type, const QStringList &formats);
+ QByteArray watcherName(const QByteArray &exp);
+
private:
friend class WatchModel;
@@ -194,7 +196,6 @@ private:
EditHandlers m_editHandlers;
QHash<QByteArray, int> m_watcherNames;
- QByteArray watcherName(const QByteArray &exp);
QHash<QString, int> m_typeFormats;
QHash<QByteArray, int> m_individualFormats; // Indexed by iname.
QHash<QString, QStringList> m_reportedTypeFormats;