diff options
author | hjk <qtc-committer@nokia.com> | 2010-06-25 14:08:53 +0200 |
---|---|---|
committer | hjk <qtc-committer@nokia.com> | 2010-06-25 14:09:35 +0200 |
commit | e2159536b02209516d6c38b8a9b6596001dd4af9 (patch) | |
tree | 317fb34ecbc7fadff4d6fe15879f587501146aaf /src/plugins/debugger | |
parent | 112b713343ddaff25b0a60878319b9e1d228577e (diff) | |
download | qt-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.pri | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.h | 4 | ||||
-rw-r--r-- | src/plugins/debugger/qml/qmlengine.cpp | 223 | ||||
-rw-r--r-- | src/plugins/debugger/qml/qmlengine.h | 19 | ||||
-rw-r--r-- | src/plugins/debugger/watchhandler.h | 3 |
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; |