diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-24 21:13:41 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-24 21:14:07 +0200 |
commit | 922ca8c3a839ccbf3407bfe7e449bfceec5ecd23 (patch) | |
tree | f18c3702e1692c17ebe710530aba931c8a4554f6 /src/plugins | |
parent | 9c9fca5e27bd91da1ea07bebd7569049493c5ccf (diff) | |
parent | 9dd496c069154ac655be9b85b72a6eb409bfa223 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ic5aad89b014527d3dfd7ad9b1837e3c3065c5f4c
Diffstat (limited to 'src/plugins')
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; }; |