From ff73727f2fcaf0b302b92d43f25feb2024b9eb5a Mon Sep 17 00:00:00 2001 From: Aurindam Jana <aurindam.jana@nokia.com> Date: Fri, 28 Oct 2011 16:43:20 +0200 Subject: [PATCH] QmlV8DebuggerClient: Show Watched Expressions Change-Id: Ic51116741556ba1f36f64c7d1341ba993bdeacc9 Reviewed-by: Kai Koehne <kai.koehne@nokia.com> --- .../debugger/qml/qmlv8debuggerclient.cpp | 126 ++++++++++++------ .../debugger/qml/qmlv8debuggerclient.h | 2 +- 2 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 8fe6ba63782..64e1a3b0bdb 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -128,8 +128,10 @@ public: QmlEngine *engine; QHash<BreakpointModelId, int> breakpoints; QHash<int, BreakpointModelId> breakpointsSync; - QHash<int, QByteArray> locals; - QHash<int, WatchDataPair> watches; + QHash<int, QByteArray> localsAndWatchers; + QHash<int, QString> evaluatingWatches; + QStringList watchedExpressions; + QStack<QString> watchesToEvaluate; QScriptValue parser; QScriptValue stringifier; @@ -233,8 +235,6 @@ void QmlV8DebuggerClientPrivate::evaluate(const QString expr, bool global, bool disableBreak, int frame, bool addContext) { - updateCurrentStackFrameIndex = false; - // { "seq" : <number>, // "type" : "request", // "command" : "evaluate", @@ -921,6 +921,7 @@ void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id) { QTC_CHECK(d->state == QmlV8DebuggerClient::WaitingForRequestState || d->state == QmlV8DebuggerClient::RunningState); + SDEBUG(QString(_("State: %1")).arg(d->state)); BreakHandler *handler = d->engine->breakHandler(); const BreakpointParameters ¶ms = handler->breakpointData(id); @@ -997,27 +998,21 @@ void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const QString expression = QString(_("%1 = %2;")).arg(property).arg(value); if (stackHandler->isContentsValid()) { d->state = QmlV8DebuggerClient::BacktraceRequestedState; + d->updateCurrentStackFrameIndex = false; d->evaluate(expression, false, false, stackHandler->currentIndex()); } } void QmlV8DebuggerClient::updateWatchData(const WatchData &data) { + QTC_CHECK(d->state == QmlV8DebuggerClient::WaitingForRequestState + || d->state == QmlV8DebuggerClient::RunningState); + if (data.isWatcher()) { - WatchDataPair pair(data.iname, data.exp); - if (d->watches.key(pair)) { - WatchData data1 = data; - data1.setAllUnneeded(); - // data1.setValue(_("<unavailable>")); - // data1.setHasChildren(false); - d->engine->watchHandler()->insertData(data1); - } else { - StackHandler *stackHandler = d->engine->stackHandler(); - if (stackHandler->isContentsValid()) - d->evaluate(data.exp, false, false, stackHandler->currentIndex()); - else - d->evaluate(data.exp); - d->watches.insert(d->sequence, pair); + QString exp(data.exp); + if (!d->watchedExpressions.contains(exp)) { + //Push new expression to the stack + d->watchesToEvaluate.push(exp); } } } @@ -1030,6 +1025,7 @@ void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command) if (stackHandler->isContentsValid()) { //Set the state d->state = QmlV8DebuggerClient::BacktraceRequestedState; + d->updateCurrentStackFrameIndex = false; d->evaluate(command, false, false, stackHandler->currentIndex()); } else { //Currently cannot evaluate if not in a javascript break @@ -1038,15 +1034,28 @@ void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command) } } -void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &/*watchers*/) +void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &watchers) { - //TODO:: + SDEBUG(watchers); + //Cache the watched expression List + d->watchedExpressions = watchers; + //Evaluate new expressions one at a time. + if (!d->watchesToEvaluate.isEmpty()) { + StackHandler *stackHandler = d->engine->stackHandler(); + const QString exp = d->watchesToEvaluate.pop(); + if (stackHandler->isContentsValid()) { + d->evaluate(exp, false, false, stackHandler->currentIndex()); + } else { + d->evaluate(exp); + } + d->evaluatingWatches.insert(d->sequence, exp); + } } void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId) { QTC_CHECK(d->state == QmlV8DebuggerClient::WaitingForRequestState); - d->locals.insertMulti(objectId, iname); + d->localsAndWatchers.insertMulti(objectId, iname); d->lookup(QList<int>() << objectId); } @@ -1097,14 +1106,16 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data) } } else if (debugCommand == _(LOOKUP)) { - expandLocal(resp.value(_(BODY)), resp.value(_(REFS))); + expandLocalsAndWatchers(resp.value(_(BODY)), resp.value(_(REFS))); } else if (debugCommand == _(EVALUATE)) { + int seq = resp.value(_("request_seq")).toInt(); if (success) { - int seq = resp.value(_("request_seq")).toInt(); updateEvaluationResult(seq, resp.value(_(BODY)), resp.value(_(REFS))); } else { d->engine->showMessage(resp.value(_("message")).toString(), ScriptConsoleOutput); + if (d->evaluatingWatches.contains(seq)) + updateEvaluationResult(seq, QVariant(), QVariant()); } } else if (debugCommand == _(LISTBREAKPOINTS)) { @@ -1355,7 +1366,7 @@ void QmlV8DebuggerClient::updateLocals(const QVariant &localsVal, const QVariant if (data.exp.startsWith(".") || data.exp.isEmpty()) continue; - data.name = data.exp; + data.name = QString(data.exp); data.iname = QByteArray("local.") + data.exp; localData = valueFromRef(localData.value(_(VALUE)).toMap() @@ -1418,7 +1429,7 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r if (data.exp.startsWith(".") || data.exp.isEmpty()) continue; - data.name = data.exp; + data.name = QString(data.exp); data.iname = QByteArray("local.") + data.exp; localData = valueFromRef(localData.value(_(REF)).toInt(), d->refsVal).toMap(); @@ -1460,27 +1471,45 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, const QVariant &b QmlV8ObjectData body = d->extractData(QVariant(bodyMap)); - if (!d->watches.contains(sequence)) { + if (!d->evaluatingWatches.contains(sequence)) { //Console d->engine->showMessage(body.value.toString(), ScriptConsoleOutput); } else { - WatchDataPair pair = d->watches.value(sequence); - QByteArray iname = pair.first; - QByteArray exp = pair.second; + QString exp = d->evaluatingWatches.take(sequence); + QByteArray iname = d->engine->watchHandler()->watcherName(exp.toLatin1()); + SDEBUG(QString(iname)); WatchData data; - data.exp = exp; - data.name = data.exp; + data.exp = exp.toLatin1(); + data.name = exp; data.iname = iname; data.id = bodyMap.value(_(HANDLE)).toInt(); data.type = body.type; data.value = body.value.toString(); - const QVariantList properties = body.properties.toList(); - data.setHasChildren(properties.count()); - // data.setAllUnneeded(); - // data.setValueNeeded(); + //TODO:: Fix expanding watched objects/expressions +// const QVariantList properties = body.properties.toList(); +// data.setHasChildren(properties.count()); + //Insert the newly evaluated expression to the Watchers Window + d->engine->watchHandler()->beginCycle(false); d->engine->watchHandler()->insertData(data); + d->engine->watchHandler()->endCycle(); + + //Check if there are more expressions to be evaluated + //Evaluate one at a time. + if (!d->watchesToEvaluate.isEmpty()) { + QTC_CHECK(d->state == QmlV8DebuggerClient::WaitingForRequestState); + StackHandler *stackHandler = d->engine->stackHandler(); + const QString exp = d->watchesToEvaluate.pop(); + if (stackHandler->isContentsValid()) { + d->evaluate(exp, false, false, stackHandler->currentIndex()); + } else { + d->evaluate(exp); + } + d->evaluatingWatches.insert(d->sequence, exp); + + } + // foreach (const QVariant &property, properties) { // QVariantMap propertyData = property.toMap(); @@ -1571,7 +1600,7 @@ QVariant QmlV8DebuggerClient::valueFromRef(int handle, const QVariant &refsVal) return variant; } -void QmlV8DebuggerClient::expandLocal(const QVariant &bodyVal, const QVariant &refsVal) +void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal) { // { "seq" : <number>, // "type" : "response", @@ -1584,7 +1613,7 @@ void QmlV8DebuggerClient::expandLocal(const QVariant &bodyVal, const QVariant &r const QVariantMap body = bodyVal.toMap(); int handle = body.keys().value(0).toInt(); - QByteArray prepend = d->locals.take(handle); + QByteArray prepend = d->localsAndWatchers.take(handle); const WatchData *parent = d->engine->watchHandler()->findItem(prepend); QmlV8ObjectData bodyObjectData = d->extractData( body.value(body.keys().value(0))); @@ -1606,7 +1635,10 @@ void QmlV8DebuggerClient::expandLocal(const QVariant &bodyVal, const QVariant &r else if (parent->value == _("Object")) data.exp = parent->exp + QByteArray(".") + data.name.toLatin1(); } - data.iname = prepend + '.' + data.name.toUtf8(); + if (prepend.startsWith("local.")) + data.iname = prepend + '.' + data.name.toLatin1(); + if (prepend.startsWith("watch.")) + data.iname = prepend; propertyData = valueFromRef(propertyData.value(_(REF)).toInt(), refsVal).toMap(); data.id = propertyData.value(_(HANDLE)).toInt(); @@ -1695,6 +1727,24 @@ void QmlV8DebuggerClient::updateLocalsAndWatchers() d->engine->watchHandler()->beginCycle(); d->engine->watchHandler()->insertBulkData(d->localDataList); d->engine->watchHandler()->endCycle(); + + //Push all Watched expressions to a stack. + //Evaluate the expressions one at a time + //and append the evaluated result to the watchers + //window (see updateEvaluationResult()) + foreach (const QString &expr, d->watchedExpressions) + d->watchesToEvaluate.push(expr); + + if (!d->watchesToEvaluate.isEmpty()) { + StackHandler *stackHandler = d->engine->stackHandler(); + const QString exp = d->watchesToEvaluate.pop(); + if (stackHandler->isContentsValid()) { + d->evaluate(exp, false, false, stackHandler->currentIndex()); + } else { + d->evaluate(exp); + } + d->evaluatingWatches.insert(d->sequence, exp); + } } } // Internal diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index a31fb91fc77..d3ce6fe6c09 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -119,7 +119,7 @@ private: QVariant valueFromRef(int handle, const QVariant &refsVal); - void expandLocal(const QVariant &bodyVal, const QVariant &refsVal); + void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal); void highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage); -- GitLab