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 &params = 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