aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-10-16 14:06:49 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-10-23 11:56:14 +0000
commit33bfa05c59a0d4ebcc8943ff710ee1da207da014 (patch)
treed6b19ad41c37f1eeec4ad8cf68ea2b0e219b0d36
parentf06cbeb00b00e54826a67816663920cb468141a2 (diff)
QmlDebug: Add V4 debug client from tst_qqmldebugjs.cpp
This is useful for implementing additional V4 debug clients. Along the way, we also drop the dependency on QML by using the JSON API from QtCore for JSON manipulation. Task-number: QTBUG-66504 Change-Id: Ib51e8e97b030a49fe8185ad5354d1cca63efef4a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qmldebug/qmldebug.pro7
-rw-r--r--src/qmldebug/qv4debugclient.cpp578
-rw-r--r--src/qmldebug/qv4debugclient_p.h121
-rw-r--r--src/qmldebug/qv4debugclient_p_p.h80
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp898
6 files changed, 900 insertions, 786 deletions
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
index 0807482d23..42b73e5711 100644
--- a/src/qmldebug/qmldebug.pro
+++ b/src/qmldebug/qmldebug.pro
@@ -14,7 +14,8 @@ SOURCES += \
qqmlprofilerevent.cpp \
qqmlprofilereventlocation.cpp \
qqmlprofilereventtype.cpp \
- qqmlprofilertypedevent.cpp
+ qqmlprofilertypedevent.cpp \
+ qv4debugclient.cpp
HEADERS += \
qqmldebugclient_p.h \
@@ -32,4 +33,6 @@ HEADERS += \
qqmlprofilereventreceiver_p.h \
qqmlprofilereventtype_p.h \
qqmlprofilertypedevent_p.h \
- qqmlprofilerclientdefinitions_p.h
+ qqmlprofilerclientdefinitions_p.h \
+ qv4debugclient_p.h \
+ qv4debugclient_p_p.h
diff --git a/src/qmldebug/qv4debugclient.cpp b/src/qmldebug/qv4debugclient.cpp
new file mode 100644
index 0000000000..76c2f1ebea
--- /dev/null
+++ b/src/qmldebug/qv4debugclient.cpp
@@ -0,0 +1,578 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4debugclient_p.h"
+#include "qv4debugclient_p_p.h"
+#include "qqmldebugconnection_p.h"
+
+#include <private/qpacket_p.h>
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonArray>
+
+QT_BEGIN_NAMESPACE
+
+const char *V8REQUEST = "v8request";
+const char *V8MESSAGE = "v8message";
+const char *SEQ = "seq";
+const char *TYPE = "type";
+const char *COMMAND = "command";
+const char *ARGUMENTS = "arguments";
+const char *STEPACTION = "stepaction";
+const char *STEPCOUNT = "stepcount";
+const char *EXPRESSION = "expression";
+const char *FRAME = "frame";
+const char *CONTEXT = "context";
+const char *GLOBAL = "global";
+const char *DISABLEBREAK = "disable_break";
+const char *HANDLES = "handles";
+const char *INCLUDESOURCE = "includeSource";
+const char *FROMFRAME = "fromFrame";
+const char *TOFRAME = "toFrame";
+const char *BOTTOM = "bottom";
+const char *NUMBER = "number";
+const char *FRAMENUMBER = "frameNumber";
+const char *TYPES = "types";
+const char *IDS = "ids";
+const char *FILTER = "filter";
+const char *FROMLINE = "fromLine";
+const char *TOLINE = "toLine";
+const char *TARGET = "target";
+const char *LINE = "line";
+const char *COLUMN = "column";
+const char *ENABLED = "enabled";
+const char *CONDITION = "condition";
+const char *IGNORECOUNT = "ignoreCount";
+const char *BREAKPOINT = "breakpoint";
+const char *FLAGS = "flags";
+
+const char *CONTINEDEBUGGING = "continue";
+const char *EVALUATE = "evaluate";
+const char *LOOKUP = "lookup";
+const char *BACKTRACE = "backtrace";
+const char *SCOPE = "scope";
+const char *SCOPES = "scopes";
+const char *SCRIPTS = "scripts";
+const char *SOURCE = "source";
+const char *SETBREAKPOINT = "setbreakpoint";
+const char *CLEARBREAKPOINT = "clearbreakpoint";
+const char *CHANGEBREAKPOINT = "changebreakpoint";
+const char *SETEXCEPTIONBREAK = "setexceptionbreak";
+const char *VERSION = "version";
+const char *DISCONNECT = "disconnect";
+const char *GARBAGECOLLECTOR = "gc";
+
+const char *CONNECT = "connect";
+const char *INTERRUPT = "interrupt";
+
+const char *REQUEST = "request";
+const char *IN = "in";
+const char *NEXT = "next";
+const char *OUT = "out";
+
+const char *SCRIPT = "script";
+const char *SCRIPTREGEXP = "scriptRegExp";
+const char *EVENT = "event";
+
+const char *ALL = "all";
+const char *UNCAUGHT = "uncaught";
+
+#define VARIANTMAPINIT \
+ Q_D(QV4DebugClient); \
+ QJsonObject jsonVal; \
+ jsonVal.insert(QLatin1String(SEQ), d->seq++); \
+ jsonVal.insert(QLatin1String(TYPE), QLatin1String(REQUEST));
+
+QV4DebugClient::QV4DebugClient(QQmlDebugConnection *connection)
+ : QQmlDebugClient(*new QV4DebugClientPrivate(connection))
+{
+ QObject::connect(this, &QQmlDebugClient::stateChanged,
+ this, [this](State state) { d_func()->onStateChanged(state); });
+}
+
+QV4DebugClientPrivate::QV4DebugClientPrivate(QQmlDebugConnection *connection) :
+ QQmlDebugClientPrivate(QLatin1String("V8Debugger"), connection)
+{
+}
+
+void QV4DebugClient::connect()
+{
+ Q_D(QV4DebugClient);
+ d->sendMessage(CONNECT);
+}
+
+void QV4DebugClient::interrupt()
+{
+ Q_D(QV4DebugClient);
+ d->sendMessage(INTERRUPT);
+}
+
+void QV4DebugClient::continueDebugging(StepAction action)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "continue",
+ // "arguments" : { "stepaction" : <"in", "next" or "out">,
+ // "stepcount" : <number of steps (default 1)>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CONTINEDEBUGGING));
+
+ if (action != Continue) {
+ QJsonObject args;
+ switch (action) {
+ case In:
+ args.insert(QLatin1String(STEPACTION), QLatin1String(IN));
+ break;
+ case Out:
+ args.insert(QLatin1String(STEPACTION), QLatin1String(OUT));
+ break;
+ case Next:
+ args.insert(QLatin1String(STEPACTION), QLatin1String(NEXT));
+ break;
+ default:
+ break;
+ }
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ }
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::evaluate(const QString &expr, int frame, int context)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "evaluate",
+ // "arguments" : { "expression" : <expression to evaluate>,
+ // "frame" : <number>,
+ // "context" : <object ID>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(EVALUATE));
+
+ QJsonObject args;
+ args.insert(QLatin1String(EXPRESSION), expr);
+
+ if (frame != -1)
+ args.insert(QLatin1String(FRAME), frame);
+
+ if (context != -1)
+ args.insert(QLatin1String(CONTEXT), context);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::lookup(const QList<int> &handles, bool includeSource)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "lookup",
+ // "arguments" : { "handles" : <array of handles>,
+ // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND),(QLatin1String(LOOKUP)));
+
+ QJsonObject args;
+ QJsonArray array;
+
+ for (int handle : handles)
+ array.append(handle);
+
+ args.insert(QLatin1String(HANDLES), array);
+
+ if (includeSource)
+ args.insert(QLatin1String(INCLUDESOURCE), includeSource);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "backtrace",
+ // "arguments" : { "fromFrame" : <number>
+ // "toFrame" : <number>
+ // "bottom" : <boolean, set to true if the bottom of the stack is requested>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(BACKTRACE));
+
+ QJsonObject args;
+
+ if (fromFrame != -1)
+ args.insert(QLatin1String(FROMFRAME), fromFrame);
+
+ if (toFrame != -1)
+ args.insert(QLatin1String(TOFRAME), toFrame);
+
+ if (bottom)
+ args.insert(QLatin1String(BOTTOM), bottom);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::frame(int number)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "frame",
+ // "arguments" : { "number" : <frame number>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(FRAME));
+
+ if (number != -1) {
+ QJsonObject args;
+ args.insert(QLatin1String(NUMBER), number);
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ }
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::scope(int number, int frameNumber)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "scope",
+ // "arguments" : { "number" : <scope number>
+ // "frameNumber" : <frame number, optional uses selected frame if missing>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SCOPE));
+
+ if (number != -1) {
+ QJsonObject args;
+ args.insert(QLatin1String(NUMBER), number);
+
+ if (frameNumber != -1)
+ args.insert(QLatin1String(FRAMENUMBER), frameNumber);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ }
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::scripts(int types, const QList<int> &ids, bool includeSource)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "scripts",
+ // "arguments" : { "types" : <types of scripts to retrieve
+ // set bit 0 for native scripts
+ // set bit 1 for extension scripts
+ // set bit 2 for normal scripts
+ // (default is 4 for normal scripts)>
+ // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
+ // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
+ // "filter" : <string or number: filter string or script id.
+ // If a number is specified, then only the script with the same number as its script id will be retrieved.
+ // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SCRIPTS));
+
+ QJsonObject args;
+ args.insert(QLatin1String(TYPES), types);
+
+ if (ids.count()) {
+ QJsonArray array;
+ for (int id : ids)
+ array.append(id);
+
+ args.insert(QLatin1String(IDS), array);
+ }
+
+ if (includeSource)
+ args.insert(QLatin1String(INCLUDESOURCE), includeSource);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::setBreakpoint(const QString &target, int line, int column, bool enabled,
+ const QString &condition, int ignoreCount)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "setbreakpoint",
+ // "arguments" : { "type" : "scriptRegExp"
+ // "target" : <function expression or script identification>
+ // "line" : <line in script or function>
+ // "column" : <character position within the line>
+ // "enabled" : <initial enabled state. True or false, default is true>
+ // "condition" : <string with break point condition>
+ // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
+ // }
+ // }
+
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SETBREAKPOINT));
+
+ QJsonObject args;
+
+ args.insert(QLatin1String(TYPE), QLatin1String(SCRIPTREGEXP));
+ args.insert(QLatin1String(TARGET), target);
+
+ if (line != -1)
+ args.insert(QLatin1String(LINE), line);
+
+ if (column != -1)
+ args.insert(QLatin1String(COLUMN), column);
+
+ args.insert(QLatin1String(ENABLED), enabled);
+
+ if (!condition.isEmpty())
+ args.insert(QLatin1String(CONDITION), condition);
+
+ if (ignoreCount != -1)
+ args.insert(QLatin1String(IGNORECOUNT), ignoreCount);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS),args);
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::clearBreakpoint(int breakpoint)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "clearbreakpoint",
+ // "arguments" : { "breakpoint" : <number of the break point to clear>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CLEARBREAKPOINT));
+
+ QJsonObject args;
+ args.insert(QLatin1String(BREAKPOINT), breakpoint);
+ jsonVal.insert(QLatin1String(ARGUMENTS),args);
+
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::changeBreakpoint(int breakpoint, bool enabled)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "changebreakpoint",
+ // "arguments" : { "breakpoint" : <number of the break point to change>
+ // "enabled" : <bool: enables the break type if true, disables if false>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(CHANGEBREAKPOINT));
+
+ QJsonObject args;
+ args.insert(QLatin1String(BREAKPOINT), breakpoint);
+ args.insert(QLatin1String(ENABLED), enabled);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::setExceptionBreak(Exception type, bool enabled)
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "setexceptionbreak",
+ // "arguments" : { "type" : <string: "all", or "uncaught">,
+ // "enabled" : <optional bool: enables the break type if true>
+ // }
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(SETEXCEPTIONBREAK));
+
+ QJsonObject args;
+
+ if (type == All)
+ args.insert(QLatin1String(TYPE), QLatin1String(ALL));
+ else if (type == Uncaught)
+ args.insert(QLatin1String(TYPE), QLatin1String(UNCAUGHT));
+
+ if (enabled)
+ args.insert(QLatin1String(ENABLED), enabled);
+
+ jsonVal.insert(QLatin1String(ARGUMENTS), args);
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+void QV4DebugClient::version()
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "version",
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(VERSION));
+ d->sendMessage(V8REQUEST, jsonVal);
+}
+
+QV4DebugClient::Response QV4DebugClient::response() const
+{
+ Q_D(const QV4DebugClient);
+ const QJsonObject value = QJsonDocument::fromJson(d->response).object();
+ return {
+ value.value(QLatin1String(COMMAND)).toString(),
+ value.value(QLatin1String("body"))
+ };
+}
+
+void QV4DebugClient::disconnect()
+{
+ // { "seq" : <number>,
+ // "type" : "request",
+ // "command" : "disconnect",
+ // }
+ VARIANTMAPINIT;
+ jsonVal.insert(QLatin1String(COMMAND), QLatin1String(DISCONNECT));
+ d->sendMessage(DISCONNECT, jsonVal);
+}
+
+void QV4DebugClientPrivate::onStateChanged(QQmlDebugClient::State state)
+{
+ if (state == QQmlDebugClient::Enabled)
+ flushSendBuffer();
+}
+
+void QV4DebugClient::messageReceived(const QByteArray &data)
+{
+ Q_D(QV4DebugClient);
+ QPacket ds(connection()->currentDataStreamVersion(), data);
+ QByteArray command;
+ ds >> command;
+
+ if (command == "V8DEBUG") {
+ QByteArray type;
+ ds >> type >> d->response;
+
+ if (type == CONNECT) {
+ emit connected();
+
+ } else if (type == INTERRUPT) {
+ emit interrupted();
+
+ } else if (type == V8MESSAGE) {
+ const QJsonObject value = QJsonDocument::fromJson(d->response).object();
+ QString type = value.value(QLatin1String(TYPE)).toString();
+
+ if (type == QLatin1String("response")) {
+
+ if (!value.value(QLatin1String("success")).toBool()) {
+ emit failure();
+ qDebug() << "Received success == false response from application:"
+ << value.value(QLatin1String("message")).toString();
+ return;
+ }
+
+ QString debugCommand(value.value(QLatin1String(COMMAND)).toString());
+ if (debugCommand == QLatin1String(BACKTRACE) ||
+ debugCommand == QLatin1String(LOOKUP) ||
+ debugCommand == QLatin1String(SETBREAKPOINT) ||
+ debugCommand == QLatin1String(EVALUATE) ||
+ debugCommand == QLatin1String(VERSION) ||
+ debugCommand == QLatin1String(DISCONNECT) ||
+ debugCommand == QLatin1String(GARBAGECOLLECTOR) ||
+ debugCommand == QLatin1String(CHANGEBREAKPOINT) ||
+ debugCommand == QLatin1String(CLEARBREAKPOINT) ||
+ debugCommand == QLatin1String(FRAME) ||
+ debugCommand == QLatin1String(SCOPE) ||
+ debugCommand == QLatin1String(SCOPES) ||
+ debugCommand == QLatin1String(SCRIPTS) ||
+ debugCommand == QLatin1String(SOURCE) ||
+ debugCommand == QLatin1String(SETEXCEPTIONBREAK)) {
+ emit result();
+ } else {
+ // DO NOTHING
+ }
+
+ } else if (type == QLatin1String(EVENT)) {
+ QString event(value.value(QLatin1String(EVENT)).toString());
+
+ if (event == QLatin1String("break") || event == QLatin1String("exception"))
+ emit stopped();
+ }
+ }
+ }
+}
+
+void QV4DebugClientPrivate::sendMessage(const QByteArray &command, const QJsonObject &args)
+{
+ Q_Q(QV4DebugClient);
+ const QByteArray msg = packMessage(command, args);
+ if (q->state() == QQmlDebugClient::Enabled) {
+ q->sendMessage(msg);
+ } else {
+ sendBuffer.append(msg);
+ }
+}
+
+void QV4DebugClientPrivate::flushSendBuffer()
+{
+ foreach (const QByteArray &msg, sendBuffer)
+ sendMessage(msg);
+ sendBuffer.clear();
+}
+
+QByteArray QV4DebugClientPrivate::packMessage(const QByteArray &type, const QJsonObject &object)
+{
+ QPacket rs(connection->currentDataStreamVersion());
+ QByteArray cmd = "V8DEBUG";
+ rs << cmd << type << QJsonDocument(object).toJson(QJsonDocument::Compact);
+ return rs.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qv4debugclient_p.h b/src/qmldebug/qv4debugclient_p.h
new file mode 100644
index 0000000000..fdcf4284c5
--- /dev/null
+++ b/src/qmldebug/qv4debugclient_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4DEBUGCLIENT_P_H
+#define QV4DEBUGCLIENT_P_H
+
+#include <QtQmlDebug/private/qqmldebugclient_p.h>
+#include <QtCore/qjsonvalue.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QV4DebugClientPrivate;
+class QV4DebugClient : public QQmlDebugClient
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QV4DebugClient)
+
+public:
+ enum StepAction
+ {
+ Continue,
+ In,
+ Out,
+ Next
+ };
+
+ enum Exception
+ {
+ All,
+ Uncaught
+ };
+
+ struct Response
+ {
+ QString command;
+ QJsonValue body;
+ };
+
+ QV4DebugClient(QQmlDebugConnection *connection);
+
+ void connect();
+ void disconnect();
+
+ void interrupt();
+ void continueDebugging(StepAction stepAction);
+ void evaluate(const QString &expr, int frame = -1, int context = -1);
+ void lookup(const QList<int> &handles, bool includeSource = false);
+ void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
+ void frame(int number = -1);
+ void scope(int number = -1, int frameNumber = -1);
+ void scripts(int types = 4, const QList<int> &ids = QList<int>(), bool includeSource = false);
+ void setBreakpoint(const QString &target, int line = -1, int column = -1, bool enabled = true,
+ const QString &condition = QString(), int ignoreCount = -1);
+ void clearBreakpoint(int breakpoint);
+ void changeBreakpoint(int breakpoint, bool enabled);
+ void setExceptionBreak(Exception type, bool enabled = false);
+ void version();
+
+ Response response() const;
+
+protected:
+ void messageReceived(const QByteArray &data) override;
+
+signals:
+ void connected();
+ void interrupted();
+ void result();
+ void failure();
+ void stopped();
+};
+
+QT_END_NAMESPACE
+
+#endif // QV4DEBUGCLIENT_P_H
diff --git a/src/qmldebug/qv4debugclient_p_p.h b/src/qmldebug/qv4debugclient_p_p.h
new file mode 100644
index 0000000000..993c281632
--- /dev/null
+++ b/src/qmldebug/qv4debugclient_p_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4DEBUGCLIENT_P_P_H
+#define QV4DEBUGCLIENT_P_P_H
+
+#include "qv4debugclient_p.h"
+#include "qqmldebugclient_p_p.h"
+
+#include <QtCore/qjsonobject.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QV4DebugClientPrivate : public QQmlDebugClientPrivate
+{
+ Q_DECLARE_PUBLIC(QV4DebugClient)
+
+public:
+ QV4DebugClientPrivate(QQmlDebugConnection *connection);
+
+ void sendMessage(const QByteArray &command, const QJsonObject &args = QJsonObject());
+ void flushSendBuffer();
+ QByteArray packMessage(const QByteArray &type, const QJsonObject &object);
+ void onStateChanged(QQmlDebugClient::State state);
+
+ int seq = 0;
+ QList<QByteArray> sendBuffer;
+ QByteArray response;
+};
+
+QT_END_NAMESPACE
+
+#endif // QV4DEBUGCLIENT_P_P_H
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
index 8fef435d98..2a32fa445b 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qqmldebugjs
-QT += qml testlib gui-private core-private
+QT += testlib gui-private core-private
macos:CONFIG -= app_bundle
SOURCES += tst_qqmldebugjs.cpp
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
index 941303d3ef..79a1e56a41 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -31,7 +31,7 @@
#include "../shared/qqmlenginedebugclient.h"
#include "../../../shared/util.h"
-#include <private/qqmldebugclient_p.h>
+#include <private/qv4debugclient_p.h>
#include <private/qqmldebugconnection_p.h>
#include <private/qpacket_p.h>
@@ -43,72 +43,8 @@
#include <QtCore/qdir.h>
#include <QtCore/qmutex.h>
#include <QtCore/qlibraryinfo.h>
-#include <QtQml/qjsengine.h>
-
-const char *V8REQUEST = "v8request";
-const char *V8MESSAGE = "v8message";
-const char *SEQ = "seq";
-const char *TYPE = "type";
-const char *COMMAND = "command";
-const char *ARGUMENTS = "arguments";
-const char *STEPACTION = "stepaction";
-const char *STEPCOUNT = "stepcount";
-const char *EXPRESSION = "expression";
-const char *FRAME = "frame";
-const char *CONTEXT = "context";
-const char *GLOBAL = "global";
-const char *DISABLEBREAK = "disable_break";
-const char *HANDLES = "handles";
-const char *INCLUDESOURCE = "includeSource";
-const char *FROMFRAME = "fromFrame";
-const char *TOFRAME = "toFrame";
-const char *BOTTOM = "bottom";
-const char *NUMBER = "number";
-const char *FRAMENUMBER = "frameNumber";
-const char *TYPES = "types";
-const char *IDS = "ids";
-const char *FILTER = "filter";
-const char *FROMLINE = "fromLine";
-const char *TOLINE = "toLine";
-const char *TARGET = "target";
-const char *LINE = "line";
-const char *COLUMN = "column";
-const char *ENABLED = "enabled";
-const char *CONDITION = "condition";
-const char *IGNORECOUNT = "ignoreCount";
-const char *BREAKPOINT = "breakpoint";
-const char *FLAGS = "flags";
-
-const char *CONTINEDEBUGGING = "continue";
-const char *EVALUATE = "evaluate";
-const char *LOOKUP = "lookup";
-const char *BACKTRACE = "backtrace";
-const char *SCOPE = "scope";
-const char *SCOPES = "scopes";
-const char *SCRIPTS = "scripts";
-const char *SOURCE = "source";
-const char *SETBREAKPOINT = "setbreakpoint";
-const char *CLEARBREAKPOINT = "clearbreakpoint";
-const char *CHANGEBREAKPOINT = "changebreakpoint";
-const char *SETEXCEPTIONBREAK = "setexceptionbreak";
-const char *VERSION = "version";
-const char *DISCONNECT = "disconnect";
-const char *GARBAGECOLLECTOR = "gc";
-
-const char *CONNECT = "connect";
-const char *INTERRUPT = "interrupt";
-
-const char *REQUEST = "request";
-const char *IN = "in";
-const char *NEXT = "next";
-const char *OUT = "out";
-
-const char *SCRIPT = "script";
-const char *SCRIPTREGEXP = "scriptRegExp";
-const char *EVENT = "event";
-
-const char *ALL = "all";
-const char *UNCAUGHT = "uncaught";
+#include <QtCore/qjsonobject.h>
+#include <QtCore/qjsonarray.h>
const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block";
const char *NORMALMODE = "-qmljsdebugger=port:3771,3800";
@@ -129,13 +65,6 @@ const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
const char *ENCODEQMLSCOPE_QMLFILE = "encodeQmlScope.qml";
const char *BREAKONANCHOR_QMLFILE = "breakOnAnchor.qml";
-#define VARIANTMAPINIT \
- QString obj("{}"); \
- QJSValue jsonVal = parser.call(QJSValueList() << obj); \
- jsonVal.setProperty(SEQ,QJSValue(seq++)); \
- jsonVal.setProperty(TYPE,REQUEST);
-
-
#undef QVERIFY
#define QVERIFY(statement) \
do {\
@@ -146,9 +75,6 @@ do {\
}\
} while (0)
-
-class QJSDebugClient;
-
class tst_QQmlDebugJS : public QQmlDebugTest
{
Q_OBJECT
@@ -231,7 +157,7 @@ private:
ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE),
bool blockMode = true, bool restrictServices = false);
QList<QQmlDebugClient *> createClients() override;
- QPointer<QJSDebugClient> m_client;
+ QPointer<QV4DebugClient> m_client;
void targetData();
bool waitForClientSignal(const char *signal, int timeout = 30000);
@@ -240,555 +166,7 @@ private:
QTime t;
};
-class QJSDebugClient : public QQmlDebugClient
-{
- Q_OBJECT
-public:
- enum StepAction
- {
- Continue,
- In,
- Out,
- Next
- };
-
- enum Exception
- {
- All,
- Uncaught
- };
-
- QJSDebugClient(QQmlDebugConnection *connection)
- : QQmlDebugClient(QLatin1String("V8Debugger"), connection),
- seq(0)
- {
- parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
- stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
- QObject::connect(this, &QQmlDebugClient::stateChanged,
- this, &QJSDebugClient::onStateChanged);
- }
-
- void connect();
- void interrupt();
-
- void continueDebugging(StepAction stepAction);
- void evaluate(QString expr, int frame = -1, int context = -1);
- void lookup(QList<int> handles, bool includeSource = false);
- void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
- void frame(int number = -1);
- void scope(int number = -1, int frameNumber = -1);
- void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
- void setBreakpoint(QString target, int line = -1, int column = -1, bool enabled = true,
- QString condition = QString(), int ignoreCount = -1);
- void clearBreakpoint(int breakpoint);
- void changeBreakpoint(int breakpoint, bool enabled);
- void setExceptionBreak(Exception type, bool enabled = false);
- void version();
- void disconnect();
-
-protected:
- //inherited from QQmlDebugClient
- void onStateChanged(State state);
- void messageReceived(const QByteArray &data);
-
-signals:
- void connected();
- void interruptRequested();
- void result();
- void failure();
- void stopped();
-
-private:
- void sendMessage(const QByteArray &);
- void flushSendBuffer();
- QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray());
-
-private:
- QJSEngine jsEngine;
- int seq;
-
- QList<QByteArray> sendBuffer;
-public:
- QJSValue parser;
- QJSValue stringify;
- QByteArray response;
-
-};
-
-void QJSDebugClient::connect()
-{
- const QJSValue jsonVal = parser.call(QJSValueList() << QLatin1String("{}"));
- sendMessage(packMessage(CONNECT,
- stringify.call(QJSValueList() << jsonVal).toString().toUtf8()));
-}
-
-void QJSDebugClient::interrupt()
-{
- sendMessage(packMessage(INTERRUPT));
-}
-
-void QJSDebugClient::continueDebugging(StepAction action)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "continue",
- // "arguments" : { "stepaction" : <"in", "next" or "out">,
- // "stepcount" : <number of steps (default 1)>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
-
- if (action != Continue) {
- QJSValue args = parser.call(QJSValueList() << obj);
- switch (action) {
- case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
- break;
- case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
- break;
- case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
- break;
- default:break;
- }
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::evaluate(QString expr, int frame, int context)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "evaluate",
- // "arguments" : { "expression" : <expression to evaluate>,
- // "frame" : <number>,
- // "context" : <object ID>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
-
- if (frame != -1)
- args.setProperty(QLatin1String(FRAME),QJSValue(frame));
-
- if (context != -1)
- args.setProperty(QLatin1String(CONTEXT), QJSValue(context));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "lookup",
- // "arguments" : { "handles" : <array of handles>,
- // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- QString arr("[]");
- QJSValue array = parser.call(QJSValueList() << arr);
- int index = 0;
- foreach (int handle, handles) {
- array.setProperty(index++,QJSValue(handle));
- }
- args.setProperty(QLatin1String(HANDLES),array);
-
- if (includeSource)
- args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "backtrace",
- // "arguments" : { "fromFrame" : <number>
- // "toFrame" : <number>
- // "bottom" : <boolean, set to true if the bottom of the stack is requested>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- if (fromFrame != -1)
- args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
-
- if (toFrame != -1)
- args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
-
- if (bottom)
- args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::frame(int number)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "frame",
- // "arguments" : { "number" : <frame number>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
-
- if (number != -1) {
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(NUMBER),QJSValue(number));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::scope(int number, int frameNumber)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "scope",
- // "arguments" : { "number" : <scope number>
- // "frameNumber" : <frame number, optional uses selected frame if missing>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
-
- if (number != -1) {
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(NUMBER),QJSValue(number));
-
- if (frameNumber != -1)
- args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "scripts",
- // "arguments" : { "types" : <types of scripts to retrieve
- // set bit 0 for native scripts
- // set bit 1 for extension scripts
- // set bit 2 for normal scripts
- // (default is 4 for normal scripts)>
- // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
- // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
- // "filter" : <string or number: filter string or script id.
- // If a number is specified, then only the script with the same number as its script id will be retrieved.
- // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(TYPES),QJSValue(types));
-
- if (ids.count()) {
- QString arr("[]");
- QJSValue array = parser.call(QJSValueList() << arr);
- int index = 0;
- foreach (int id, ids) {
- array.setProperty(index++,QJSValue(id));
- }
- args.setProperty(QLatin1String(IDS),array);
- }
-
- if (includeSource)
- args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::setBreakpoint(QString target, int line, int column, bool enabled,
- QString condition, int ignoreCount)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "setbreakpoint",
- // "arguments" : { "type" : "scriptRegExp"
- // "target" : <function expression or script identification>
- // "line" : <line in script or function>
- // "column" : <character position within the line>
- // "enabled" : <initial enabled state. True or false, default is true>
- // "condition" : <string with break point condition>
- // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
- // }
- // }
-
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(SCRIPTREGEXP)));
- args.setProperty(QLatin1String(TARGET),QJSValue(target));
-
- if (line != -1)
- args.setProperty(QLatin1String(LINE),QJSValue(line));
-
- if (column != -1)
- args.setProperty(QLatin1String(COLUMN),QJSValue(column));
-
- args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
-
- if (!condition.isEmpty())
- args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
-
- if (ignoreCount != -1)
- args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::clearBreakpoint(int breakpoint)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "clearbreakpoint",
- // "arguments" : { "breakpoint" : <number of the break point to clear>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "changebreakpoint",
- // "arguments" : { "breakpoint" : <number of the break point to change>
- // "enabled" : <bool: enables the break type if true, disables if false>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND), QLatin1String(CHANGEBREAKPOINT));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- args.setProperty(QLatin1String(BREAKPOINT), breakpoint);
- args.setProperty(QLatin1String(ENABLED), enabled);
- jsonVal.setProperty(QLatin1String(ARGUMENTS), args);
-
- const QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "setexceptionbreak",
- // "arguments" : { "type" : <string: "all", or "uncaught">,
- // "enabled" : <optional bool: enables the break type if true>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- if (type == All)
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
- else if (type == Uncaught)
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
-
- if (enabled)
- args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::version()
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "version",
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::disconnect()
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "disconnect",
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(DISCONNECT, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::onStateChanged(State state)
-{
- if (state == Enabled)
- flushSendBuffer();
-}
-
-void QJSDebugClient::messageReceived(const QByteArray &data)
-{
- QPacket ds(connection()->currentDataStreamVersion(), data);
- QByteArray command;
- ds >> command;
-
- if (command == "V8DEBUG") {
- QByteArray type;
- ds >> type >> response;
-
- if (type == CONNECT) {
- emit connected();
-
- } else if (type == INTERRUPT) {
- emit interruptRequested();
-
- } else if (type == V8MESSAGE) {
- QString jsonString(response);
- QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QString type = value.value("type").toString();
-
- if (type == "response") {
-
- if (!value.value("success").toBool()) {
- emit failure();
- qDebug() << "Received success == false response from application:"
- << value.value("message").toString();
- return;
- }
-
- QString debugCommand(value.value("command").toString());
- if (debugCommand == "backtrace" ||
- debugCommand == "lookup" ||
- debugCommand == "setbreakpoint" ||
- debugCommand == "evaluate" ||
- debugCommand == "version" ||
- debugCommand == "disconnect" ||
- debugCommand == "gc" ||
- debugCommand == "changebreakpoint" ||
- debugCommand == "clearbreakpoint" ||
- debugCommand == "frame" ||
- debugCommand == "scope" ||
- debugCommand == "scopes" ||
- debugCommand == "scripts" ||
- debugCommand == "source" ||
- debugCommand == "setexceptionbreak" /*||
- debugCommand == "profile"*/) {
- emit result();
- } else {
- // DO NOTHING
- }
-
- } else if (type == QLatin1String(EVENT)) {
- QString event(value.value(QLatin1String(EVENT)).toString());
-
- if (event == "break" ||
- event == "exception")
- emit stopped();
- }
-
- }
- }
-}
-
-void QJSDebugClient::sendMessage(const QByteArray &msg)
-{
- if (state() == Enabled) {
- QQmlDebugClient::sendMessage(msg);
- } else {
- sendBuffer.append(msg);
- }
-}
-
-void QJSDebugClient::flushSendBuffer()
-{
- foreach (const QByteArray &msg, sendBuffer)
- QQmlDebugClient::sendMessage(msg);
- sendBuffer.clear();
-}
-
-QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
-{
- QPacket rs(connection()->currentDataStreamVersion());
- QByteArray cmd = "V8DEBUG";
- rs << cmd << type << message;
- return rs.data();
-}
void tst_QQmlDebugJS::initTestCase()
{
@@ -842,7 +220,7 @@ void tst_QQmlDebugJS::interrupt()
m_client->connect();
m_client->interrupt();
- QVERIFY(waitForClientSignal(SIGNAL(interruptRequested())));
+ QVERIFY(waitForClientSignal(SIGNAL(interrupted())));
}
void tst_QQmlDebugJS::getVersion()
@@ -896,13 +274,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(ONCOMPLETED_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
@@ -917,13 +293,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(ONCOMPLETED_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
@@ -939,13 +313,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(TIMER_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
@@ -960,13 +332,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(TEST_JSFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
@@ -983,13 +353,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
@@ -1006,13 +374,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
@@ -1027,13 +393,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
}
void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
@@ -1050,11 +414,8 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
//Get the frame index
- QString jsonString = m_client->response;
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
{
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
int frameIndex = body.value("index").toInt();
//Verify the value of 'result'
@@ -1062,13 +423,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
QVERIFY(waitForClientSignal(SIGNAL(result())));
}
- jsonString = m_client->response;
- QJSValue val = m_client->parser.call(QJSValueList() << QJSValue(jsonString));
- QVERIFY(val.isObject());
- QJSValue body = val.property(QStringLiteral("body"));
- QVERIFY(body.isObject());
- val = body.property("value");
- QVERIFY(val.isNumber());
+ const QJsonObject body = m_client->response().body.toObject();
+ QVERIFY(!body.isEmpty());
+ QJsonValue val = body.value("value");
+ QVERIFY(val.isDouble());
const int a = val.toInt();
QVERIFY(a > out);
@@ -1086,15 +444,12 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
- m_client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QV4DebugClient::Continue);
QVERIFY(m_process->waitForFinished());
QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
@@ -1134,34 +489,32 @@ void tst_QQmlDebugJS::clearBreakpoint()
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- //Will hit 1st brakpoint, change this breakpoint enable = false
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ {
+ //Will hit 1st brakpoint, change this breakpoint enable = false
+ const QJsonObject body = m_client->response().body.toObject();
+ const QJsonArray breakpointsHit = body.value("breakpoints").toArray();
- QVariantMap body = value.value("body").toMap();
- QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
+ int breakpoint = breakpointsHit.at(0).toInt();
+ m_client->clearBreakpoint(breakpoint);
- int breakpoint = breakpointsHit.at(0).toInt();
- m_client->clearBreakpoint(breakpoint);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
- QVERIFY(waitForClientSignal(SIGNAL(result())));
+ //Continue with debugging
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ //Hit 2nd breakpoint
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- //Continue with debugging
- m_client->continueDebugging(QJSDebugClient::Continue);
- //Hit 2nd breakpoint
- QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+ //Continue with debugging
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ }
- //Continue with debugging
- m_client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- jsonString = m_client->response;
- value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
+ {
+ const QJsonObject body = m_client->response().body.toObject();
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
+ }
}
void tst_QQmlDebugJS::changeBreakpoint()
@@ -1174,23 +527,21 @@ void tst_QQmlDebugJS::changeBreakpoint()
QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
bool isStopped = false;
- QObject::connect(m_client, &QJSDebugClient::stopped, this, [&]() { isStopped = true; });
+ QObject::connect(m_client, &QV4DebugClient::stopped, this, [&]() { isStopped = true; });
auto continueDebugging = [&]() {
- m_client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QV4DebugClient::Continue);
isStopped = false;
};
m_client->connect();
auto extractBody = [&]() {
- const QVariantMap value = m_client->parser.call(
- QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap();
- return value.value("body").toMap();
+ return m_client->response().body.toObject();
};
- auto extractBreakPointId = [&](const QVariantMap &body) {
- const QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
+ auto extractBreakPointId = [&](const QJsonObject &body) {
+ const QJsonArray breakpointsHit = body.value("breakpoints").toArray();
if (breakpointsHit.size() != 1)
return -1;
return breakpointsHit[0].toInt();
@@ -1198,7 +549,7 @@ void tst_QQmlDebugJS::changeBreakpoint()
auto setBreakPoint = [&](int sourceLine, bool enabled) {
int id = -1;
- auto connection = QObject::connect(m_client, &QJSDebugClient::result, [&]() {
+ auto connection = QObject::connect(m_client, &QV4DebugClient::result, [&]() {
id = extractBody().value("breakpoint").toInt();
});
@@ -1221,7 +572,7 @@ void tst_QQmlDebugJS::changeBreakpoint()
auto verifyBreakpoint = [&](int sourceLine, int breakpointId) {
QTRY_VERIFY_WITH_TIMEOUT(isStopped, 30000);
- const QVariantMap body = extractBody();
+ const QJsonObject body = extractBody();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
QCOMPARE(extractBreakPointId(body), breakpointId);
};
@@ -1261,7 +612,7 @@ void tst_QQmlDebugJS::setExceptionBreak()
QFETCH(bool, qmlscene);
QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess);
- m_client->setExceptionBreak(QJSDebugClient::All,true);
+ m_client->setExceptionBreak(QV4DebugClient::All,true);
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
}
@@ -1278,24 +629,19 @@ void tst_QQmlDebugJS::stepNext()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- m_client->continueDebugging(QJSDebugClient::Next);
+ m_client->continueDebugging(QV4DebugClient::Next);
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = m_client->response().body.toObject();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(STEPACTION_QMLFILE));
}
-static QVariantMap responseBody(QJSDebugClient *client)
+static QJsonObject responseBody(QV4DebugClient *client)
{
- const QString jsonString(client->response);
- const QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString))
- .toVariant().toMap();
- return value.value("body").toMap();
+ return client->response().body.toObject();
}
void tst_QQmlDebugJS::stepIn()
@@ -1312,12 +658,12 @@ void tst_QQmlDebugJS::stepIn()
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- m_client->continueDebugging(QJSDebugClient::In);
+ m_client->continueDebugging(QV4DebugClient::In);
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- const QVariantMap body = responseBody(m_client);
+ const QJsonObject body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
void tst_QQmlDebugJS::stepOut()
@@ -1334,12 +680,12 @@ void tst_QQmlDebugJS::stepOut()
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- m_client->continueDebugging(QJSDebugClient::Out);
+ m_client->continueDebugging(QV4DebugClient::Out);
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- const QVariantMap body = responseBody(m_client);
+ const QJsonObject body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
void tst_QQmlDebugJS::continueDebugging()
@@ -1356,16 +702,14 @@ void tst_QQmlDebugJS::continueDebugging()
m_client->connect();
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- m_client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QV4DebugClient::Continue);
QVERIFY(waitForClientSignal(SIGNAL(stopped())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ const QJsonObject body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(STEPACTION_QMLFILE));
}
void tst_QQmlDebugJS::backtrace()
@@ -1449,32 +793,27 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
m_client->frame();
QVERIFY(waitForClientSignal(SIGNAL(result())));
- //Get the frame index
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- int frameIndex = body.value("index").toInt();
-
- m_client->evaluate(QLatin1String("root.a"), frameIndex);
- QVERIFY(waitForClientSignal(SIGNAL(result())));
-
- //Verify the value of 'timer.interval'
- jsonString = m_client->response;
- value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- body = value.value("body").toMap();
+ {
+ //Get the frame index
+ const QJsonObject body = responseBody(m_client);
+ int frameIndex = body.value("index").toInt();
+ m_client->evaluate(QLatin1String("root.a"), frameIndex);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+ }
- QCOMPARE(body.value("value").toInt(),10);
+ {
+ //Verify the value of 'timer.interval'
+ const QJsonObject body = responseBody(m_client);
+ QCOMPARE(body.value("value").toInt(),10);
+ }
}
void tst_QQmlDebugJS::evaluateInContext()
{
m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
- + "/qmlscene", this);
- m_client = new QJSDebugClient(m_connection);
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_client = new QV4DebugClient(m_connection);
QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection));
m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
@@ -1530,14 +869,12 @@ void tst_QQmlDebugJS::getScripts()
m_client->scripts();
QVERIFY(waitForClientSignal(SIGNAL(result())));
- QString jsonString(m_client->response);
- QVariantMap value = m_client->parser.call(QJSValueList()
- << QJSValue(jsonString)).toVariant().toMap();
- QList<QVariant> scripts = value.value("body").toList();
+ const QJsonArray scripts = m_client->response().body.toArray();
QCOMPARE(scripts.count(), 1);
- QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
+ QVERIFY(scripts.first().toObject()[QStringLiteral("name")].toString()
+ .endsWith(QStringLiteral("data/test.qml")));
}
void tst_QQmlDebugJS::encodeQmlScope()
@@ -1551,42 +888,38 @@ void tst_QQmlDebugJS::encodeQmlScope()
bool isStopped = false;
bool scopesFailed = false;
- QObject::connect(m_client, &QJSDebugClient::failure, this, [&]() {
- qWarning() << "received failure" << m_client->response;
+ QObject::connect(m_client, &QV4DebugClient::failure, this, [&]() {
+ qWarning() << "received failure" << m_client->response().body;
scopesFailed = true;
m_process->stop();
numFrames = 2;
isStopped = false;
});
- QObject::connect(m_client, &QJSDebugClient::stopped, this, [&]() {
+ QObject::connect(m_client, &QV4DebugClient::stopped, this, [&]() {
m_client->frame();
isStopped = true;
});
- QObject::connect(m_client, &QJSDebugClient::result, this, [&]() {
- const QVariantMap value = m_client->parser.call(
- QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap();
-
- const QMap<QString, QVariant> body = value.value("body").toMap();
- const QString command = value.value("command").toString();
+ QObject::connect(m_client, &QV4DebugClient::result, this, [&]() {
+ const QV4DebugClient::Response value = m_client->response();
- if (command == QString("scope")) {
+ if (value.command == QString("scope")) {
// If the scope commands fail we get a failure() signal above.
if (++numReceivedScopes == numExpectedScopes) {
- m_client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QV4DebugClient::Continue);
isStopped = false;
}
- } else if (command == QString("frame")) {
+ } else if (value.command == QString("frame")) {
// We want at least a global scope and some kind of local scope here.
- const QList<QVariant> scopes = body.value("scopes").toList();
- if (scopes.length() < 2)
+ const QJsonArray scopes = value.body.toObject().value("scopes").toArray();
+ if (scopes.count() < 2)
scopesFailed = true;
- for (const QVariant &scope : scopes) {
+ for (const QJsonValue &scope : scopes) {
++numExpectedScopes;
- m_client->scope(scope.toMap().value("index").toInt());
+ m_client->scope(scope.toObject().value("index").toInt());
}
++numFrames;
@@ -1611,21 +944,21 @@ void tst_QQmlDebugJS::breakOnAnchor()
int breaks = 0;
bool stopped = false;
- QObject::connect(m_client, &QJSDebugClient::stopped, this, [&]() {
+ QObject::connect(m_client, &QV4DebugClient::stopped, this, [&]() {
stopped = true;
++breaks;
m_client->evaluate("this", 0, -1);
});
- QObject::connect(m_client, &QJSDebugClient::result, this, [&]() {
+ QObject::connect(m_client, &QV4DebugClient::result, this, [&]() {
if (stopped) {
- m_client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QV4DebugClient::Continue);
stopped = false;
}
});
- QObject::connect(m_client, &QJSDebugClient::failure, this, [&]() {
- qWarning() << "received failure" << m_client->response;
+ QObject::connect(m_client, &QV4DebugClient::failure, this, [&]() {
+ qWarning() << "received failure" << m_client->response().body;
});
m_client->setBreakpoint(file, 34);
@@ -1643,7 +976,7 @@ void tst_QQmlDebugJS::breakOnAnchor()
QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients()
{
- m_client = new QJSDebugClient(m_connection);
+ m_client = new QV4DebugClient(m_connection);
return QList<QQmlDebugClient *>({m_client});
}
@@ -1661,10 +994,9 @@ bool tst_QQmlDebugJS::waitForClientSignal(const char *signal, int timeout)
void tst_QQmlDebugJS::checkVersionParameters()
{
- const QVariantMap value = m_client->parser.call(
- QJSValueList() << QJSValue(QString(m_client->response))).toVariant().toMap();
- QCOMPARE(value.value("command").toString(), QString("version"));
- const QVariantMap body = value.value("body").toMap();
+ const QV4DebugClient::Response value = m_client->response();
+ QCOMPARE(value.command, QString("version"));
+ const QJsonObject body = value.body.toObject();
QCOMPARE(body.value("UnpausedEvaluate").toBool(), true);
QCOMPARE(body.value("ContextEvaluate").toBool(), true);
QCOMPARE(body.value("ChangeBreakpoint").toBool(), true);