diff --git a/src/plugins/debugger/qml/qmldebuggerclient.h b/src/plugins/debugger/qml/qmldebuggerclient.h index 11eafe213cb48566674b10301a2976b69795f925..df93d70310d67784ba82cdf09113ed468ffccf33 100644 --- a/src/plugins/debugger/qml/qmldebuggerclient.h +++ b/src/plugins/debugger/qml/qmldebuggerclient.h @@ -34,6 +34,7 @@ #define QMLDEBUGGERCLIENT_H #include "qmljsprivateapi.h" +#include "debuggerengine.h" namespace Debugger { namespace Internal { @@ -60,6 +61,8 @@ public: virtual void executeNext() = 0; virtual void executeStepI() = 0; + virtual void executeRunToLine(const ContextData &data) = 0; + virtual void continueInferior() = 0; virtual void interruptInferior() = 0; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index d300f8685cd82061a6f6f918e563ad7c62346d78..4cad9eba62fec2dc8d8712e78524eb9c3c9bff8f 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -530,8 +530,13 @@ void QmlEngine::executeNextI() void QmlEngine::executeRunToLine(const ContextData &data) { - Q_UNUSED(data) - SDEBUG("FIXME: QmlEngine::executeRunToLine()"); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + showStatusMessage(tr("Run to line %1 (%2) requested...").arg(data.lineNumber).arg(data.fileName), 5000); + resetLocation(); + if (d->m_adapter.activeDebuggerClient()) + d->m_adapter.activeDebuggerClient()->executeRunToLine(data); + notifyInferiorRunRequested(); + notifyInferiorRunOk(); } void QmlEngine::executeRunToFunction(const QString &functionName) @@ -777,7 +782,9 @@ void QmlEngine::synchronizeWatchers() unsigned QmlEngine::debuggerCapabilities() const { - return AddWatcherCapability|AddWatcherWhileRunningCapability; + return AddWatcherCapability + | AddWatcherWhileRunningCapability + | RunToLineCapability; /*ReverseSteppingCapability | SnapshotCapability | AutoDerefPointersCapability | DisassemblerCapability | RegisterCapability | ShowMemoryCapability diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index b326a340b3e5f2f0753b5e781c1a4e4bcb5b1249..03afa154ae0330ce044eb0901d5d02ca72a43782 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -138,6 +138,7 @@ public: QmlEngine *engine; QHash<BreakpointModelId, int> breakpoints; QHash<int, BreakpointModelId> breakpointsSync; + QList<int> breakpointsTemp; QScriptValue parser; QScriptValue stringifier; @@ -1019,6 +1020,19 @@ void QmlV8DebuggerClient::executeStepI() d->continueDebugging(In); } +void QmlV8DebuggerClient::executeRunToLine(const ContextData &data) +{ + if (d->isOldService) { + d->setBreakpoint(QString(_(SCRIPT)), QFileInfo(data.fileName).fileName(), + data.lineNumber - 1); + } else { + d->setBreakpoint(QString(_(SCRIPTREGEXP)), QFileInfo(data.fileName).fileName(), + data.lineNumber - 1); + } + clearExceptionSelection(); + d->continueDebugging(Continue); +} + void QmlV8DebuggerClient::continueInferior() { clearExceptionSelection(); @@ -1282,11 +1296,16 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data) const QVariantMap breakpointData = resp.value(_(BODY)).toMap(); int index = breakpointData.value(_("breakpoint")).toInt(); - BreakpointModelId id = d->breakpointsSync.take(seq); - d->breakpoints.insert(id, index); + if (d->breakpointsSync.contains(seq)) { + BreakpointModelId id = d->breakpointsSync.take(seq); + d->breakpoints.insert(id, index); - if (d->engine->breakHandler()->state(id) != BreakpointInserted) - d->engine->breakHandler()->notifyBreakpointInsertOk(id); + if (d->engine->breakHandler()->state(id) != BreakpointInserted) + d->engine->breakHandler()->notifyBreakpointInsertOk(id); + + } else { + d->breakpointsTemp.append(index); + } } else if (debugCommand == _(CHANGEBREAKPOINT)) { @@ -1447,6 +1466,10 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data) } if (d->engine->state() == InferiorRunOk) { + foreach (const QVariant &breakpointId, v8BreakpointIds) { + if (d->breakpointsTemp.contains(breakpointId.toInt())) + d->clearBreakpoint(breakpointId.toInt()); + } d->engine->inferiorSpontaneousStop(); d->backtrace(); } else if (d->engine->state() == InferiorStopOk) { diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h index 944f1cda986ad902f8f92f80e52d46a56e44d3a3..d663da15aef3a603a34ed251dcb58c25c4ae02d6 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.h +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h @@ -73,6 +73,8 @@ public: void executeNext(); void executeStepI(); + void executeRunToLine(const ContextData &data); + void continueInferior(); void interruptInferior(); diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 19d6fe9285ea9ba4ce3b7c9a76da0853d3e6991d..f8ad0c944f48a314a0fe22ae303e7a4a28fc1bbd 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -183,6 +183,17 @@ void QScriptDebuggerClient::executeStepI() sendMessage(reply); } +void QScriptDebuggerClient::executeRunToLine(const ContextData &data) +{ + JSAgentBreakpointData bp; + bp.fileUrl = QUrl::fromLocalFile(data.fileName).toString().toUtf8(); + bp.lineNumber = data.lineNumber; + bp.functionName = "TEMPORARY"; + d->breakpoints.insert(bp); + synchronizeBreakpoints(); + continueInferior(); +} + void QScriptDebuggerClient::continueInferior() { QByteArray reply; @@ -398,6 +409,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) if (ideStackFrames.size() && ideStackFrames.back().function == QLatin1String("<global>")) ideStackFrames.takeLast(); + d->engine->stackHandler()->setFrames(ideStackFrames); d->engine->watchHandler()->beginCycle(); @@ -478,6 +490,18 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) } } + QList<JSAgentBreakpointData> breakpoints(d->breakpoints.toList()); + foreach (const JSAgentBreakpointData &data, breakpoints) { + if (data.fileUrl == QUrl::fromLocalFile(file).toString().toUtf8() && + data.lineNumber == line && + data.functionName == "TEMPORARY") { + breakpoints.removeOne(data); + d->breakpoints = JSAgentBreakpoints::fromList(breakpoints); + synchronizeBreakpoints(); + break; + } + } + d->logReceiveMessage(logString); } diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.h b/src/plugins/debugger/qml/qscriptdebuggerclient.h index fe8b539db2e81e2c5af1fdfdd7622b5aad10ed3e..ccae14680c98906176429503fba3af1f560a7e21 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.h +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.h @@ -59,6 +59,8 @@ public: void executeNext(); void executeStepI(); + void executeRunToLine(const ContextData &data); + void continueInferior(); void interruptInferior();