From bfbdec8427bdce8b593e5647274ab3e4a38e80a3 Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@nokia.com> Date: Fri, 16 Dec 2011 16:37:14 +0100 Subject: [PATCH] Avoid hitting the anonymous wrapper functions in .qml file QtDeclarative generates anonymous wrapper functions for QML bindings and slots, e.g. onPressed(): { i++ } becomes (function (onPressed) { i++ } ) v8 will by default break when the anonymous function is called, not when the actual code is executed. If we now hit this outer function we'll relocate the breakpoint to column = 1, and continue. Change-Id: Ieea4f4ea4fbf21d7245a6243fc36d141948ef2ce Reviewed-by: Aurindam Jana <aurindam.jana@nokia.com> --- .../debugger/qml/qmlv8debuggerclient.cpp | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index a76f8fef5f1..1f2d992550d 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -1383,7 +1383,50 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data) const QString eventType(resp.value(_(EVENT)).toString()); if (eventType == _("break")) { - if (d->engine->state() == InferiorRunOk) { + const QVariantMap breakData = resp.value(_(BODY)).toMap(); + const QString invocationText = breakData.value(_("invocationText")).toString(); + const QString scriptUrl = breakData.value(_("script")).toMap().value(_("name")).toString(); + const QString sourceLineText = breakData.value("sourceLineText").toString(); + + if (invocationText.startsWith(_("[anonymous]()")) + && scriptUrl.endsWith(_(".qml")) + && sourceLineText.trimmed().startsWith(QLatin1Char('('))) { + // we hit most likely the anonymous wrapper function automatically generated for bindings + // -> relocate the breakpoint to column: 1 and continue + + int newColumn = sourceLineText.indexOf(QLatin1Char('(')) + 1; + + QList<int> v8BreakpointIds; + { + const QVariantList v8BreakpointIdList = breakData.value(_("breakpoints")).toList(); + foreach (const QVariant &breakpointId, v8BreakpointIdList) + v8BreakpointIds << breakpointId.toInt(); + } + + BreakHandler *handler = d->engine->breakHandler(); + + foreach (int v8Id, v8BreakpointIds) { + BreakpointModelId internalId; + foreach (const BreakpointModelId &id, d->breakpoints.keys()) { + if (d->breakpoints.value(id) == v8Id) { + internalId = id; + break; + } + } + + if (internalId.isValid()) { + const BreakpointParameters ¶ms = handler->breakpointData(internalId); + + d->clearBreakpoint(v8Id); + const QString type = d->isOldService ? QString(_(SCRIPT)) :QString(_(SCRIPTREGEXP)); + d->setBreakpoint(type, QFileInfo(params.fileName).fileName(), + params.lineNumber - 1, newColumn, params.enabled, + QString(params.condition), params.ignoreCount); + d->breakpointsSync.insert(d->sequence, internalId); + } + } + d->continueDebugging(Continue); + } else if (d->engine->state() == InferiorRunOk) { d->engine->inferiorSpontaneousStop(); d->backtrace(); } -- GitLab