aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2015-08-24 21:13:41 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-08-24 21:14:07 +0200
commit922ca8c3a839ccbf3407bfe7e449bfceec5ecd23 (patch)
treef18c3702e1692c17ebe710530aba931c8a4554f6 /src/plugins
parent9c9fca5e27bd91da1ea07bebd7569049493c5ccf (diff)
parent9dd496c069154ac655be9b85b72a6eb409bfa223 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp116
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp51
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h1
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp1
5 files changed, 103 insertions, 70 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 64ee5c3b96..2ef7713ac7 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -37,6 +37,7 @@
#include <private/qv4string_p.h>
#include <private/qv4objectiterator_p.h>
#include <private/qv4identifier_p.h>
+#include <private/qv4runtime_p.h>
#include <QtCore/qjsonarray.h>
@@ -109,51 +110,78 @@ void QV4DataCollector::collect(const QV4::ScopedValue &value)
m_collectedRefs->append(addRef(value));
}
-QJsonObject QV4DataCollector::lookupRef(Ref ref)
+const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::ExecutionEngine *engine,
+ QJsonObject &dict)
{
- QJsonObject dict;
- if (lookupSpecialRef(ref, &dict))
- return dict;
-
- dict.insert(QStringLiteral("handle"), qint64(ref));
+ QV4::Scope scope(engine);
+ QV4::ScopedValue typeString(scope, QV4::Runtime::typeofValue(engine, value));
+ dict.insert(QStringLiteral("type"), typeString->toQStringNoThrow());
- QV4::Scope scope(engine());
- QV4::ScopedValue value(scope, getValue(ref));
+ const QLatin1String valueKey("value");
switch (value->type()) {
case QV4::Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
- break;
+ return 0;
case QV4::Value::Undefined_Type:
- dict.insert(QStringLiteral("type"), QStringLiteral("undefined"));
- break;
+ dict.insert(valueKey, QJsonValue::Undefined);
+ return 0;
case QV4::Value::Null_Type:
+ // "null" is not the correct type, but we leave this in until QtC can deal with "object"
dict.insert(QStringLiteral("type"), QStringLiteral("null"));
- break;
+ dict.insert(valueKey, QJsonValue::Null);
+ return 0;
case QV4::Value::Boolean_Type:
- dict.insert(QStringLiteral("type"), QStringLiteral("boolean"));
- dict.insert(QStringLiteral("value"), value->booleanValue() ? QStringLiteral("true")
- : QStringLiteral("false"));
- break;
+ dict.insert(valueKey, value->booleanValue());
+ return 0;
case QV4::Value::Managed_Type:
- if (QV4::String *s = value->as<QV4::String>()) {
- dict.insert(QStringLiteral("type"), QStringLiteral("string"));
- dict.insert(QStringLiteral("value"), s->toQString());
- } else if (QV4::Object *o = value->as<QV4::Object>()) {
- dict.insert(QStringLiteral("type"), QStringLiteral("object"));
- dict.insert(QStringLiteral("properties"), collectProperties(o));
+ if (const QV4::String *s = value->as<QV4::String>()) {
+ dict.insert(valueKey, s->toQString());
+ } else if (const QV4::ArrayObject *a = value->as<QV4::ArrayObject>()) {
+ // size of an array is number of its numerical properties; We don't consider free form
+ // object properties here.
+ dict.insert(valueKey, qint64(a->getLength()));
+ return a;
+ } else if (const QV4::Object *o = value->as<QV4::Object>()) {
+ int numProperties = 0;
+ QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
+ QV4::PropertyAttributes attrs;
+ uint index;
+ QV4::ScopedProperty p(scope);
+ QV4::ScopedString name(scope);
+ while (true) {
+ it.next(name.getRef(), &index, p, &attrs);
+ if (attrs.isEmpty())
+ break;
+ else
+ ++numProperties;
+ }
+ dict.insert(valueKey, numProperties);
+ return o;
} else {
Q_UNREACHABLE();
}
- break;
+ return 0;
case QV4::Value::Integer_Type:
- dict.insert(QStringLiteral("type"), QStringLiteral("number"));
- dict.insert(QStringLiteral("value"), value->integerValue());
- break;
+ dict.insert(valueKey, value->integerValue());
+ return 0;
default: // double
- dict.insert(QStringLiteral("type"), QStringLiteral("number"));
- dict.insert(QStringLiteral("value"), value->doubleValue());
- break;
+ dict.insert(valueKey, value->doubleValue());
+ return 0;
}
+}
+
+QJsonObject QV4DataCollector::lookupRef(Ref ref)
+{
+ QJsonObject dict;
+ if (lookupSpecialRef(ref, &dict))
+ return dict;
+
+ dict.insert(QStringLiteral("handle"), qint64(ref));
+ QV4::Scope scope(engine());
+ QV4::ScopedValue value(scope, getValue(ref));
+
+ if (const QV4::Object *o = collectProperty(value, engine(), dict))
+ dict.insert(QStringLiteral("properties"), collectProperties(o));
return dict;
}
@@ -165,7 +193,6 @@ QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionNa
QJsonObject dict;
dict.insert(QStringLiteral("handle"), qint64(ref));
dict.insert(QStringLiteral("type"), QStringLiteral("function"));
- dict.insert(QStringLiteral("className"), QStringLiteral("Function"));
dict.insert(QStringLiteral("name"), functionName);
specialRefs.insert(ref, dict);
@@ -236,7 +263,7 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
QV4::ScopedObject array(scope, values.value());
if (deduplicate) {
for (Ref i = 0; i < array->getLength(); ++i) {
- if (array->getIndexed(i) == value.rawValue())
+ if (array->getIndexed(i) == value.rawValue() && !specialRefs.contains(i))
return i;
}
}
@@ -264,7 +291,7 @@ bool QV4DataCollector::lookupSpecialRef(Ref ref, QJsonObject *dict)
return true;
}
-QJsonArray QV4DataCollector::collectProperties(QV4::Object *object)
+QJsonArray QV4DataCollector::collectProperties(const QV4::Object *object)
{
QJsonArray res;
@@ -290,20 +317,14 @@ QJsonObject QV4DataCollector::collectAsJson(const QString &name, const QV4::Scop
QJsonObject dict;
if (!name.isNull())
dict.insert(QStringLiteral("name"), name);
- Ref ref = addRef(value);
- dict.insert(QStringLiteral("ref"), qint64(ref));
- if (m_collectedRefs)
- m_collectedRefs->append(ref);
-
- // TODO: enable this when creator can handle it.
- if (false) {
- if (value->isManaged() && !value->isString()) {
- QV4::Scope scope(engine());
- QV4::ScopedObject obj(scope, value->as<QV4::Object>());
- dict.insert(QStringLiteral("propertycount"), qint64(obj->getLength()));
- }
+ if (value->isManaged() && !value->isString()) {
+ Ref ref = addRef(value);
+ dict.insert(QStringLiteral("ref"), qint64(ref));
+ if (m_collectedRefs)
+ m_collectedRefs->append(ref);
}
+ collectProperty(value, engine(), dict);
return dict;
}
@@ -317,9 +338,16 @@ ExpressionEvalJob::ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr,
void ExpressionEvalJob::handleResult(QV4::ScopedValue &result)
{
+ if (hasExeption())
+ exception = result->toQStringNoThrow();
collector->collect(result);
}
+const QString &ExpressionEvalJob::exceptionMessage() const
+{
+ return exception;
+}
+
GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine, int seq)
: engine(engine)
, seq(seq)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index c91b77cb93..7d26d71bdf 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -72,7 +72,7 @@ private:
QV4::ReturnedValue getValue(Ref ref);
bool lookupSpecialRef(Ref ref, QJsonObject *dict);
- QJsonArray collectProperties(QV4::Object *object);
+ QJsonArray collectProperties(const QV4::Object *object);
QJsonObject collectAsJson(const QString &name, const QV4::ScopedValue &value);
void collectArgumentsInContext();
@@ -104,11 +104,13 @@ private:
class ExpressionEvalJob: public QV4::Debugging::Debugger::JavaScriptJob
{
QV4DataCollector *collector;
+ QString exception;
public:
ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, const QString &expression,
QV4DataCollector *collector);
virtual void handleResult(QV4::ScopedValue &result);
+ const QString &exceptionMessage() const;
};
class GatherSourcesJob: public QV4::Debugging::Debugger::Job
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 6b68f9518e..89820c9f56 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -549,31 +549,29 @@ public:
virtual void handleRequest()
{
- //decypher the payload:
- QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QString expression = arguments.value(QStringLiteral("expression")).toString();
- const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
-
QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- Q_ASSERT(debugger->state() == QV4::Debugging::Debugger::Paused);
-
- QV4DataCollector *collector = debugService->collector();
- QV4DataCollector::Refs refs;
- RefHolder holder(collector, &refs);
- Q_ASSERT(debugger->state() == QV4::Debugging::Debugger::Paused);
-
- ExpressionEvalJob job(debugger->engine(), frame, expression, collector);
- debugger->runInEngine(&job);
-
- Q_ASSERT(refs.size() == 1);
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(collector->lookupRef(refs.first()));
- addRefs();
+ if (debugger->state() == QV4::Debugging::Debugger::Paused) {
+ QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
+ QString expression = arguments.value(QStringLiteral("expression")).toString();
+ const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
+
+ QV4DataCollector *collector = debugService->collector();
+ RefHolder holder(collector, debugService->refs());
+ ExpressionEvalJob job(debugger->engine(), frame, expression, collector);
+ debugger->runInEngine(&job);
+ if (job.hasExeption()) {
+ createErrorResponse(job.exceptionMessage());
+ } else {
+ addCommand();
+ addRequestSequence();
+ addSuccess(true);
+ addRunning();
+ addBody(collector->lookupRef(debugService->refs()->last()));
+ addRefs();
+ }
+ } else {
+ createErrorResponse(QStringLiteral("Debugger has to be paused for evaluate to work."));
+ }
}
};
} // anonymous namespace
@@ -894,6 +892,11 @@ QV4DataCollector *QV4DebugServiceImpl::collector() const
return theCollector.data();
}
+QV4DataCollector::Refs *QV4DebugServiceImpl::refs()
+{
+ return &collectedRefs;
+}
+
void QV4DebugServiceImpl::selectFrame(int frameNr)
{
theSelectedFrame = frameNr;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
index c80ad78cc8..6c2950de8c 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
@@ -90,6 +90,7 @@ public:
QV4DataCollector *collector() const;
QV4DebuggerAgent debuggerAgent;
+ QV4DataCollector::Refs *refs();
protected:
void messageReceived(const QByteArray &);
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index 1cfebea03c..93e1d0c030 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -112,7 +112,6 @@ private:
QString m_pluginName;
int m_portFrom;
int m_portTo;
- bool m_block;
QString m_hostAddress;
QString m_fileName;
};