diff options
Diffstat (limited to 'src/qmldebug/qqmlenginedebugclient.cpp')
-rw-r--r-- | src/qmldebug/qqmlenginedebugclient.cpp | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/src/qmldebug/qqmlenginedebugclient.cpp b/src/qmldebug/qqmlenginedebugclient.cpp new file mode 100644 index 0000000000..910cc6ca67 --- /dev/null +++ b/src/qmldebug/qqmlenginedebugclient.cpp @@ -0,0 +1,545 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qqmlenginedebugclient_p_p.h" +#include <private/qqmldebugconnection_p.h> + +QT_BEGIN_NAMESPACE + +struct QQmlObjectData { + QUrl url; + qint32 lineNumber = -1; + qint32 columnNumber = -1; + QString idString; + QString objectName; + QString objectType; + qint32 objectId = -1; + qint32 contextId = -1; + qint32 parentId = -1; +}; + +QPacket &operator>>(QPacket &ds, QQmlObjectData &data) +{ + ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString + >> data.objectName >> data.objectType >> data.objectId >> data.contextId + >> data.parentId; + return ds; +} + +struct QQmlObjectProperty { + enum Type { Unknown, Basic, Object, List, SignalProperty }; + Type type = Unknown; + QString name; + QVariant value; + QString valueTypeName; + QString binding; + bool hasNotifySignal = false; +}; + +QPacket &operator>>(QPacket &ds, QQmlObjectProperty &data) +{ + qint32 type; + ds >> type >> data.name >> data.value >> data.valueTypeName + >> data.binding >> data.hasNotifySignal; + data.type = QQmlObjectProperty::Type(type); + return ds; +} + +QQmlEngineDebugClient::QQmlEngineDebugClient(QQmlDebugConnection *connection) : + QQmlDebugClient(*new QQmlEngineDebugClientPrivate(connection)) +{ +} + +QQmlEngineDebugClientPrivate::QQmlEngineDebugClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate (QLatin1String("QmlDebugger"), connection) +{ +} + + +qint32 QQmlEngineDebugClient::addWatch( + const QQmlEngineDebugPropertyReference &property, bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("WATCH_PROPERTY") << id << property.objectDebugId + << property.name.toUtf8(); + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::addWatch( + const QQmlEngineDebugContextReference &, const QString &, bool *success) +{ + *success = false; + qWarning("QQmlEngineDebugClient::addWatch(): Not implemented"); + return -1; +} + +qint32 QQmlEngineDebugClient::addWatch( + const QQmlEngineDebugObjectReference &object, const QString &expr, + bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.debugId << expr; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::addWatch( + const QQmlEngineDebugObjectReference &object, bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("WATCH_OBJECT") << id << object.debugId; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::addWatch( + const QQmlEngineDebugFileReference &, bool *success) +{ + *success = false; + qWarning("QQmlEngineDebugClient::addWatch(): Not implemented"); + return -1; +} + +void QQmlEngineDebugClient::removeWatch(qint32 id, bool *success) +{ + *success = false; + if (state() == QQmlDebugClient::Enabled) { + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("NO_WATCH") << id; + sendMessage(ds.data()); + *success = true; + } +} + +qint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->engines.clear(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("LIST_ENGINES") << id; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryRootContexts( + const QQmlEngineDebugEngineReference &engine, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->rootContext = QQmlEngineDebugContextReference(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("LIST_OBJECTS") << id << engine.debugId; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryObject( + const QQmlEngineDebugObjectReference &object, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->object = QQmlEngineDebugObjectReference(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false << true; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryObjectsForLocation( + const QString &file, qint32 lineNumber, qint32 columnNumber, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->objects.clear(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber + << columnNumber << false << true; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryObjectRecursive( + const QQmlEngineDebugObjectReference &object, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->object = QQmlEngineDebugObjectReference(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true << true; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &file, + qint32 lineNumber, qint32 columnNumber, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->objects.clear(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber + << columnNumber << true << true; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryExpressionResult( + qint32 objectDebugId, const QString &expr, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->exprResult = QVariant(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr + << engines()[0].debugId; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::queryExpressionResultBC( + qint32 objectDebugId, const QString &expr, bool *success) +{ + Q_D(QQmlEngineDebugClient); + d->exprResult = QVariant(); + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::setBindingForObject( + qint32 objectDebugId, + const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + const QString &source, qint32 line, + bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("SET_BINDING") << id << objectDebugId << propertyName + << bindingExpression << isLiteralValue << source << line; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::resetBindingForObject( + qint32 objectDebugId, + const QString &propertyName, + bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("RESET_BINDING") << id << objectDebugId << propertyName; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +qint32 QQmlEngineDebugClient::setMethodBody( + qint32 objectDebugId, const QString &methodName, + const QString &methodBody, bool *success) +{ + qint32 id = -1; + *success = false; + if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { + id = getId(); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("SET_METHOD_BODY") << id << objectDebugId + << methodName << methodBody; + sendMessage(ds.data()); + *success = true; + } + return id; +} + +void QQmlEngineDebugClient::decode(QPacket &ds, + QQmlEngineDebugObjectReference &o, + bool simple) +{ + QQmlObjectData data; + ds >> data; + o.debugId = data.objectId; + o.className = data.objectType; + o.idString = data.idString; + o.name = data.objectName; + o.source.url = data.url; + o.source.lineNumber = data.lineNumber; + o.source.columnNumber = data.columnNumber; + o.contextDebugId = data.contextId; + + if (simple) + return; + + qint32 childCount; + bool recur; + ds >> childCount >> recur; + + for (qint32 ii = 0; ii < childCount; ++ii) { + o.children.append(QQmlEngineDebugObjectReference()); + decode(ds, o.children.last(), !recur); + } + + qint32 propCount; + ds >> propCount; + + for (qint32 ii = 0; ii < propCount; ++ii) { + QQmlObjectProperty data; + ds >> data; + QQmlEngineDebugPropertyReference prop; + prop.objectDebugId = o.debugId; + prop.name = data.name; + prop.binding = data.binding; + prop.hasNotifySignal = data.hasNotifySignal; + prop.valueTypeName = data.valueTypeName; + switch (data.type) { + case QQmlObjectProperty::Basic: + case QQmlObjectProperty::List: + case QQmlObjectProperty::SignalProperty: + { + prop.value = data.value; + break; + } + case QQmlObjectProperty::Object: + { + QQmlEngineDebugObjectReference obj; + obj.name = data.value.toString(); + obj.className = prop.valueTypeName; + prop.value = QVariant::fromValue(obj); + break; + } + case QQmlObjectProperty::Unknown: + break; + } + o.properties << prop; + } +} + +void QQmlEngineDebugClient::decode(QPacket &ds, + QList<QQmlEngineDebugObjectReference> &o, + bool simple) +{ + qint32 count; + ds >> count; + for (qint32 i = 0; i < count; i++) { + QQmlEngineDebugObjectReference obj; + decode(ds, obj, simple); + o << obj; + } +} + +QList<QQmlEngineDebugEngineReference> QQmlEngineDebugClient::engines() const +{ + Q_D(const QQmlEngineDebugClient); + return d->engines; +} + +QQmlEngineDebugContextReference QQmlEngineDebugClient::rootContext() const +{ + Q_D(const QQmlEngineDebugClient); + return d->rootContext; +} + +QQmlEngineDebugObjectReference QQmlEngineDebugClient::object() const +{ + Q_D(const QQmlEngineDebugClient); + return d->object; +} + +QList<QQmlEngineDebugObjectReference> QQmlEngineDebugClient::objects() const +{ + Q_D(const QQmlEngineDebugClient); + return d->objects; +} + +QVariant QQmlEngineDebugClient::resultExpr() const +{ + Q_D(const QQmlEngineDebugClient); + return d->exprResult; +} + +bool QQmlEngineDebugClient::valid() const +{ + Q_D(const QQmlEngineDebugClient); + return d->valid; +} + +void QQmlEngineDebugClient::decode(QPacket &ds, + QQmlEngineDebugContextReference &c) +{ + ds >> c.name >> c.debugId; + + qint32 contextCount; + ds >> contextCount; + + for (qint32 ii = 0; ii < contextCount; ++ii) { + c.contexts.append(QQmlEngineDebugContextReference()); + decode(ds, c.contexts.last()); + } + + qint32 objectCount; + ds >> objectCount; + + for (qint32 ii = 0; ii < objectCount; ++ii) { + QQmlEngineDebugObjectReference obj; + decode(ds, obj, true); + + obj.contextDebugId = c.debugId; + c.objects << obj; + } +} + +void QQmlEngineDebugClient::messageReceived(const QByteArray &data) +{ + Q_D(QQmlEngineDebugClient); + d->valid = false; + QPacket ds(connection()->currentDataStreamVersion(), data); + + qint32 queryId; + QByteArray type; + ds >> type >> queryId; + + //qDebug() << "QQmlEngineDebugPrivate::message()" << type; + + if (type == "LIST_ENGINES_R") { + qint32 count; + ds >> count; + + d->engines.clear(); + for (qint32 ii = 0; ii < count; ++ii) { + QQmlEngineDebugEngineReference eng; + ds >> eng.name; + ds >> eng.debugId; + d->engines << eng; + } + } else if (type == "LIST_OBJECTS_R") { + if (!ds.atEnd()) + decode(ds, d->rootContext); + + } else if (type == "FETCH_OBJECT_R") { + if (!ds.atEnd()) + decode(ds, d->object, false); + + } else if (type == "FETCH_OBJECTS_FOR_LOCATION_R") { + if (!ds.atEnd()) + decode(ds, d->objects, false); + + } else if (type == "EVAL_EXPRESSION_R") {; + ds >> d->exprResult; + + } else if (type == "WATCH_PROPERTY_R") { + ds >> d->valid; + + } else if (type == "WATCH_OBJECT_R") { + ds >> d->valid; + + } else if (type == "WATCH_EXPR_OBJECT_R") { + ds >> d->valid; + + } else if (type == "UPDATE_WATCH") { + qint32 debugId; + QByteArray name; + QVariant value; + ds >> debugId >> name >> value; + emit valueChanged(name, value); + return; + + } else if (type == "OBJECT_CREATED") { + qint32 engineId; + qint32 objectId; + qint32 parentId; + ds >> engineId >> objectId >> parentId; + emit newObject(objectId); + return; + } else if (type == "SET_BINDING_R") { + ds >> d->valid; + } else if (type == "RESET_BINDING_R") { + ds >> d->valid; + } else if (type == "SET_METHOD_BODY_R") { + ds >> d->valid; + } else if (type == "NO_WATCH_R") { + ds >> d->valid; + } + emit result(); +} + + +qint32 QQmlEngineDebugClient::getId() +{ + Q_D(QQmlEngineDebugClient); + return d->nextId++; +} + +QT_END_NAMESPACE + +#include "moc_qqmlenginedebugclient_p.cpp" |