Commit 0931948c authored by Olivier Goffart's avatar Olivier Goffart
Browse files

QML JS debugging: premilary support of locals

Unfortunatelly, streaming QVariant is not a really good idea, as streaming
a custom type would fail
parent 181e7086
......@@ -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 {
......
......@@ -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;
......
......@@ -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);
......
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