forked from qt-creator/qt-creator
Debugger: Start using callbacks in QmlEngine commands
Version, Backtrace, Frame, Scope and Lookup for now. Change-Id: I615c8f8c00484e9bb1742485f24bdfc537f83021 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -83,6 +83,8 @@
|
||||
#endif
|
||||
# define XSDEBUG(s) qDebug() << s
|
||||
|
||||
#define CB(callback) [this](const QVariantMap &r) { callback(r); }
|
||||
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QmlDebug;
|
||||
@@ -116,6 +118,8 @@ struct QmlV8ObjectData
|
||||
QVariantList properties;
|
||||
};
|
||||
|
||||
typedef std::function<void(const QVariantMap &)> QmlCallback;
|
||||
|
||||
class QmlEnginePrivate : QmlDebugClient
|
||||
{
|
||||
public:
|
||||
@@ -134,8 +138,8 @@ public:
|
||||
|
||||
void evaluate(const QString expr, bool global = false, bool disableBreak = false,
|
||||
int frame = -1, bool addContext = false);
|
||||
void lookup(const QList<int> handles, bool includeSource = false);
|
||||
void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
|
||||
void lookup(const QList<int> handles);
|
||||
void backtrace();
|
||||
void frame(int number);
|
||||
void scope(int number, int frameNumber = -1);
|
||||
void scripts(int types = 4, const QList<int> ids = QList<int>(),
|
||||
@@ -152,17 +156,19 @@ public:
|
||||
void expandObject(const QByteArray &iname, quint64 objectId);
|
||||
void flushSendBuffer();
|
||||
|
||||
void handleBacktrace(const QVariant &bodyVal);
|
||||
void handleLookup(const QVariant &bodyVal);
|
||||
void handleBacktrace(const QVariantMap &response);
|
||||
void handleLookup(const QVariantMap &response);
|
||||
void handleEvaluate(int sequence, bool success, const QVariant &bodyVal);
|
||||
void handleFrame(const QVariant &bodyVal);
|
||||
void handleScope(const QVariant &bodyVal);
|
||||
void handleFrame(const QVariantMap &response);
|
||||
void handleFrameHelper(const QVariantMap ¤tFrame);
|
||||
void handleScope(const QVariantMap &response);
|
||||
void handleVersion(const QVariantMap &response);
|
||||
StackFrame extractStackFrame(const QVariant &bodyVal);
|
||||
|
||||
bool canEvaluateScript(const QString &script);
|
||||
void updateScriptSource(const QString &fileName, int lineOffset, int columnOffset, const QString &source);
|
||||
|
||||
void runCommand(const DebuggerCommand &command);
|
||||
void runCommand(const DebuggerCommand &command, const QmlCallback &cb = QmlCallback());
|
||||
void runDirectCommand(const QByteArray &type, const QByteArray &msg = QByteArray());
|
||||
|
||||
void clearRefs() { refVals.clear(); }
|
||||
@@ -208,6 +214,8 @@ public:
|
||||
QTimer connectionTimer;
|
||||
QmlDebug::QmlDebugConnection *connection;
|
||||
QmlDebug::QDebugMessageClient *msgClient = 0;
|
||||
|
||||
QHash<int, QmlCallback> callbackForToken;
|
||||
};
|
||||
|
||||
static void updateDocument(IDocument *document, const QTextDocument *textDocument)
|
||||
@@ -1389,7 +1397,7 @@ void QmlEnginePrivate::evaluate(const QString expr, bool global,
|
||||
runCommand(cmd);
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::lookup(QList<int> handles, bool includeSource)
|
||||
void QmlEnginePrivate::lookup(QList<int> handles)
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "request",
|
||||
@@ -1402,16 +1410,11 @@ void QmlEnginePrivate::lookup(QList<int> handles, bool includeSource)
|
||||
// }
|
||||
|
||||
DebuggerCommand cmd(LOOKUP);
|
||||
|
||||
cmd.arg(HANDLES, handles);
|
||||
|
||||
if (includeSource)
|
||||
cmd.arg(INCLUDESOURCE, includeSource);
|
||||
|
||||
runCommand(cmd);
|
||||
runCommand(cmd, CB(handleLookup));
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::backtrace(int fromFrame, int toFrame, bool bottom)
|
||||
void QmlEnginePrivate::backtrace()
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "request",
|
||||
@@ -1424,17 +1427,7 @@ void QmlEnginePrivate::backtrace(int fromFrame, int toFrame, bool bottom)
|
||||
// }
|
||||
|
||||
DebuggerCommand cmd(BACKTRACE);
|
||||
|
||||
if (fromFrame != -1)
|
||||
cmd.arg(FROMFRAME, fromFrame);
|
||||
|
||||
if (toFrame != -1)
|
||||
cmd.arg(TOFRAME, toFrame);
|
||||
|
||||
if (bottom)
|
||||
cmd.arg(BOTTOM, bottom);
|
||||
|
||||
runCommand(cmd);
|
||||
runCommand(cmd, CB(handleBacktrace));
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::frame(int number)
|
||||
@@ -1450,7 +1443,7 @@ void QmlEnginePrivate::frame(int number)
|
||||
if (number != -1)
|
||||
cmd.arg(NUMBER, number);
|
||||
|
||||
runCommand(cmd);
|
||||
runCommand(cmd, CB(handleFrame));
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::scope(int number, int frameNumber)
|
||||
@@ -1469,7 +1462,7 @@ void QmlEnginePrivate::scope(int number, int frameNumber)
|
||||
if (frameNumber != -1)
|
||||
cmd.arg(FRAMENUMBER, frameNumber);
|
||||
|
||||
runCommand(cmd);
|
||||
runCommand(cmd, CB(handleScope));
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::scripts(int types, const QList<int> ids, bool includeSource,
|
||||
@@ -1709,12 +1702,15 @@ void QmlEnginePrivate::clearCache()
|
||||
updateLocalsAndWatchers.clear();
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::runCommand(const DebuggerCommand &command)
|
||||
void QmlEnginePrivate::runCommand(const DebuggerCommand &command, const QmlCallback &cb)
|
||||
{
|
||||
QByteArray msg = "{\"seq\":" + QByteArray::number(++sequence) + ","
|
||||
+ "\"type\":\"request\","
|
||||
+ "\"command\":\"" + command.function + "\","
|
||||
+ "\"arguments\":{" + command.arguments() + "}}";
|
||||
if (cb)
|
||||
callbackForToken[sequence] = cb;
|
||||
|
||||
runDirectCommand(V8REQUEST, msg);
|
||||
}
|
||||
|
||||
@@ -1793,6 +1789,8 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
|
||||
|
||||
if (type == _("response")) {
|
||||
|
||||
const QString debugCommand(resp.value(_(COMMAND)).toString());
|
||||
|
||||
memorizeRefs(resp.value(_(REFS)));
|
||||
|
||||
bool success = resp.value(_("success")).toBool();
|
||||
@@ -1800,22 +1798,16 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
|
||||
SDEBUG("Request was unsuccessful");
|
||||
}
|
||||
|
||||
const QString debugCommand(resp.value(_(COMMAND)).toString());
|
||||
int requestSeq = resp.value(_("request_seq")).toInt();
|
||||
if (callbackForToken.contains(requestSeq)) {
|
||||
callbackForToken[requestSeq](resp);
|
||||
|
||||
if (debugCommand == _(DISCONNECT)) {
|
||||
} else if (debugCommand == _(DISCONNECT)) {
|
||||
//debugging session ended
|
||||
|
||||
} else if (debugCommand == _(CONTINEDEBUGGING)) {
|
||||
//do nothing, wait for next break
|
||||
|
||||
} else if (debugCommand == _(BACKTRACE)) {
|
||||
if (success)
|
||||
handleBacktrace(resp.value(_(BODY)));
|
||||
|
||||
} else if (debugCommand == _(LOOKUP)) {
|
||||
if (success)
|
||||
handleLookup(resp.value(_(BODY)));
|
||||
|
||||
} else if (debugCommand == _(EVALUATE)) {
|
||||
int seq = resp.value(_("request_seq")).toInt();
|
||||
if (success) {
|
||||
@@ -1886,14 +1878,6 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
|
||||
// }
|
||||
|
||||
|
||||
} else if (debugCommand == _(FRAME)) {
|
||||
if (success)
|
||||
handleFrame(resp.value(_(BODY)));
|
||||
|
||||
} else if (debugCommand == _(SCOPE)) {
|
||||
if (success)
|
||||
handleScope(resp.value(_(BODY)));
|
||||
|
||||
} else if (debugCommand == _(SCRIPTS)) {
|
||||
// { "seq" : <number>,
|
||||
// "type" : "response",
|
||||
@@ -1951,11 +1935,6 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
|
||||
engine->sourceFilesHandler()->setSourceFiles(files);
|
||||
//update open editors
|
||||
}
|
||||
} else if (debugCommand == _(VERSION)) {
|
||||
engine->showMessage(QString(_("Using V8 Version: %1")).arg(
|
||||
resp.value(_(BODY)).toMap().
|
||||
value(_("V8Version")).toString()), LogOutput);
|
||||
|
||||
} else {
|
||||
// DO NOTHING
|
||||
}
|
||||
@@ -2100,7 +2079,7 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleBacktrace(const QVariant &bodyVal)
|
||||
void QmlEnginePrivate::handleBacktrace(const QVariantMap &response)
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "response",
|
||||
@@ -2115,7 +2094,7 @@ void QmlEnginePrivate::handleBacktrace(const QVariant &bodyVal)
|
||||
// "success" : true
|
||||
// }
|
||||
|
||||
const QVariantMap body = bodyVal.toMap();
|
||||
const QVariantMap body = response.value(_(BODY)).toMap();
|
||||
const QVariantList frames = body.value(_("frames")).toList();
|
||||
|
||||
int fromFrameIndex = body.value(_("fromFrame")).toInt();
|
||||
@@ -2141,7 +2120,7 @@ void QmlEnginePrivate::handleBacktrace(const QVariant &bodyVal)
|
||||
//Update all Locals visible in current scope
|
||||
//Traverse the scope chain and store the local properties
|
||||
//in a list and show them in the Locals Window.
|
||||
handleFrame(frames.value(0));
|
||||
handleFrameHelper(frames.value(0).toMap());
|
||||
}
|
||||
|
||||
StackFrame QmlEnginePrivate::extractStackFrame(const QVariant &bodyVal)
|
||||
@@ -2205,7 +2184,7 @@ StackFrame QmlEnginePrivate::extractStackFrame(const QVariant &bodyVal)
|
||||
return stackFrame;
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleFrame(const QVariant &bodyVal)
|
||||
void QmlEnginePrivate::handleFrame(const QVariantMap &response)
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "response",
|
||||
@@ -2237,8 +2216,11 @@ void QmlEnginePrivate::handleFrame(const QVariant &bodyVal)
|
||||
// "running" : <is the VM running after sending this response>
|
||||
// "success" : true
|
||||
// }
|
||||
QVariantMap currentFrame = bodyVal.toMap();
|
||||
handleFrameHelper(response.value(_(BODY)).toMap());
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleFrameHelper(const QVariantMap ¤tFrame)
|
||||
{
|
||||
StackHandler *stackHandler = engine->stackHandler();
|
||||
WatchHandler * watchHandler = engine->watchHandler();
|
||||
watchHandler->notifyUpdateStarted();
|
||||
@@ -2295,7 +2277,7 @@ void QmlEnginePrivate::handleFrame(const QVariant &bodyVal)
|
||||
engine->stackFrameCompleted();
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleScope(const QVariant &bodyVal)
|
||||
void QmlEnginePrivate::handleScope(const QVariantMap &response)
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "response",
|
||||
@@ -2318,7 +2300,7 @@ void QmlEnginePrivate::handleScope(const QVariant &bodyVal)
|
||||
// "running" : <is the VM running after sending this response>
|
||||
// "success" : true
|
||||
// }
|
||||
QVariantMap bodyMap = bodyVal.toMap();
|
||||
QVariantMap bodyMap = response.value(_(BODY)).toMap();
|
||||
|
||||
//Check if the frameIndex is same as current Stack Index
|
||||
StackHandler *stackHandler = engine->stackHandler();
|
||||
@@ -2485,7 +2467,7 @@ void QmlEnginePrivate::handleEvaluate(int sequence, bool success, const QVariant
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleLookup(const QVariant &bodyVal)
|
||||
void QmlEnginePrivate::handleLookup(const QVariantMap &response)
|
||||
{
|
||||
// { "seq" : <number>,
|
||||
// "type" : "response",
|
||||
@@ -2495,7 +2477,7 @@ void QmlEnginePrivate::handleLookup(const QVariant &bodyVal)
|
||||
// "running" : <is the VM running after sending this response>
|
||||
// "success" : true
|
||||
// }
|
||||
const QVariantMap body = bodyVal.toMap();
|
||||
const QVariantMap body = response.value(_(BODY)).toMap();
|
||||
|
||||
QStringList handlesList = body.keys();
|
||||
WatchHandler *watchHandler = engine->watchHandler();
|
||||
@@ -2539,6 +2521,13 @@ void QmlEnginePrivate::stateChanged(State state)
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleVersion(const QVariantMap &response)
|
||||
{
|
||||
engine->showMessage(QString(_("Using V8 Version: %1")).arg(
|
||||
response.value(_(BODY)).toMap().
|
||||
value(_("V8Version")).toString()), LogOutput);
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::sendMessage(const QByteArray &msg)
|
||||
{
|
||||
if (state() == Enabled)
|
||||
|
||||
Reference in New Issue
Block a user