QmlV8DebuggerClient: Local Variables

Show "this" data in the locals window.
If handle is not present in ref list then fetch Local data
asynchronously. Insert the data when lookup request succeeds.

Change-Id: Ie342bcb963b76b8fcdb958979b59fb084fe50e51
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
This commit is contained in:
Aurindam Jana
2011-10-31 17:14:21 +01:00
parent ff73727f2f
commit 717acb6bf4

View File

@@ -52,9 +52,9 @@
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptValue>
#define DEBUG_QML 0
#define DEBUG_QML 1
#if DEBUG_QML
# define SDEBUG(s) qDebug() << s
# define SDEBUG(s) qDebug() << s << '\n'
#else
# define SDEBUG(s)
#endif
@@ -1005,9 +1005,6 @@ void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const
void QmlV8DebuggerClient::updateWatchData(const WatchData &data)
{
QTC_CHECK(d->state == QmlV8DebuggerClient::WaitingForRequestState
|| d->state == QmlV8DebuggerClient::RunningState);
if (data.isWatcher()) {
QString exp(data.exp);
if (!d->watchedExpressions.contains(exp)) {
@@ -1271,10 +1268,28 @@ void QmlV8DebuggerClient::updateStack(const QVariant &bodyVal, const QVariant &r
//Traverse the scope chain and store the local properties
//in a list and show them in the Locals Window.
const QVariantMap currentFrame = frames.value(0).toMap();
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
d->localDataList.clear();
d->currentFrameScopes.clear();
d->refsVal = refsVal;
//Set "this" variable
{
WatchData data;
data.exp = QByteArray("this");
data.name = QString(data.exp);
data.iname = "local." + data.exp;
QVariantMap receiver = currentFrame.value(_("receiver")).toMap();
if (receiver.contains(_(REF))) {
receiver = valueFromRef(receiver.value(_(REF)).toInt(), refsVal).toMap();
}
data.id = receiver.value(_("handle")).toInt();
QmlV8ObjectData receiverData = d->extractData(QVariant(receiver));
data.type = receiverData.type;
data.value = receiverData.value.toString();
data.setHasChildren(receiverData.properties.toList().count());
d->localDataList << data;
}
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
foreach (const QVariant &scope, currentFrameScopes) {
d->currentFrameScopes.push(scope.toMap().value(_("index")).toInt());
}
@@ -1432,16 +1447,25 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r
data.name = QString(data.exp);
data.iname = QByteArray("local.") + data.exp;
localData = valueFromRef(localData.value(_(REF)).toInt(), d->refsVal).toMap();
data.id = localData.value(_(HANDLE)).toInt();
int handle = localData.value(_(REF)).toInt();
localData = valueFromRef(handle, d->refsVal).toMap();
if (localData.isEmpty()) {
//Fetch Data asynchronously and insert later
// see expandLocalsAndWatchers()
d->localsAndWatchers.insert(handle, data.exp);
d->lookup(QList<int>() << handle);
QmlV8ObjectData objectData = d->extractData(QVariant(localData));
data.type = objectData.type;
data.value = objectData.value.toString();
} else {
data.id = localData.value(_(HANDLE)).toInt();
data.setHasChildren(objectData.properties.toList().count());
QmlV8ObjectData objectData = d->extractData(QVariant(localData));
data.type = objectData.type;
data.value = objectData.value.toString();
d->localDataList << data;
data.setHasChildren(objectData.properties.toList().count());
d->localDataList << data;
}
}
if (!d->currentFrameScopes.isEmpty()) {
@@ -1490,6 +1514,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, const QVariant &b
//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);
@@ -1498,7 +1523,6 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, const QVariant &b
//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()) {
@@ -1612,45 +1636,68 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const
// }
const QVariantMap body = bodyVal.toMap();
int handle = body.keys().value(0).toInt();
QByteArray prepend = d->localsAndWatchers.take(handle);
const WatchData *parent = d->engine->watchHandler()->findItem(prepend);
QString handle = body.keys().value(0);
QmlV8ObjectData bodyObjectData = d->extractData(
body.value(body.keys().value(0)));
body.value(handle));
QByteArray prepend = d->localsAndWatchers.take(handle.toInt());
QList<WatchData> watchDataList;
const QVariantList properties = bodyObjectData.properties.toList();
if (bodyObjectData.properties.isValid()) {
//Could be an object or function
const WatchData *parent = d->engine->watchHandler()->findItem(prepend);
const QVariantList properties = bodyObjectData.properties.toList();
foreach (const QVariant &property, properties) {
QVariantMap propertyData = property.toMap();
WatchData data;
data.name = propertyData.value(_(NAME)).toString();
QList<WatchData> children;
foreach (const QVariant &property, properties) {
QVariantMap propertyData = property.toMap();
WatchData data;
data.name = propertyData.value(_(NAME)).toString();
//Check for v8 specific local data
if (data.name.startsWith(".") || data.name.isEmpty())
continue;
if (parent && parent->type == "object") {
if (parent->value == _("Array"))
data.exp = parent->exp + QByteArray("[") + data.name.toLatin1() + QByteArray("]");
else if (parent->value == _("Object"))
data.exp = parent->exp + QByteArray(".") + data.name.toLatin1();
} else {
data.exp = data.name.toLatin1();
}
//Check for v8 specific local data
if (data.name.startsWith(".") || data.name.isEmpty())
continue;
if (parent->type == "object") {
if (parent->value == _("Array"))
data.exp = parent->exp + QByteArray("[") + data.name.toLatin1() + QByteArray("]");
else if (parent->value == _("Object"))
data.exp = parent->exp + QByteArray(".") + data.name.toLatin1();
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();
QmlV8ObjectData objectData = d->extractData(QVariant(propertyData));
data.type = objectData.type;
data.value = objectData.value.toString();
data.setHasChildren(objectData.properties.toList().count());
watchDataList << data;
}
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();
} else {
//rest
WatchData data;
data.exp = prepend;
data.name = data.exp;
data.iname = "local." + data.exp;
data.id = handle.toInt();
QmlV8ObjectData objectData = d->extractData(QVariant(propertyData));
data.type = objectData.type;
data.value = objectData.value.toString();
data.type = bodyObjectData.type;
data.value = bodyObjectData.value.toString();
data.setHasChildren(objectData.properties.toList().count());
children << data;
data.setHasChildren(bodyObjectData.properties.toList().count());
watchDataList << data;
}
d->engine->watchHandler()->insertBulkData(children);
d->engine->watchHandler()->beginCycle(false);
d->engine->watchHandler()->insertBulkData(watchDataList);
d->engine->watchHandler()->endCycle();
d->localDataList << watchDataList;
}
void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber,