summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-07-22 13:00:26 +0200
committerOlivier Goffart <olivier.goffart@nokia.com>2010-07-22 13:18:04 +0200
commitbfa609e33650061ef656a0c998d6a070fe0128c6 (patch)
treeebb7a60f6c1c8f33ba213ed6780e018be9f3e7c9 /src/tools
parent0340d6ad8b1b6a867e215de228e0f8d2d6df403a (diff)
downloadqt-creator-bfa609e33650061ef656a0c998d6a070fe0128c6.tar.gz
QML JS Debugger: Better way to stream watch data
QVariant does not work as they can contain custom type that corrypt the stream
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/qml/qmlobserver/jsdebuggeragent.cpp88
1 files changed, 82 insertions, 6 deletions
diff --git a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
index c54c721f7b..d79b18c4d4 100644
--- a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
+++ b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
@@ -47,9 +47,78 @@
#include <QtScript/QScriptContextInfo>
#include <QtCore/QDebug>
#include <QtCore/QUrl>
+#include <QtCore/QDateTime>
+#include <QtScript/qscriptvalueiterator.h>
QT_BEGIN_NAMESPACE
+namespace {
+struct JSAgentWatchData {
+ QByteArray exp;
+ QString name;
+ QString value;
+ QString type;
+ bool hasChildren;
+
+ static JSAgentWatchData fromScriptValue(const QString &expression, const QScriptValue &value)
+ {
+ JSAgentWatchData data;
+ data.exp = expression.toUtf8();
+ data.name = expression;
+ data.hasChildren = false;
+ data.value = value.toString();
+ if (value.isArray()) {
+ data.type = QLatin1String("Array");
+ data.value = QString::fromLatin1("[Array of length %1]").arg(value.property("length").toString());
+ data.hasChildren = true;
+ } else if (value.isBool()) {
+ data.type = QLatin1String("Bool");
+// data.value = value.toBool() ? QLatin1String("true") : QLatin1String("false");
+ } else if (value.isDate()) {
+ data.type = QLatin1String("Date");
+ data.value = value.toDateTime().toString();
+ } else if (value.isError()) {
+ data.type = QLatin1String("Error");
+ } else if (value.isFunction()) {
+ data.type = QLatin1String("Function");
+ } else if (value.isUndefined()) {
+ data.type = QLatin1String("<undefined>");
+ } else if (value.isNumber()) {
+ data.type = QLatin1String("Number");
+ } else if (value.isRegExp()) {
+ data.type = QLatin1String("RegExp");
+ } else if (value.isString()) {
+ data.type = QLatin1String("String");
+ } else if (value.isVariant()) {
+ data.type = QLatin1String("Variant");
+ } else if (value.isObject()) {
+ data.type = QLatin1String("Object");
+ data.hasChildren = true;
+ data.value = QLatin1String("[Object]");
+/* } else if (value.isQMetaObject()) {
+ data.setType(QLatin1String("QMetaObject"), false);
+ data.setValue(QString(QLatin1Char(' ')));
+ } else if (value.isQObject()) {
+ data.type = QLatin1String("QObject");
+ data.hasChildren = true;*/
+ } else if (value.isNull()) {
+ data.type = QLatin1String("<null>");
+ } else {
+ data.type = QLatin1String("<unknown>");
+ }
+ return data;
+ }
+};
+
+
+QDataStream& operator<<(QDataStream& s, const JSAgentWatchData& data)
+{
+ return s << data.exp << data.name << data.value << data.type << data.hasChildren;
+}
+
+}
+
+
/*!
Constructs a new agent for the given \a engine. The agent will
report debugging-related events (e.g. step completion) to the given
@@ -219,13 +288,13 @@ void JSDebuggerAgent::messageReceived(const QByteArray& message)
QString expr;
ds >> id >> expr;
- QVariant val = engine()->evaluate(expr).toVariant();
+ JSAgentWatchData data = JSAgentWatchData::fromScriptValue(expr, engine()->evaluate(expr));
// Clear any exceptions occurred during locals evaluation.
engine()->clearExceptions();
QByteArray reply;
QDataStream rs(&reply, QIODevice::WriteOnly);
- rs << QByteArray("RESULT") << id << expr << val;
+ rs << QByteArray("RESULT") << id << data;
sendMessage(reply);
state = oldState;
@@ -265,18 +334,25 @@ void JSDebuggerAgent::stopped()
}
backtrace.append(qMakePair(functionName, qMakePair( QUrl(info.fileName()).toLocalFile(), info.lineNumber() ) ) );
}
- QList<QPair<QString, QVariant> > watches;
+ QList<JSAgentWatchData> watches;
foreach (const QString &expr, watchExpressions) {
- watches << qMakePair(expr, engine()->evaluate(expr).toVariant());
+ watches << JSAgentWatchData::fromScriptValue(expr, engine()->evaluate(expr));
+ }
+
+ QList<JSAgentWatchData> locals;
+ QScriptValue activationObject = engine()->currentContext()->activationObject();
+ QScriptValueIterator it(activationObject);
+ while (it.hasNext()) {
+ it.next();
+ locals << JSAgentWatchData::fromScriptValue(it.name(), it.value());
}
// Clear any exceptions occurred during locals evaluation.
engine()->clearExceptions();
-
QByteArray reply;
QDataStream rs(&reply, QIODevice::WriteOnly);
- rs << QByteArray("STOPPED") << backtrace << watches << engine()->currentContext()->activationObject().toVariant();
+ rs << QByteArray("STOPPED") << backtrace << watches << locals;
sendMessage(reply);
loop.exec(QEventLoop::ExcludeUserInputEvents);