Commit ff73727f authored by Aurindam Jana's avatar Aurindam Jana
Browse files

QmlV8DebuggerClient: Show Watched Expressions



Change-Id: Ic51116741556ba1f36f64c7d1341ba993bdeacc9
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent b8af7f2a
......@@ -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 &params = 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
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment