From 0931948c01bcf3481bea8ec66bcd2c93cdb7f287 Mon Sep 17 00:00:00 2001 From: Olivier Goffart <olivier.goffart@nokia.com> Date: Fri, 16 Jul 2010 11:44:29 +0200 Subject: [PATCH] QML JS debugging: premilary support of locals Unfortunatelly, streaming QVariant is not a really good idea, as streaming a custom type would fail --- src/plugins/debugger/qml/qmlengine.cpp | 152 +++++++++--------- src/plugins/debugger/qml/qmlengine.h | 2 +- src/tools/qml/qmlobserver/jsdebuggeragent.cpp | 2 +- 3 files changed, 76 insertions(+), 80 deletions(-) diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 1bc3de738ed..64d02257242 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -529,34 +529,44 @@ void QmlEngine::updateWatchData(const WatchData &data) } } -void QmlEngine::updateSubItem(const WatchData &data0) -{ - Q_UNUSED(data0) - QTC_ASSERT(false, return); -} - -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) +void QmlEngine::updateSubItem(WatchData &data, const QVariant &value) { + QList<WatchData> children; switch (value.userType()) { + case QVariant::Invalid:{ + const QString nullValue = QLatin1String("<undefined>"); + data.setType(nullValue, false); + data.setValue(nullValue); + break;} + case QVariant::Map: { + data.setType(QString::fromLatin1("Object"), false); + QVariantMap map = value.toMap(); + for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { + WatchData childData; + childData.iname = data.iname + '.' + it.key().toLatin1(); + childData.exp = it.key().toLatin1(); + childData.name = it.key(); + updateSubItem(childData, it.value()); + children.append(childData); + } + break; + } + case QVariant::List: { + data.setType(QString::fromLatin1("Array"), false); + QVariantList list = value.toList(); + QStringList values; + for (int i = 0; i < list.count(); ++i) { + WatchData childData; + childData.exp = QByteArray::number(i); + childData.iname = data.iname + '.' + childData.exp; + childData.name = QString::number(i); + updateSubItem(childData, list.at(i)); + children.append(childData); + values.append(list.at(i).toString()); + } + data.setValue(QLatin1Char('[') + values.join(QLatin1String(",")) + QLatin1Char(']')); + break; + } case QVariant::Bool: data.setType(QLatin1String("Bool"), false); data.setValue(value.toBool() ? QLatin1String("true") : QLatin1String("false")); @@ -569,56 +579,41 @@ static void updateWatchDataFromVariant(const QVariant &value, WatchData &data) 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); - } + break; + default: + data.setType(QString::fromLatin1(value.typeName()), false); + data.setValue(value.toString()); } + data.setHasChildren(!children.isEmpty()); + watchHandler()->insertData(data); +} + +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;*/ } void QmlEngine::messageReceived(const QByteArray &message) @@ -637,7 +632,8 @@ void QmlEngine::messageReceived(const QByteArray &message) QList<QPair<QString, QPair<QString, qint32> > > backtrace; QList<QPair<QString, QVariant> > watches; - stream >> backtrace >> watches; + QVariant locals; + stream >> backtrace >> watches >> locals; StackFrames stackFrames; typedef QPair<QString, QPair<QString, qint32> > Iterator; @@ -660,26 +656,26 @@ void QmlEngine::messageReceived(const QByteArray &message) data.name = it.first; data.exp = it.first.toUtf8(); data.iname = watchHandler()->watcherName(data.exp); - updateWatchDataFromVariant(it.second, data); - watchHandler()->insertData(data); + updateSubItem(data, it.second); } - watchHandler()->endCycle(); - - foreach (QDeclarativeDebugWatch *watch, m_watches) { - qDebug() << "WATCH" - << watch->objectName() - << watch->queryId() - << watch->state() - << watch->objectDebugId(); +// QVariantMap localsMap = locals.toMap(); +// for (QVariantMap::const_iterator it = localsMap.constBegin(); it != localsMap.constEnd(); it++) + { + WatchData localData; + localData.iname = "local"; + localData.name = QLatin1String("local"); + updateSubItem(localData, locals); } + watchHandler()->endCycle(); + } else if (command == "RESULT") { WatchData data; QVariant variant; stream >> data.iname >> data.name >> variant; data.exp = data.name.toUtf8(); - updateWatchDataFromVariant(variant, data); + updateSubItem(data, variant); qDebug() << Q_FUNC_INFO << this << data.name << data.iname << variant; watchHandler()->insertData(data); } else { diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 29e876983ad..910386c49c4 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -120,7 +120,7 @@ private: void maybeBreakNow(bool byFunction); void updateWatchData(const WatchData &data); void updateLocals(); - void updateSubItem(const WatchData &data); + void updateSubItem(WatchData& data, const QVariant& value); unsigned int debuggerCapabilities() const; diff --git a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp index 6e2553cb84f..c54c721f7b8 100644 --- a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp +++ b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp @@ -276,7 +276,7 @@ void JSDebuggerAgent::stopped() QByteArray reply; QDataStream rs(&reply, QIODevice::WriteOnly); - rs << QByteArray("STOPPED") << backtrace << watches; + rs << QByteArray("STOPPED") << backtrace << watches << engine()->currentContext()->activationObject().toVariant(); sendMessage(reply); loop.exec(QEventLoop::ExcludeUserInputEvents); -- GitLab