summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/debugger/qml/qmldebuggerclient.h3
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp240
-rw-r--r--src/plugins/debugger/qml/qmlengine.h4
-rw-r--r--src/plugins/debugger/qml/qmlv8debuggerclient.cpp82
-rw-r--r--src/plugins/debugger/qml/qmlv8debuggerclient.h3
-rw-r--r--src/plugins/debugger/qml/qscriptdebuggerclient.cpp41
-rw-r--r--src/plugins/debugger/qml/qscriptdebuggerclient.h3
7 files changed, 307 insertions, 69 deletions
diff --git a/src/plugins/debugger/qml/qmldebuggerclient.h b/src/plugins/debugger/qml/qmldebuggerclient.h
index 0a89e035fd..fcb7c607d8 100644
--- a/src/plugins/debugger/qml/qmldebuggerclient.h
+++ b/src/plugins/debugger/qml/qmldebuggerclient.h
@@ -69,7 +69,8 @@ public:
virtual void activateFrame(int index) = 0;
virtual bool acceptsBreakpoint(const BreakpointModelId &id);
- virtual void insertBreakpoint(const BreakpointModelId &id) = 0;
+ virtual void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ int adjustedColumn = -1) = 0;
virtual void removeBreakpoint(const BreakpointModelId &id) = 0;
virtual void changeBreakpoint(const BreakpointModelId &id) = 0;
virtual void synchronizeBreakpoints() = 0;
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 943c486952..e00d1ed7ff 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -58,6 +58,8 @@
#include <projectexplorer/applicationlauncher.h>
#include <qmljsdebugclient/qdeclarativeoutputparser.h>
#include <qmljseditor/qmljseditorconstants.h>
+#include <qmljs/parser/qmljsast_p.h>
+#include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
@@ -95,6 +97,8 @@
# define XSDEBUG(s) qDebug() << s
using namespace ProjectExplorer;
+using namespace QmlJS;
+using namespace AST;
namespace Debugger {
namespace Internal {
@@ -114,6 +118,7 @@ private:
QHash<QString, QWeakPointer<TextEditor::ITextEditor> > m_sourceEditors;
InteractiveInterpreter m_interpreter;
bool m_validContext;
+ QHash<QString,BreakpointModelId> pendingBreakpoints;
};
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q)
@@ -121,6 +126,163 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q)
m_validContext(false)
{}
+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 ast->lastSourceLocation().startLine >= *line && !done;
+ }
+
+ //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)
+ {
+ 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);
+ 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;
+};
///////////////////////////////////////////////////////////////////////
//
@@ -188,6 +350,11 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters,
connect(&d->m_noDebugOutputTimer, SIGNAL(timeout()), this, SLOT(beginConnection()));
qtMessageLogHandler()->setHasEditableRow(true);
+
+ connect(ModelManagerInterface::instance(),
+ SIGNAL(documentUpdated(QmlJS::Document::Ptr)),
+ this,
+ SLOT(documentUpdated(QmlJS::Document::Ptr)));
}
QmlEngine::~QmlEngine()
@@ -560,8 +727,14 @@ void QmlEngine::executeRunToLine(const ContextData &data)
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
showStatusMessage(tr("Run to line %1 (%2) requested...").arg(data.lineNumber).arg(data.fileName), 5000);
resetLocation();
+ ContextData modifiedData = data;
+ quint32 line = data.lineNumber;
+ quint32 column;
+ bool valid;
+ if (adjustBreakpointLineAndColumn(data.fileName, &line, &column, &valid))
+ modifiedData.lineNumber = line;
if (d->m_adapter.activeDebuggerClient())
- d->m_adapter.activeDebuggerClient()->executeRunToLine(data);
+ d->m_adapter.activeDebuggerClient()->executeRunToLine(modifiedData);
notifyInferiorRunRequested();
notifyInferiorRunOk();
}
@@ -601,11 +774,25 @@ void QmlEngine::insertBreakpoint(BreakpointModelId id)
QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << id << this << state);
handler->notifyBreakpointInsertProceeding(id);
+ const BreakpointParameters &params = handler->breakpointData(id);
+ quint32 line = params.lineNumber;
+ quint32 column = 0;
+ if (params.type == BreakpointByFileAndLine) {
+ bool valid = false;
+ if (!adjustBreakpointLineAndColumn(params.fileName, &line, &column,
+ &valid)) {
+ d->pendingBreakpoints.insertMulti(params.fileName, id);
+ return;
+ }
+ if (!valid)
+ return;
+ }
+
if (d->m_adapter.activeDebuggerClient()) {
- d->m_adapter.activeDebuggerClient()->insertBreakpoint(id);
+ d->m_adapter.activeDebuggerClient()->insertBreakpoint(id, line, column);
} else {
foreach (QmlDebuggerClient *client, d->m_adapter.debuggerClients()) {
- client->insertBreakpoint(id);
+ client->insertBreakpoint(id, line, column);
}
}
}
@@ -613,6 +800,21 @@ void QmlEngine::insertBreakpoint(BreakpointModelId id)
void QmlEngine::removeBreakpoint(BreakpointModelId id)
{
BreakHandler *handler = breakHandler();
+
+ const BreakpointParameters &params = handler->breakpointData(id);
+ if (params.type == BreakpointByFileAndLine &&
+ d->pendingBreakpoints.contains(params.fileName)) {
+ QHash<QString, BreakpointModelId>::iterator i =
+ d->pendingBreakpoints.find(params.fileName);
+ while (i != d->pendingBreakpoints.end() && i.key() == params.fileName) {
+ if (i.value() == id) {
+ d->pendingBreakpoints.erase(i);
+ return;
+ }
+ ++i;
+ }
+ }
+
BreakpointState state = handler->state(id);
QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << id << this << state);
handler->notifyBreakpointRemoveProceeding(id);
@@ -852,6 +1054,17 @@ void QmlEngine::disconnected()
notifyInferiorExited();
}
+void QmlEngine::documentUpdated(QmlJS::Document::Ptr doc)
+{
+ QString fileName = doc->fileName();
+ if (d->pendingBreakpoints.contains(fileName)) {
+ QList<BreakpointModelId> ids = d->pendingBreakpoints.values(fileName);
+ d->pendingBreakpoints.remove(fileName);
+ foreach (const BreakpointModelId &id, ids)
+ insertBreakpoint(id);
+ }
+}
+
void QmlEngine::updateCurrentContext()
{
const QString context = state() == InferiorStopOk ?
@@ -1085,6 +1298,27 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
return item;
}
+bool QmlEngine::adjustBreakpointLineAndColumn(
+ const QString &filePath, quint32 *line, quint32 *column, bool *valid)
+{
+ bool success = true;
+ //check if file is in the latest snapshot
+ //ignoring documentChangedOnDisk
+ //TODO:: update breakpoints if document is changed.
+ Document::Ptr doc = ModelManagerInterface::instance()->newestSnapshot().
+ document(filePath);
+ if (doc.isNull()) {
+ ModelManagerInterface::instance()->updateSourceFiles(
+ QStringList() << filePath, false);
+ success = false;
+ } else {
+ ASTWalker walker;
+ walker(doc->ast(), line, column);
+ *valid = walker.done;
+ }
+ return success;
+}
+
QmlAdapter *QmlEngine::adapter() const
{
return &d->m_adapter;
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 72cc70bdea..b8558c98e6 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -37,6 +37,7 @@
#include <qmljsdebugclient/qdeclarativeenginedebug.h>
#include <qmljsdebugclient/qdebugmessageclient.h>
#include <utils/outputformat.h>
+#include <qmljs/qmljsdocument.h>
#include <QAbstractSocket>
@@ -92,6 +93,7 @@ public:
public slots:
void disconnected();
+ void documentUpdated(QmlJS::Document::Ptr doc);
private slots:
void errorMessageBoxFinished(int result);
@@ -184,6 +186,8 @@ private:
bool canEvaluateScript(const QString &script);
QtMessageLogItem *constructLogItemTree(const QVariant &result,
const QString &key = QString());
+ bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line,
+ quint32 *column, bool *valid);
private:
friend class QmlCppEngine;
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
index 35e6c7e151..aaf4e6e6ea 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
@@ -105,8 +105,8 @@ public:
bool includeSource = false, const QVariant filter = QVariant());
void source(int frame = -1, int fromLine = -1, int toLine = -1);
- void setBreakpoint(const QString type, const QString target, int line = -1,
- int column = -1, bool enabled = true,
+ void setBreakpoint(const QString type, const QString target,
+ bool enabled = true,int line = 0, int column = 0,
const QString condition = QString(), int ignoreCount = -1);
void changeBreakpoint(int breakpoint, bool enabled = true,
const QString condition = QString(), int ignoreCount = -1);
@@ -513,7 +513,7 @@ void QmlV8DebuggerClientPrivate::source(int frame, int fromLine, int toLine)
}
void QmlV8DebuggerClientPrivate::setBreakpoint(const QString type, const QString target,
- int line, int column, bool enabled,
+ bool enabled, int line, int column,
const QString condition, int ignoreCount)
{
// { "seq" : <number>,
@@ -542,13 +542,17 @@ void QmlV8DebuggerClientPrivate::setBreakpoint(const QString type, const QString
QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
args.setProperty(_(TYPE), QScriptValue(type));
- args.setProperty(_(TARGET), QScriptValue(target));
+ if (type == _(SCRIPTREGEXP))
+ args.setProperty(_(TARGET),
+ QScriptValue(QFileInfo(target).fileName()));
+ else
+ args.setProperty(_(TARGET), QScriptValue(target));
- if (line != -1)
- args.setProperty(_(LINE), QScriptValue(line));
+ if (line)
+ args.setProperty(_(LINE), QScriptValue(line - 1));
- if (column != -1)
- args.setProperty(_(COLUMN), QScriptValue(column));
+ if (column)
+ args.setProperty(_(COLUMN), QScriptValue(column - 1));
args.setProperty(_(ENABLED), QScriptValue(enabled));
@@ -959,7 +963,7 @@ void QmlV8DebuggerClientPrivate::reformatRequest(QByteArray &request)
bool enabled;
rs >> signalHandler >> enabled;
- setBreakpoint(_(EVENT), QString::fromUtf8(signalHandler), -1, -1, enabled);
+ setBreakpoint(_(EVENT), QString::fromUtf8(signalHandler), enabled);
}
}
}
@@ -1050,8 +1054,8 @@ void QmlV8DebuggerClient::executeStepI()
void QmlV8DebuggerClient::executeRunToLine(const ContextData &data)
{
- d->setBreakpoint(QString(_(SCRIPTREGEXP)), QFileInfo(data.fileName).fileName(),
- data.lineNumber - 1);
+ d->setBreakpoint(QString(_(SCRIPTREGEXP)), data.fileName,
+ data.lineNumber);
clearExceptionSelection();
d->continueDebugging(Continue);
}
@@ -1082,7 +1086,9 @@ bool QmlV8DebuggerClient::acceptsBreakpoint(const BreakpointModelId &id)
|| type == BreakpointAtJavaScriptThrow);
}
-void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id)
+void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id,
+ int adjustedLine,
+ int adjustedColumn)
{
BreakHandler *handler = d->engine->breakHandler();
const BreakpointParameters &params = handler->breakpointData(id);
@@ -1092,14 +1098,12 @@ void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id)
d->setExceptionBreak(AllExceptions, params.enabled);
} else if (params.type == BreakpointByFileAndLine) {
- d->setBreakpoint(QString(_(SCRIPTREGEXP)),
- QFileInfo(params.fileName).fileName(),
- params.lineNumber - 1, -1, params.enabled,
+ d->setBreakpoint(QString(_(SCRIPTREGEXP)), params.fileName,
+ params.enabled, adjustedLine, adjustedColumn,
QLatin1String(params.condition), params.ignoreCount);
} else if (params.type == BreakpointOnQmlSignalHandler) {
- d->setBreakpoint(QString(_(EVENT)), params.functionName,
- -1, -1, params.enabled);
+ d->setBreakpoint(QString(_(EVENT)), params.functionName, params.enabled);
d->engine->breakHandler()->notifyBreakpointInsertOk(id);
}
@@ -1109,20 +1113,17 @@ void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id)
void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
{
BreakHandler *handler = d->engine->breakHandler();
+ const BreakpointParameters &params = handler->breakpointData(id);
int breakpoint = d->breakpoints.value(id);
d->breakpoints.remove(id);
- if (handler->breakpointData(id).type == BreakpointAtJavaScriptThrow) {
+ if (params.type == BreakpointAtJavaScriptThrow)
d->setExceptionBreak(AllExceptions);
-
- } else if (handler->breakpointData(id).type == BreakpointOnQmlSignalHandler) {
- d->setBreakpoint(QString(_(EVENT)), handler->breakpointData(id).functionName,
- -1, -1, false);
-
- } else {
+ else if (params.type == BreakpointOnQmlSignalHandler)
+ d->setBreakpoint(QString(_(EVENT)), params.functionName, false);
+ else
d->clearBreakpoint(breakpoint);
- }
}
void QmlV8DebuggerClient::changeBreakpoint(const BreakpointModelId &id)
@@ -1133,9 +1134,8 @@ void QmlV8DebuggerClient::changeBreakpoint(const BreakpointModelId &id)
if (params.type == BreakpointAtJavaScriptThrow) {
d->setExceptionBreak(AllExceptions, params.enabled);
- } else if (handler->breakpointData(id).type == BreakpointOnQmlSignalHandler) {
- d->setBreakpoint(QString(_(EVENT)), params.functionName,
- -1, -1, params.enabled);
+ } else if (params.type == BreakpointOnQmlSignalHandler) {
+ d->setBreakpoint(QString(_(EVENT)), params.functionName, params.enabled);
} else {
int breakpoint = d->breakpoints.value(id);
@@ -1311,8 +1311,15 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
BreakpointModelId id = d->breakpointsSync.take(seq);
d->breakpoints.insert(id, index);
- if (d->engine->breakHandler()->state(id) != BreakpointInserted)
- d->engine->breakHandler()->notifyBreakpointInsertOk(id);
+ BreakHandler *handler = d->engine->breakHandler();
+ if (handler->state(id) != BreakpointInserted) {
+ BreakpointResponse br = handler->response(id);
+ br.lineNumber = breakpointData.value(_("line")
+ ).toInt() + 1;
+ handler->setResponse(id, br);
+ handler->notifyBreakpointInsertOk(id);
+ }
+
} else {
d->breakpointsTemp.append(index);
@@ -1450,14 +1457,13 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
const BreakpointParameters &params = handler->breakpointData(internalId);
d->clearBreakpoint(v8Id);
- d->setBreakpoint(
- QString(_(SCRIPTREGEXP)),
- QFileInfo(params.fileName).fileName(),
- params.lineNumber - 1,
- newColumn,
- params.enabled,
- QString(params.condition),
- params.ignoreCount);
+ d->setBreakpoint(QString(_(SCRIPTREGEXP)),
+ params.fileName,
+ params.enabled,
+ params.lineNumber,
+ newColumn,
+ QString(params.condition),
+ params.ignoreCount);
d->breakpointsSync.insert(d->sequence, internalId);
}
}
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h
index 3f68b0e64e..c7cb0fbe36 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.h
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h
@@ -81,7 +81,8 @@ public:
void activateFrame(int index);
bool acceptsBreakpoint(const BreakpointModelId &id);
- void insertBreakpoint(const BreakpointModelId &id);
+ void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ int adjustedColumn = -1);
void removeBreakpoint(const BreakpointModelId &id);
void changeBreakpoint(const BreakpointModelId &id);
void synchronizeBreakpoints();
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
index c62c976844..6af0162e06 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
@@ -119,12 +119,13 @@ class QScriptDebuggerClientPrivate
{
public:
explicit QScriptDebuggerClientPrivate(QScriptDebuggerClient *) :
- ping(0), engine(0)
+ ping(0), sessionStarted(false), engine(0)
{
}
int ping;
+ bool sessionStarted;
QmlEngine *engine;
JSAgentBreakpoints breakpoints;
@@ -225,10 +226,12 @@ void QScriptDebuggerClient::startSession()
QTC_CHECK(handler->state(id) == BreakpointInsertProceeding);
handler->notifyBreakpointInsertOk(id);
}
+ d->sessionStarted = true;
}
void QScriptDebuggerClient::endSession()
{
+ d->sessionStarted = false;
}
void QScriptDebuggerClient::activateFrame(int index)
@@ -242,14 +245,22 @@ void QScriptDebuggerClient::activateFrame(int index)
sendMessage(reply);
}
-void QScriptDebuggerClient::insertBreakpoint(const BreakpointModelId &id)
+void QScriptDebuggerClient::insertBreakpoint(const BreakpointModelId &id,
+ int adjustedLine,
+ int /*adjustedColumn*/)
{
BreakHandler *handler = d->engine->breakHandler();
JSAgentBreakpointData bp;
bp.fileUrl = QUrl::fromLocalFile(handler->fileName(id)).toString().toUtf8();
- bp.lineNumber = handler->lineNumber(id);
+ bp.lineNumber = adjustedLine;
bp.functionName = handler->functionName(id).toUtf8();
d->breakpoints.insert(bp);
+
+ BreakpointResponse br = handler->response(id);
+ br.lineNumber = adjustedLine;
+ handler->setResponse(id, br);
+ if (d->sessionStarted && handler->state(id) == BreakpointInsertProceeding)
+ handler->notifyBreakpointInsertOk(id);
}
void QScriptDebuggerClient::removeBreakpoint(const BreakpointModelId &id)
@@ -266,7 +277,8 @@ void QScriptDebuggerClient::changeBreakpoint(const BreakpointModelId &id)
{
BreakHandler *handler = d->engine->breakHandler();
if (handler->isEnabled(id)) {
- insertBreakpoint(id);
+ BreakpointResponse br = handler->response(id);
+ insertBreakpoint(id, br.lineNumber);
} else {
removeBreakpoint(id);
}
@@ -461,33 +473,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
.arg(QLatin1String(stackFrames.value(0).fileUrl), Qt::escape(error));
showMessageBox(QMessageBox::Information, tr("Uncaught Exception"), msg);
} else {
- //
- // Make breakpoint non-pending
- //
QString file;
- QString function;
int line = -1;
if (!ideStackFrames.isEmpty()) {
file = ideStackFrames.at(0).file;
line = ideStackFrames.at(0).line;
- function = ideStackFrames.at(0).function;
- }
-
- BreakHandler *handler = d->engine->breakHandler();
- foreach (BreakpointModelId id, handler->engineBreakpointIds(d->engine)) {
- QString processedFilename = handler->fileName(id);
-
- if (processedFilename == file && handler->lineNumber(id) == line) {
- if (handler->state(id) == BreakpointInsertProceeding)
- handler->notifyBreakpointInsertOk(id);
- QTC_CHECK(handler->state(id) == BreakpointInserted);
- BreakpointResponse br = handler->response(id);
- br.fileName = file;
- br.lineNumber = line;
- br.functionName = function;
- handler->setResponse(id, br);
- }
}
QList<JSAgentBreakpointData> breakpoints(d->breakpoints.toList());
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.h b/src/plugins/debugger/qml/qscriptdebuggerclient.h
index 74716cdddd..58602723db 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.h
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.h
@@ -66,7 +66,8 @@ public:
void activateFrame(int index);
- void insertBreakpoint(const BreakpointModelId &id);
+ void insertBreakpoint(const BreakpointModelId &id, int adjustedLine,
+ int adjustedColumn = -1);
void removeBreakpoint(const BreakpointModelId &id);
void changeBreakpoint(const BreakpointModelId &id);
void synchronizeBreakpoints();