forked from qt-creator/qt-creator
Debugger: Consolidate QmlEngine
Create a QmlEnginePrivate. Move the QmlDebugClient there.
Merge QmlAdapter into QmlEngine Abstraction is not used anymore.
Move some helper bits to a qmlengineutils.{h,cpp}
Change-Id: I63117355d786cc12641101b7fd38c7cd208d11eb
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -146,12 +146,11 @@ QtcPlugin {
|
|||||||
prefix: "qml/"
|
prefix: "qml/"
|
||||||
files: [
|
files: [
|
||||||
"interactiveinterpreter.cpp", "interactiveinterpreter.h",
|
"interactiveinterpreter.cpp", "interactiveinterpreter.h",
|
||||||
"qmladapter.cpp", "qmladapter.h",
|
|
||||||
"qmlcppengine.cpp", "qmlcppengine.h",
|
"qmlcppengine.cpp", "qmlcppengine.h",
|
||||||
"qmlengine.cpp", "qmlengine.h",
|
"qmlengine.cpp", "qmlengine.h",
|
||||||
|
"qmlengineutils.cpp", "qmlengineutils.h",
|
||||||
"qmlinspectoradapter.cpp", "qmlinspectoradapter.h",
|
"qmlinspectoradapter.cpp", "qmlinspectoradapter.h",
|
||||||
"qmlinspectoragent.cpp", "qmlinspectoragent.h",
|
"qmlinspectoragent.cpp", "qmlinspectoragent.h",
|
||||||
"qmlv8debuggerclient.cpp", "qmlv8debuggerclient.h",
|
|
||||||
"qmlv8debuggerclientconstants.h"
|
"qmlv8debuggerclientconstants.h"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/qmlengine.h \
|
$$PWD/qmlengine.h \
|
||||||
$$PWD/qmladapter.h \
|
$$PWD/qmlengineutils.h \
|
||||||
$$PWD/qmlcppengine.h \
|
$$PWD/qmlcppengine.h \
|
||||||
$$PWD/qmlv8debuggerclient.h \
|
|
||||||
$$PWD/interactiveinterpreter.h \
|
$$PWD/interactiveinterpreter.h \
|
||||||
$$PWD/qmlv8debuggerclientconstants.h \
|
$$PWD/qmlv8debuggerclientconstants.h \
|
||||||
$$PWD/qmlinspectoragent.h \
|
$$PWD/qmlinspectoragent.h \
|
||||||
@@ -10,9 +9,8 @@ HEADERS += \
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/qmlengine.cpp \
|
$$PWD/qmlengine.cpp \
|
||||||
$$PWD/qmladapter.cpp \
|
$$PWD/qmlengineutils.cpp \
|
||||||
$$PWD/qmlcppengine.cpp \
|
$$PWD/qmlcppengine.cpp \
|
||||||
$$PWD/qmlv8debuggerclient.cpp \
|
|
||||||
$$PWD/interactiveinterpreter.cpp \
|
$$PWD/interactiveinterpreter.cpp \
|
||||||
$$PWD/qmlinspectoragent.cpp \
|
$$PWD/qmlinspectoragent.cpp \
|
||||||
$$PWD/qmlinspectoradapter.cpp
|
$$PWD/qmlinspectoradapter.cpp
|
||||||
|
|||||||
@@ -1,233 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://www.qt.io/licensing
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** 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 http://www.qt.io/terms-conditions. For further information
|
|
||||||
** use the contact form at http://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 2.1 or version 3 as published by the Free
|
|
||||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
||||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
||||||
** following information to ensure the GNU Lesser General Public License
|
|
||||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "qmladapter.h"
|
|
||||||
|
|
||||||
#include <debugger/debuggerstringutils.h>
|
|
||||||
#include "qmlengine.h"
|
|
||||||
#include "qmlv8debuggerclient.h"
|
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
using namespace QmlDebug;
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
QmlAdapter manages the connection & clients for QML/JS debugging.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_engine(engine)
|
|
||||||
, m_qmlClient(0)
|
|
||||||
, m_conn(0)
|
|
||||||
, m_msgClient(0)
|
|
||||||
{
|
|
||||||
m_connectionTimer.setInterval(4000);
|
|
||||||
m_connectionTimer.setSingleShot(true);
|
|
||||||
connect(&m_connectionTimer, &QTimer::timeout, this, &QmlAdapter::checkConnectionState);
|
|
||||||
|
|
||||||
m_conn = new QmlDebugConnection(this);
|
|
||||||
connect(m_conn, &QmlDebugConnection::stateMessage,
|
|
||||||
this, &QmlAdapter::showConnectionStateMessage);
|
|
||||||
connect(m_conn, &QmlDebugConnection::errorMessage,
|
|
||||||
this, &QmlAdapter::showConnectionErrorMessage);
|
|
||||||
connect(m_conn, &QmlDebugConnection::error,
|
|
||||||
this, &QmlAdapter::connectionErrorOccurred);
|
|
||||||
connect(m_conn, &QmlDebugConnection::opened,
|
|
||||||
&m_connectionTimer, &QTimer::stop);
|
|
||||||
connect(m_conn, &QmlDebugConnection::opened,
|
|
||||||
this, &QmlAdapter::connected);
|
|
||||||
connect(m_conn, &QmlDebugConnection::closed,
|
|
||||||
this, &QmlAdapter::disconnected);
|
|
||||||
|
|
||||||
createDebuggerClients();
|
|
||||||
m_msgClient = new QDebugMessageClient(m_conn);
|
|
||||||
connect(m_msgClient, &QDebugMessageClient::newState, this, &QmlAdapter::clientStateChanged);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QmlAdapter::~QmlAdapter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::beginConnectionTcp(const QString &address, quint16 port)
|
|
||||||
{
|
|
||||||
if (m_engine.isNull() || !m_conn || m_conn->isOpen())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_conn->connectToHost(address, port);
|
|
||||||
|
|
||||||
//A timeout to check the connection state
|
|
||||||
m_connectionTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::closeConnection()
|
|
||||||
{
|
|
||||||
if (m_connectionTimer.isActive()) {
|
|
||||||
m_connectionTimer.stop();
|
|
||||||
} else {
|
|
||||||
if (m_conn)
|
|
||||||
m_conn->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::connectionErrorOccurred(QDebugSupport::Error error)
|
|
||||||
{
|
|
||||||
// this is only an error if we are already connected and something goes wrong.
|
|
||||||
if (isConnected()) {
|
|
||||||
emit connectionError(error);
|
|
||||||
} else {
|
|
||||||
m_connectionTimer.stop();
|
|
||||||
emit connectionStartupFailed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::clientStateChanged(QmlDebugClient::State state)
|
|
||||||
{
|
|
||||||
QString serviceName;
|
|
||||||
float version = 0;
|
|
||||||
if (QmlDebugClient *client = qobject_cast<QmlDebugClient*>(sender())) {
|
|
||||||
serviceName = client->name();
|
|
||||||
version = client->remoteVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
logServiceStateChange(serviceName, version, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::debugClientStateChanged(QmlDebugClient::State state)
|
|
||||||
{
|
|
||||||
if (state != QmlDebugClient::Enabled)
|
|
||||||
return;
|
|
||||||
QmlDebugClient *client = qobject_cast<QmlDebugClient*>(sender());
|
|
||||||
QTC_ASSERT(client, return);
|
|
||||||
|
|
||||||
m_qmlClient = qobject_cast<QmlV8DebuggerClient *>(client);
|
|
||||||
m_qmlClient->startSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::checkConnectionState()
|
|
||||||
{
|
|
||||||
if (!isConnected()) {
|
|
||||||
closeConnection();
|
|
||||||
emit connectionStartupFailed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QmlAdapter::isConnected() const
|
|
||||||
{
|
|
||||||
return m_conn && m_qmlClient && m_conn->isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::createDebuggerClients()
|
|
||||||
{
|
|
||||||
QmlV8DebuggerClient *debugClient2 = new QmlV8DebuggerClient(m_conn);
|
|
||||||
connect(debugClient2, &QmlV8DebuggerClient::newState,
|
|
||||||
this, &QmlAdapter::clientStateChanged);
|
|
||||||
connect(debugClient2, &QmlV8DebuggerClient::newState,
|
|
||||||
this, &QmlAdapter::debugClientStateChanged);
|
|
||||||
|
|
||||||
m_debugClients.insert(debugClient2->name(),debugClient2);
|
|
||||||
|
|
||||||
debugClient2->setEngine((QmlEngine*)(m_engine.data()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QmlDebugConnection *QmlAdapter::connection() const
|
|
||||||
{
|
|
||||||
return m_conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebuggerEngine *QmlAdapter::debuggerEngine() const
|
|
||||||
{
|
|
||||||
return m_engine.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::showConnectionStateMessage(const QString &message)
|
|
||||||
{
|
|
||||||
if (!m_engine.isNull())
|
|
||||||
m_engine.data()->showMessage(_("QML Debugger: ") + message, LogStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::showConnectionErrorMessage(const QString &message)
|
|
||||||
{
|
|
||||||
if (!m_engine.isNull())
|
|
||||||
m_engine.data()->showMessage(_("QML Debugger: ") + message, LogError);
|
|
||||||
}
|
|
||||||
|
|
||||||
QmlV8DebuggerClient *QmlAdapter::activeDebuggerClient() const
|
|
||||||
{
|
|
||||||
return m_qmlClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<QString, QmlV8DebuggerClient*> QmlAdapter::debuggerClients() const
|
|
||||||
{
|
|
||||||
return m_debugClients;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDebugMessageClient *QmlAdapter::messageClient() const
|
|
||||||
{
|
|
||||||
return m_msgClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::logServiceStateChange(const QString &service, float version,
|
|
||||||
QmlDebugClient::State newState)
|
|
||||||
{
|
|
||||||
switch (newState) {
|
|
||||||
case QmlDebugClient::Unavailable: {
|
|
||||||
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'unavailable'.").
|
|
||||||
arg(service).arg(QString::number(version)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QmlDebugClient::Enabled: {
|
|
||||||
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'enabled'.").
|
|
||||||
arg(service).arg(QString::number(version)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QmlDebugClient::NotConnected: {
|
|
||||||
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'not connected'.").
|
|
||||||
arg(service).arg(QString::number(version)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlAdapter::logServiceActivity(const QString &service, const QString &logMessage)
|
|
||||||
{
|
|
||||||
if (!m_engine.isNull())
|
|
||||||
m_engine.data()->showMessage(service + QLatin1Char(' ') + logMessage, LogDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Debugger
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://www.qt.io/licensing
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** 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 http://www.qt.io/terms-conditions. For further information
|
|
||||||
** use the contact form at http://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 2.1 or version 3 as published by the Free
|
|
||||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
||||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
||||||
** following information to ensure the GNU Lesser General Public License
|
|
||||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef QMLADAPTER_H
|
|
||||||
#define QMLADAPTER_H
|
|
||||||
|
|
||||||
#include <qmldebug/qmldebugclient.h>
|
|
||||||
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
namespace QmlDebug {
|
|
||||||
class BaseEngineDebugClient;
|
|
||||||
class QmlDebugConnection;
|
|
||||||
class QDebugMessageClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class QmlV8DebuggerClient;
|
|
||||||
class DebuggerEngine;
|
|
||||||
class QmlAdapterPrivate;
|
|
||||||
|
|
||||||
class QmlAdapter : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QmlAdapter(DebuggerEngine *engine, QObject *parent = 0);
|
|
||||||
virtual ~QmlAdapter();
|
|
||||||
|
|
||||||
void beginConnectionTcp(const QString &address, quint16 port);
|
|
||||||
void closeConnection();
|
|
||||||
|
|
||||||
QmlDebug::QmlDebugConnection *connection() const;
|
|
||||||
DebuggerEngine *debuggerEngine() const;
|
|
||||||
|
|
||||||
QmlV8DebuggerClient *activeDebuggerClient() const;
|
|
||||||
QHash<QString, QmlV8DebuggerClient*> debuggerClients() const;
|
|
||||||
|
|
||||||
QmlDebug::QDebugMessageClient *messageClient() const;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void logServiceStateChange(const QString &service, float version,
|
|
||||||
QmlDebug::QmlDebugClient::State newState);
|
|
||||||
void logServiceActivity(const QString &service, const QString &logMessage);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void connected();
|
|
||||||
void disconnected();
|
|
||||||
void connectionStartupFailed();
|
|
||||||
void connectionError(QDebugSupport::Error error);
|
|
||||||
void serviceConnectionError(const QString serviceName);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void connectionErrorOccurred(QDebugSupport::Error socketError);
|
|
||||||
void clientStateChanged(QmlDebug::QmlDebugClient::State state);
|
|
||||||
void debugClientStateChanged(QmlDebug::QmlDebugClient::State state);
|
|
||||||
void checkConnectionState();
|
|
||||||
void showConnectionStateMessage(const QString &message);
|
|
||||||
void showConnectionErrorMessage(const QString &message);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isConnected() const;
|
|
||||||
void createDebuggerClients();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QPointer<DebuggerEngine> m_engine;
|
|
||||||
QmlV8DebuggerClient *m_qmlClient;
|
|
||||||
QTimer m_connectionTimer;
|
|
||||||
QmlDebug::QmlDebugConnection *m_conn;
|
|
||||||
QHash<QString, QmlV8DebuggerClient*> m_debugClients;
|
|
||||||
QmlDebug::QDebugMessageClient *m_msgClient;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Debugger
|
|
||||||
|
|
||||||
#endif // QMLADAPTER_H
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -31,28 +31,21 @@
|
|||||||
#ifndef QMLENGINE_H
|
#ifndef QMLENGINE_H
|
||||||
#define QMLENGINE_H
|
#define QMLENGINE_H
|
||||||
|
|
||||||
#include "interactiveinterpreter.h"
|
|
||||||
#include "qmladapter.h"
|
|
||||||
#include "qmlinspectoradapter.h"
|
|
||||||
#include <debugger/debuggerengine.h>
|
#include <debugger/debuggerengine.h>
|
||||||
|
|
||||||
#include <projectexplorer/applicationlauncher.h>
|
|
||||||
#include <qmldebug/qdebugmessageclient.h>
|
#include <qmldebug/qdebugmessageclient.h>
|
||||||
|
#include <qmldebug/qmldebugclient.h>
|
||||||
#include <qmldebug/qmloutputparser.h>
|
#include <qmldebug/qmloutputparser.h>
|
||||||
#include <qmljs/iscriptevaluator.h>
|
#include <qmljs/iscriptevaluator.h>
|
||||||
#include <qmljs/qmljsdocument.h>
|
#include <qmljs/qmljsdocument.h>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QTextDocument)
|
|
||||||
|
|
||||||
namespace Core { class IDocument; }
|
|
||||||
|
|
||||||
namespace TextEditor { class BaseTextEditor; }
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class WatchData;
|
||||||
|
class WatchItem;
|
||||||
|
class QmlEnginePrivate;
|
||||||
class QmlAdapter;
|
class QmlAdapter;
|
||||||
class WatchTreeView;
|
|
||||||
|
|
||||||
class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator
|
class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator
|
||||||
{
|
{
|
||||||
@@ -63,31 +56,11 @@ public:
|
|||||||
DebuggerEngine *masterEngine = 0);
|
DebuggerEngine *masterEngine = 0);
|
||||||
~QmlEngine();
|
~QmlEngine();
|
||||||
|
|
||||||
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
|
void filterApplicationMessage(const QString &msg, int channel) const;
|
||||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
|
||||||
|
|
||||||
bool canDisplayTooltip() const;
|
void logServiceStateChange(const QString &service, float version,
|
||||||
|
QmlDebug::QmlDebugClient::State newState);
|
||||||
void showMessage(const QString &msg, int channel = LogDebug,
|
void logServiceActivity(const QString &service, const QString &logMessage);
|
||||||
int timeout = -1) const;
|
|
||||||
void gotoLocation(const Internal::Location &location);
|
|
||||||
|
|
||||||
void filterApplicationMessage(const QString &msg, int channel);
|
|
||||||
void inferiorSpontaneousStop();
|
|
||||||
|
|
||||||
enum LogDirection {
|
|
||||||
LogSend,
|
|
||||||
LogReceive
|
|
||||||
};
|
|
||||||
|
|
||||||
void logMessage(const QString &service, LogDirection direction,
|
|
||||||
const QString &str);
|
|
||||||
|
|
||||||
void setSourceFiles(const QStringList &fileNames);
|
|
||||||
void updateScriptSource(const QString &fileName, int lineOffset,
|
|
||||||
int columnOffset, const QString &source);
|
|
||||||
|
|
||||||
void insertBreakpoint(Breakpoint bp);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void disconnected();
|
void disconnected();
|
||||||
@@ -96,23 +69,28 @@ private slots:
|
|||||||
|
|
||||||
void errorMessageBoxFinished(int result);
|
void errorMessageBoxFinished(int result);
|
||||||
void updateCurrentContext();
|
void updateCurrentContext();
|
||||||
void appendDebugOutput(QtMsgType type, const QString &message,
|
|
||||||
const QmlDebug::QDebugContextInfo &info);
|
|
||||||
|
|
||||||
void tryToConnect(quint16 port = 0);
|
void tryToConnect(quint16 port = 0);
|
||||||
void beginConnection(quint16 port = 0);
|
void beginConnection(quint16 port = 0);
|
||||||
void connectionEstablished();
|
void connectionEstablished();
|
||||||
void connectionStartupFailed();
|
void connectionStartupFailed();
|
||||||
void appStartupFailed(const QString &errorMessage);
|
void appStartupFailed(const QString &errorMessage);
|
||||||
void connectionError(QDebugSupport::Error error);
|
|
||||||
void serviceConnectionError(const QString &service);
|
|
||||||
void appendMessage(const QString &msg, Utils::OutputFormat);
|
void appendMessage(const QString &msg, Utils::OutputFormat);
|
||||||
|
|
||||||
void synchronizeWatchers();
|
void synchronizeWatchers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// DebuggerEngine implementation.
|
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
|
||||||
|
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||||
|
|
||||||
|
void showMessage(const QString &msg, int channel = LogDebug,
|
||||||
|
int timeout = -1) const;
|
||||||
|
void gotoLocation(const Internal::Location &location);
|
||||||
|
void insertBreakpoint(Breakpoint bp);
|
||||||
|
|
||||||
bool isSynchronous() const { return false; }
|
bool isSynchronous() const { return false; }
|
||||||
|
bool canDisplayTooltip() const { return false; }
|
||||||
|
|
||||||
void executeStep();
|
void executeStep();
|
||||||
void executeStepOut();
|
void executeStepOut();
|
||||||
void executeNext();
|
void executeNext();
|
||||||
@@ -153,7 +131,6 @@ private:
|
|||||||
void reloadSourceFiles();
|
void reloadSourceFiles();
|
||||||
void reloadFullStack() {}
|
void reloadFullStack() {}
|
||||||
|
|
||||||
bool supportsThreads() const { return false; }
|
|
||||||
void updateWatchData(const QByteArray &iname);
|
void updateWatchData(const QByteArray &iname);
|
||||||
void selectWatchData(const QByteArray &iname);
|
void selectWatchData(const QByteArray &iname);
|
||||||
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
|
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
|
||||||
@@ -162,36 +139,21 @@ private:
|
|||||||
bool hasCapability(unsigned) const;
|
bool hasCapability(unsigned) const;
|
||||||
void quitDebugger();
|
void quitDebugger();
|
||||||
|
|
||||||
private:
|
|
||||||
void closeConnection();
|
void closeConnection();
|
||||||
void startApplicationLauncher();
|
void startApplicationLauncher();
|
||||||
void stopApplicationLauncher();
|
void stopApplicationLauncher();
|
||||||
|
|
||||||
bool isShadowBuildProject() const;
|
void connectionErrorOccurred(QDebugSupport::Error socketError);
|
||||||
QString fromShadowBuildFilename(const QString &filename) const;
|
void clientStateChanged(QmlDebug::QmlDebugClient::State state);
|
||||||
QString mangleFilenamePaths(const QString &filename,
|
void checkConnectionState();
|
||||||
const QString &oldBasePath, const QString &newBasePath) const;
|
void showConnectionStateMessage(const QString &message);
|
||||||
QString qmlImportPath() const;
|
void showConnectionErrorMessage(const QString &message);
|
||||||
|
bool isConnected() const;
|
||||||
void updateDocument(Core::IDocument *document, const QTextDocument *textDocument);
|
|
||||||
bool canEvaluateScript(const QString &script);
|
|
||||||
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line,
|
|
||||||
quint32 *column, bool *valid);
|
|
||||||
|
|
||||||
QmlAdapter m_adapter;
|
|
||||||
QmlInspectorAdapter m_inspectorAdapter;
|
|
||||||
ProjectExplorer::ApplicationLauncher m_applicationLauncher;
|
|
||||||
QTimer m_noDebugOutputTimer;
|
|
||||||
QmlDebug::QmlOutputParser m_outputParser;
|
|
||||||
QHash<QString, QTextDocument*> m_sourceDocuments;
|
|
||||||
QHash<QString, QWeakPointer<TextEditor::BaseTextEditor> > m_sourceEditors;
|
|
||||||
InteractiveInterpreter m_interpreter;
|
|
||||||
QHash<QString,Breakpoint> pendingBreakpoints;
|
|
||||||
QList<quint32> queryIds;
|
|
||||||
bool m_retryOnConnectFail;
|
|
||||||
bool m_automaticConnect;
|
|
||||||
|
|
||||||
|
private:
|
||||||
friend class QmlCppEngine;
|
friend class QmlCppEngine;
|
||||||
|
friend class QmlEnginePrivate;
|
||||||
|
QmlEnginePrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
270
src/plugins/debugger/qml/qmlengineutils.cpp
Normal file
270
src/plugins/debugger/qml/qmlengineutils.cpp
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 http://www.qt.io/terms-conditions. For further information
|
||||||
|
** use the contact form at http://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 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qmlengine.h"
|
||||||
|
|
||||||
|
#include <qmljs/parser/qmljsast_p.h>
|
||||||
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
#include <qmljs/consolemanagerinterface.h>
|
||||||
|
|
||||||
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
|
|
||||||
|
#include <texteditor/textdocument.h>
|
||||||
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
using namespace QmlDebug;
|
||||||
|
using namespace QmlJS;
|
||||||
|
using namespace QmlJS::AST;
|
||||||
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class ASTWalker : public Visitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void operator()(Node *ast, quint32 *l, quint32 *c)
|
||||||
|
{
|
||||||
|
done = false;
|
||||||
|
line = l;
|
||||||
|
column = c;
|
||||||
|
Node::accept(ast, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool preVisit(Node *ast)
|
||||||
|
{
|
||||||
|
return !done && ast->lastSourceLocation().startLine >= *line;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Case 1: Breakpoint is between sourceStart(exclusive) and
|
||||||
|
// sourceEnd(inclusive) --> End tree walk.
|
||||||
|
//Case 2: Breakpoint is on sourceStart --> Check for the start
|
||||||
|
// of the first executable code. Set the line number and
|
||||||
|
// column number. End tree walk.
|
||||||
|
//Case 3: Breakpoint is on "unbreakable" code --> Find the next "breakable"
|
||||||
|
// code and check for Case 2. End tree walk.
|
||||||
|
|
||||||
|
//Add more types when suitable.
|
||||||
|
|
||||||
|
bool visit(UiScriptBinding *ast)
|
||||||
|
{
|
||||||
|
if (!ast->statement)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
quint32 sourceStartLine = ast->firstSourceLocation().startLine;
|
||||||
|
quint32 statementStartLine;
|
||||||
|
quint32 statementColumn;
|
||||||
|
|
||||||
|
if (ast->statement->kind == Node::Kind_ExpressionStatement) {
|
||||||
|
statementStartLine = ast->statement->firstSourceLocation().startLine;
|
||||||
|
statementColumn = ast->statement->firstSourceLocation().startColumn;
|
||||||
|
|
||||||
|
} else if (ast->statement->kind == Node::Kind_Block) {
|
||||||
|
Block *block = static_cast<Block *>(ast->statement);
|
||||||
|
if (!block || !block->statements)
|
||||||
|
return true;
|
||||||
|
statementStartLine = block->statements->firstSourceLocation().startLine;
|
||||||
|
statementColumn = block->statements->firstSourceLocation().startColumn;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Case 1
|
||||||
|
//Check for possible relocation within the binding statement
|
||||||
|
|
||||||
|
//Rewritten to (function <token>() { { }})
|
||||||
|
//The offset 16 is position of inner lbrace without token length.
|
||||||
|
const int offset = 16;
|
||||||
|
|
||||||
|
//Case 2
|
||||||
|
if (statementStartLine == *line) {
|
||||||
|
if (sourceStartLine == *line)
|
||||||
|
*column = offset + ast->qualifiedId->identifierToken.length;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Case 3
|
||||||
|
if (statementStartLine > *line) {
|
||||||
|
*line = statementStartLine;
|
||||||
|
if (sourceStartLine == *line)
|
||||||
|
*column = offset + ast->qualifiedId->identifierToken.length;
|
||||||
|
else
|
||||||
|
*column = statementColumn;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visit(FunctionDeclaration *ast) {
|
||||||
|
quint32 sourceStartLine = ast->firstSourceLocation().startLine;
|
||||||
|
quint32 sourceStartColumn = ast->firstSourceLocation().startColumn;
|
||||||
|
quint32 statementStartLine = ast->body->firstSourceLocation().startLine;
|
||||||
|
quint32 statementColumn = ast->body->firstSourceLocation().startColumn;
|
||||||
|
|
||||||
|
//Case 1
|
||||||
|
//Check for possible relocation within the function declaration
|
||||||
|
|
||||||
|
//Case 2
|
||||||
|
if (statementStartLine == *line) {
|
||||||
|
if (sourceStartLine == *line)
|
||||||
|
*column = statementColumn - sourceStartColumn + 1;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Case 3
|
||||||
|
if (statementStartLine > *line) {
|
||||||
|
*line = statementStartLine;
|
||||||
|
if (sourceStartLine == *line)
|
||||||
|
*column = statementColumn - sourceStartColumn + 1;
|
||||||
|
else
|
||||||
|
*column = statementColumn;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visit(EmptyStatement *ast)
|
||||||
|
{
|
||||||
|
*line = ast->lastSourceLocation().startLine + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visit(VariableStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(VariableDeclarationList *ast) { test(ast); return true; }
|
||||||
|
bool visit(VariableDeclaration *ast) { test(ast); return true; }
|
||||||
|
bool visit(ExpressionStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(IfStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(DoWhileStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(WhileStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(ForStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(LocalForStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(ForEachStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(LocalForEachStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(ContinueStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(BreakStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(ReturnStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(WithStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(SwitchStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(CaseBlock *ast) { test(ast); return true; }
|
||||||
|
bool visit(CaseClauses *ast) { test(ast); return true; }
|
||||||
|
bool visit(CaseClause *ast) { test(ast); return true; }
|
||||||
|
bool visit(DefaultClause *ast) { test(ast); return true; }
|
||||||
|
bool visit(LabelledStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(ThrowStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(TryStatement *ast) { test(ast); return true; }
|
||||||
|
bool visit(Catch *ast) { test(ast); return true; }
|
||||||
|
bool visit(Finally *ast) { test(ast); return true; }
|
||||||
|
bool visit(FunctionExpression *ast) { test(ast); return true; }
|
||||||
|
bool visit(DebuggerStatement *ast) { test(ast); return true; }
|
||||||
|
|
||||||
|
void test(Node *ast)
|
||||||
|
{
|
||||||
|
quint32 statementStartLine = ast->firstSourceLocation().startLine;
|
||||||
|
//Case 1/2
|
||||||
|
if (statementStartLine <= *line && *line <= ast->lastSourceLocation().startLine)
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
//Case 3
|
||||||
|
if (statementStartLine > *line) {
|
||||||
|
*line = statementStartLine;
|
||||||
|
*column = ast->firstSourceLocation().startColumn;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool done;
|
||||||
|
quint32 *line;
|
||||||
|
quint32 *column;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
//check if file is in the latest snapshot
|
||||||
|
//ignoring documentChangedOnDisk
|
||||||
|
//TODO:: update breakpoints if document is changed.
|
||||||
|
ModelManagerInterface *mmIface = ModelManagerInterface::instance();
|
||||||
|
if (mmIface) {
|
||||||
|
Document::Ptr doc = mmIface->newestSnapshot().document(filePath);
|
||||||
|
if (doc.isNull()) {
|
||||||
|
ModelManagerInterface::instance()->updateSourceFiles(
|
||||||
|
QStringList() << filePath, false);
|
||||||
|
} else {
|
||||||
|
ASTWalker walker;
|
||||||
|
walker(doc->ast(), line, column);
|
||||||
|
*valid = walker.done;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendDebugOutput(QtMsgType type, const QString &message, const QDebugContextInfo &info)
|
||||||
|
{
|
||||||
|
ConsoleItem::ItemType itemType;
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
itemType = ConsoleItem::DebugType;
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
itemType = ConsoleItem::WarningType;
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
case QtFatalMsg:
|
||||||
|
itemType = ConsoleItem::ErrorType;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//This case is not possible
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto consoleManager = ConsoleManagerInterface::instance()) {
|
||||||
|
ConsoleItem *item = new ConsoleItem(consoleManager->rootItem(), itemType, message);
|
||||||
|
item->file = info.file;
|
||||||
|
item->line = info.line;
|
||||||
|
consoleManager->printToConsolePane(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearExceptionSelection()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
|
|
||||||
|
foreach (IEditor *editor, DocumentModel::editorsForOpenedDocuments()) {
|
||||||
|
if (auto ed = qobject_cast<TextEditorWidget *>(editor->widget()))
|
||||||
|
ed->setExtraSelections(TextEditorWidget::DebuggerExceptionSelection, selections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Internal
|
||||||
|
} // Debugger
|
||||||
47
src/plugins/debugger/qml/qmlengineutils.h
Normal file
47
src/plugins/debugger/qml/qmlengineutils.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 http://www.qt.io/terms-conditions. For further information
|
||||||
|
** use the contact form at http://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 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QMLENGINEUTILS_H
|
||||||
|
#define QMLENGINEUTILS_H
|
||||||
|
|
||||||
|
#include <qmldebug/qdebugmessageclient.h>
|
||||||
|
#include <qmldebug/qmloutputparser.h>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid);
|
||||||
|
void appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info);
|
||||||
|
void clearExceptionSelection();
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // QMLENGINEUTILS_H
|
||||||
@@ -30,8 +30,9 @@
|
|||||||
|
|
||||||
#include "qmlinspectoradapter.h"
|
#include "qmlinspectoradapter.h"
|
||||||
|
|
||||||
#include "qmladapter.h"
|
#include "qmlengine.h"
|
||||||
#include "qmlinspectoragent.h"
|
#include "qmlinspectoragent.h"
|
||||||
|
|
||||||
#include <debugger/debuggeractions.h>
|
#include <debugger/debuggeractions.h>
|
||||||
#include <debugger/debuggercore.h>
|
#include <debugger/debuggercore.h>
|
||||||
#include <debugger/debuggerstringutils.h>
|
#include <debugger/debuggerstringutils.h>
|
||||||
@@ -60,15 +61,12 @@ namespace Internal {
|
|||||||
* QmlInspectorAdapter manages the clients for the inspector, and the
|
* QmlInspectorAdapter manages the clients for the inspector, and the
|
||||||
* integration with the text editor.
|
* integration with the text editor.
|
||||||
*/
|
*/
|
||||||
QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
|
QmlInspectorAdapter::QmlInspectorAdapter(QmlEngine *engine, QmlDebugConnection *connection)
|
||||||
DebuggerEngine *engine,
|
: m_qmlEngine(engine)
|
||||||
QObject *parent)
|
, m_masterEngine(engine)
|
||||||
: QObject(parent)
|
|
||||||
, m_debugAdapter(debugAdapter)
|
|
||||||
, m_engine(engine)
|
|
||||||
, m_engineClient(0)
|
, m_engineClient(0)
|
||||||
, m_toolsClient(0)
|
, m_toolsClient(0)
|
||||||
, m_agent(new QmlInspectorAgent(engine, this))
|
, m_agent(new QmlInspectorAgent(engine))
|
||||||
, m_targetToSync(NoTarget)
|
, m_targetToSync(NoTarget)
|
||||||
, m_debugIdToSelect(-1)
|
, m_debugIdToSelect(-1)
|
||||||
, m_currentSelectedDebugId(-1)
|
, m_currentSelectedDebugId(-1)
|
||||||
@@ -79,16 +77,15 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
|
|||||||
, m_showAppOnTopAction(action(ShowAppOnTop))
|
, m_showAppOnTopAction(action(ShowAppOnTop))
|
||||||
, m_engineClientConnected(false)
|
, m_engineClientConnected(false)
|
||||||
{
|
{
|
||||||
if (!m_engine->isMasterEngine())
|
if (!m_masterEngine->isMasterEngine())
|
||||||
m_engine = m_engine->masterEngine();
|
m_masterEngine = m_masterEngine->masterEngine();
|
||||||
connect(m_engine, &DebuggerEngine::stateChanged,
|
connect(m_masterEngine, &DebuggerEngine::stateChanged,
|
||||||
this, &QmlInspectorAdapter::onEngineStateChanged);
|
this, &QmlInspectorAdapter::onEngineStateChanged);
|
||||||
connect(m_agent, &QmlInspectorAgent::objectFetched,
|
connect(m_agent, &QmlInspectorAgent::objectFetched,
|
||||||
this, &QmlInspectorAdapter::onObjectFetched);
|
this, &QmlInspectorAdapter::onObjectFetched);
|
||||||
connect(m_agent, &QmlInspectorAgent::jumpToObjectDefinition,
|
connect(m_agent, &QmlInspectorAgent::jumpToObjectDefinition,
|
||||||
this, &QmlInspectorAdapter::jumpToObjectDefinitionInEditor);
|
this, &QmlInspectorAdapter::jumpToObjectDefinitionInEditor);
|
||||||
|
|
||||||
QmlDebugConnection *connection = m_debugAdapter->connection();
|
|
||||||
auto engineClient1 = new DeclarativeEngineDebugClient(connection);
|
auto engineClient1 = new DeclarativeEngineDebugClient(connection);
|
||||||
connect(engineClient1, &BaseEngineDebugClient::newState,
|
connect(engineClient1, &BaseEngineDebugClient::newState,
|
||||||
this, &QmlInspectorAdapter::clientStateChanged);
|
this, &QmlInspectorAdapter::clientStateChanged);
|
||||||
@@ -186,7 +183,7 @@ void QmlInspectorAdapter::clientStateChanged(QmlDebugClient::State state)
|
|||||||
version = client->remoteVersion();
|
version = client->remoteVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_debugAdapter->logServiceStateChange(serviceName, version, state);
|
m_qmlEngine->logServiceStateChange(serviceName, version, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
||||||
@@ -199,7 +196,7 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
|||||||
connect(client, &BaseToolsClient::currentObjectsChanged,
|
connect(client, &BaseToolsClient::currentObjectsChanged,
|
||||||
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
|
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
|
||||||
connect(client, &BaseToolsClient::logActivity,
|
connect(client, &BaseToolsClient::logActivity,
|
||||||
m_debugAdapter, &QmlAdapter::logServiceActivity);
|
m_qmlEngine, &QmlEngine::logServiceActivity);
|
||||||
connect(client, &BaseToolsClient::reloaded, this, &QmlInspectorAdapter::onReloaded);
|
connect(client, &BaseToolsClient::reloaded, this, &QmlInspectorAdapter::onReloaded);
|
||||||
|
|
||||||
// register actions here
|
// register actions here
|
||||||
@@ -217,15 +214,15 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
|||||||
Core::ICore::addAdditionalContext(m_inspectorToolsContext);
|
Core::ICore::addAdditionalContext(m_inspectorToolsContext);
|
||||||
|
|
||||||
m_toolsClientConnected = true;
|
m_toolsClientConnected = true;
|
||||||
onEngineStateChanged(m_engine->state());
|
onEngineStateChanged(m_masterEngine->state());
|
||||||
if (m_showAppOnTopAction->isChecked())
|
if (m_showAppOnTopAction->isChecked())
|
||||||
m_toolsClient->showAppOnTop(true);
|
m_toolsClient->showAppOnTop(true);
|
||||||
|
|
||||||
} else if (m_toolsClientConnected && client == m_toolsClient) {
|
} else if (m_toolsClientConnected && client == m_toolsClient) {
|
||||||
disconnect(client, SIGNAL(currentObjectsChanged(QList<int>)),
|
disconnect(client, &BaseToolsClient::currentObjectsChanged,
|
||||||
this, SLOT(selectObjectsFromToolsClient(QList<int>)));
|
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
|
||||||
disconnect(client, SIGNAL(logActivity(QString,QString)),
|
disconnect(client, &BaseToolsClient::logActivity,
|
||||||
m_debugAdapter, SLOT(logServiceActivity(QString,QString)));
|
m_qmlEngine, &QmlEngine::logServiceActivity);
|
||||||
|
|
||||||
Core::ActionManager::unregisterAction(m_selectAction, Core::Id(Constants::QML_SELECTTOOL));
|
Core::ActionManager::unregisterAction(m_selectAction, Core::Id(Constants::QML_SELECTTOOL));
|
||||||
Core::ActionManager::unregisterAction(m_zoomAction, Core::Id(Constants::QML_ZOOMTOOL));
|
Core::ActionManager::unregisterAction(m_zoomAction, Core::Id(Constants::QML_ZOOMTOOL));
|
||||||
@@ -316,13 +313,13 @@ void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client)
|
|||||||
|
|
||||||
void QmlInspectorAdapter::showConnectionStateMessage(const QString &message)
|
void QmlInspectorAdapter::showConnectionStateMessage(const QString &message)
|
||||||
{
|
{
|
||||||
m_engine->showMessage(_("QML Inspector: ") + message, LogStatus);
|
m_masterEngine->showMessage(_("QML Inspector: ") + message, LogStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlInspectorAdapter::jumpToObjectDefinitionInEditor(
|
void QmlInspectorAdapter::jumpToObjectDefinitionInEditor(
|
||||||
const FileReference &objSource, int debugId)
|
const FileReference &objSource, int debugId)
|
||||||
{
|
{
|
||||||
const QString fileName = m_engine->toFileInProject(objSource.url());
|
const QString fileName = m_masterEngine->toFileInProject(objSource.url());
|
||||||
|
|
||||||
Core::EditorManager::openEditorAt(fileName, objSource.lineNumber());
|
Core::EditorManager::openEditorAt(fileName, objSource.lineNumber());
|
||||||
if (debugId != -1 && debugId != m_currentSelectedDebugId) {
|
if (debugId != -1 && debugId != m_currentSelectedDebugId) {
|
||||||
|
|||||||
@@ -41,13 +41,14 @@ class BaseEngineDebugClient;
|
|||||||
class BaseToolsClient;
|
class BaseToolsClient;
|
||||||
class ObjectReference;
|
class ObjectReference;
|
||||||
class FileReference;
|
class FileReference;
|
||||||
|
class QmlDebugConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DebuggerEngine;
|
class DebuggerEngine;
|
||||||
class QmlAdapter;
|
class QmlEngine;
|
||||||
class QmlInspectorAgent;
|
class QmlInspectorAgent;
|
||||||
|
|
||||||
class QmlInspectorAdapter : public QObject
|
class QmlInspectorAdapter : public QObject
|
||||||
@@ -55,8 +56,7 @@ class QmlInspectorAdapter : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QmlInspectorAdapter(QmlAdapter *debugAdapter, DebuggerEngine *engine,
|
QmlInspectorAdapter(QmlEngine *engine, QmlDebug::QmlDebugConnection *connection);
|
||||||
QObject *parent = 0);
|
|
||||||
~QmlInspectorAdapter();
|
~QmlInspectorAdapter();
|
||||||
|
|
||||||
QmlDebug::BaseEngineDebugClient *engineClient() const;
|
QmlDebug::BaseEngineDebugClient *engineClient() const;
|
||||||
@@ -96,8 +96,8 @@ private:
|
|||||||
|
|
||||||
void enableTools(const bool enable);
|
void enableTools(const bool enable);
|
||||||
|
|
||||||
QmlAdapter *m_debugAdapter;
|
QmlEngine *m_qmlEngine;
|
||||||
DebuggerEngine *m_engine; // Master Engine
|
DebuggerEngine *m_masterEngine;
|
||||||
QmlDebug::BaseEngineDebugClient *m_engineClient;
|
QmlDebug::BaseEngineDebugClient *m_engineClient;
|
||||||
QHash<QString, QmlDebug::BaseEngineDebugClient*> m_engineClients;
|
QHash<QString, QmlDebug::BaseEngineDebugClient*> m_engineClients;
|
||||||
QmlDebug::BaseToolsClient *m_toolsClient;
|
QmlDebug::BaseToolsClient *m_toolsClient;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://www.qt.io/licensing
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** 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 http://www.qt.io/terms-conditions. For further information
|
|
||||||
** use the contact form at http://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 2.1 or version 3 as published by the Free
|
|
||||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
||||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
||||||
** following information to ensure the GNU Lesser General Public License
|
|
||||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef QMLV8DEBUGGERCLIENT_H
|
|
||||||
#define QMLV8DEBUGGERCLIENT_H
|
|
||||||
|
|
||||||
#include <debugger/debuggerengine.h>
|
|
||||||
#include <qmldebug/qmldebugclient.h>
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class WatchData;
|
|
||||||
class WatchItem;
|
|
||||||
class QmlEngine;
|
|
||||||
class QmlV8DebuggerClientPrivate;
|
|
||||||
|
|
||||||
class QmlV8DebuggerClient : public QmlDebug::QmlDebugClient
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
enum Exceptions
|
|
||||||
{
|
|
||||||
NoExceptions,
|
|
||||||
UncaughtExceptions,
|
|
||||||
AllExceptions
|
|
||||||
};
|
|
||||||
|
|
||||||
enum StepAction
|
|
||||||
{
|
|
||||||
Continue,
|
|
||||||
In,
|
|
||||||
Out,
|
|
||||||
Next
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QmlV8DebuggerClient(QmlDebug::QmlDebugConnection *client);
|
|
||||||
~QmlV8DebuggerClient();
|
|
||||||
|
|
||||||
void startSession();
|
|
||||||
void endSession();
|
|
||||||
void resetSession();
|
|
||||||
|
|
||||||
void executeStep();
|
|
||||||
void executeStepOut();
|
|
||||||
void executeNext();
|
|
||||||
void executeStepI();
|
|
||||||
|
|
||||||
void executeRunToLine(const ContextData &data);
|
|
||||||
|
|
||||||
void continueInferior();
|
|
||||||
void interruptInferior();
|
|
||||||
|
|
||||||
void activateFrame(int index);
|
|
||||||
|
|
||||||
bool acceptsBreakpoint(Breakpoint bp);
|
|
||||||
void insertBreakpoint(Breakpoint bp, int adjustedLine,
|
|
||||||
int adjustedColumn = -1);
|
|
||||||
void removeBreakpoint(Breakpoint bp);
|
|
||||||
void changeBreakpoint(Breakpoint bp);
|
|
||||||
void synchronizeBreakpoints();
|
|
||||||
|
|
||||||
void assignValueInDebugger(const WatchData *data,
|
|
||||||
const QString &expression,
|
|
||||||
const QVariant &valueV);
|
|
||||||
|
|
||||||
void updateWatchData(const WatchData &);
|
|
||||||
void executeDebuggerCommand(const QString &command);
|
|
||||||
|
|
||||||
void synchronizeWatchers(const QStringList &watchers);
|
|
||||||
|
|
||||||
void expandObject(const QByteArray &iname, quint64 objectId);
|
|
||||||
|
|
||||||
void setEngine(QmlEngine *engine);
|
|
||||||
|
|
||||||
void getSourceFiles();
|
|
||||||
|
|
||||||
void flushSendBuffer();
|
|
||||||
|
|
||||||
void stateChanged(State state);
|
|
||||||
void sendMessage(const QByteArray &msg);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void newState(QmlDebug::QmlDebugClient::State state);
|
|
||||||
void stackFrameCompleted();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void messageReceived(const QByteArray &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updateStack(const QVariant &bodyVal, const QVariant &refsVal);
|
|
||||||
StackFrame extractStackFrame(const QVariant &bodyVal, const QVariant &refsVal);
|
|
||||||
void setCurrentFrameDetails(const QVariant &bodyVal, const QVariant &refsVal);
|
|
||||||
void updateScope(const QVariant &bodyVal, const QVariant &refsVal);
|
|
||||||
|
|
||||||
void updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal,
|
|
||||||
const QVariant &refsVal);
|
|
||||||
void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal);
|
|
||||||
void createWatchDataList(const WatchItem *parent,
|
|
||||||
const QVariantList &properties,
|
|
||||||
const QVariant &refsVal);
|
|
||||||
|
|
||||||
void highlightExceptionCode(int lineNumber, const QString &filePath,
|
|
||||||
const QString &errorMessage);
|
|
||||||
void clearExceptionSelection();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QmlV8DebuggerClientPrivate *d;
|
|
||||||
friend class QmlV8DebuggerClientPrivate;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Internal
|
|
||||||
} // Debugger
|
|
||||||
|
|
||||||
#endif // QMLV8DEBUGGERCLIENT_H
|
|
||||||
Reference in New Issue
Block a user