Commit 388a21c8 authored by Aurindam Jana's avatar Aurindam Jana
Browse files

QmlDebugger: Insert locals correctly



The watchhandler needs to be reset for locals before
inserting the values of a new frame. Also the DebuggerTooltipManager
needs to be notified. The values of the locals in the
LocalsAndExpressions window should be editable.

Task-number: QTCREATORBUG-7992
Change-Id: I556e23b408db09b510f1f2bc350ff55187ec87c2
Reviewed-by: default avatarRobert Loehning <robert.loehning@digia.com>
Reviewed-by: default avatarChristiaan Janssen <christiaan.janssen@digia.com>
parent 3f2e4374
......@@ -91,6 +91,7 @@ public:
signals:
void newStatus(QmlDebug::ClientStatus status);
void stackFrameCompleted();
protected:
virtual void statusChanged(QmlDebug::ClientStatus status);
......
......@@ -1013,9 +1013,8 @@ void QmlEngine::updateWatchData(const WatchData &data,
synchronizeWatchers();
}
if (!data.isSomethingNeeded())
watchHandler()->insertIncompleteData(data);
watchHandler()->insertData(data);
}
void QmlEngine::synchronizeWatchers()
......
......@@ -885,9 +885,6 @@ bool QmlInspectorAgent::isConnected() const
void QmlInspectorAgent::clearObjectTree()
{
// clear view
m_debuggerEngine->watchHandler()->cleanup();
m_objectTreeQueryIds.clear();
m_fetchDataIds.clear();
int old_count = m_debugIdHash.count();
......
......@@ -1186,6 +1186,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId
void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
{
d->engine = engine;
connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
}
void QmlV8DebuggerClient::getSourceFiles()
......@@ -1682,8 +1683,17 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
QVariantMap currentFrame = bodyVal.toMap();
StackHandler *stackHandler = d->engine->stackHandler();
WatchHandler * watchHandler = d->engine->watchHandler();
d->clearCache();
const int frameIndex = stackHandler->currentIndex();
watchHandler->removeAllData();
if (frameIndex < 0)
return;
const StackFrame frame = stackHandler->currentFrame();
if (!frame.isUsable())
return;
//Set "this" variable
{
WatchData data;
......@@ -1702,7 +1712,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
data.setHasChildren(true);
data.id = 0;
}
d->engine->watchHandler()->insertData(data);
watchHandler->insertData(data);
}
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
......@@ -1716,6 +1726,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
d->scope(scopeIndex);
}
d->engine->gotoLocation(stackHandler->currentFrame());
emit stackFrameCompleted();
}
void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &refsVal)
......
......@@ -401,6 +401,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
stream >> command;
WatchHandler *watchHandler = d->engine->watchHandler();
StackHandler *stackHandler = d->engine->stackHandler();
if (command == "STOPPED") {
d->engine->inferiorSpontaneousStop();
......@@ -426,35 +427,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
ideStackFrames << frame;
}
if (ideStackFrames.size() && ideStackFrames.back().function == QLatin1String("<global>"))
ideStackFrames.takeLast();
d->engine->stackHandler()->setFrames(ideStackFrames);
bool needPing = false;
foreach (WatchData data, watches) {
data.iname = watchHandler->watcherName(data.exp);
watchHandler->insertIncompleteData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname,data.id);
}
}
foreach (WatchData data, locals) {
data.iname = "local." + data.exp;
watchHandler->insertIncompleteData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname,data.id);
}
}
if (needPing)
sendPing();
stackHandler->setFrames(ideStackFrames);
bool becauseOfException;
stream >> becauseOfException;
......@@ -502,6 +475,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
if (!ideStackFrames.isEmpty())
d->engine->gotoLocation(ideStackFrames.value(0));
insertLocalsAndWatches(locals, watches, stackHandler->currentIndex());
} else if (command == "RESULT") {
WatchData data;
QByteArray iname;
......@@ -511,12 +486,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
data.iname = iname;
if (iname.startsWith("watch.")) {
watchHandler->insertIncompleteData(data);
watchHandler->insertData(data);
} else if (iname == "console") {
d->engine->showMessage(data.value, QtMessageLogOutput);
} else if (iname.startsWith("local.")) {
data.name = data.name.left(data.name.indexOf(QLatin1Char(' ')));
watchHandler->insertIncompleteData(data);
watchHandler->insertData(data);
} else {
qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
}
......@@ -531,7 +506,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
foreach (WatchData data, result) {
data.iname = iname + '.' + data.exp;
watchHandler->insertIncompleteData(data);
watchHandler->insertData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
......@@ -552,27 +527,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg(
QLatin1String(command), QString::number(frameId),
QString::number(locals.size()), QString::number(watches.size())));
bool needPing = false;
foreach (WatchData data, watches) {
data.iname = watchHandler->watcherName(data.exp);
watchHandler->insertIncompleteData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
foreach (WatchData data, locals) {
data.iname = "local." + data.exp;
watchHandler->insertIncompleteData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
if (needPing)
sendPing();
insertLocalsAndWatches(locals, watches, frameId);
} else if (command == "PONG") {
int ping;
......@@ -585,9 +541,50 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
}
void QScriptDebuggerClient::insertLocalsAndWatches(QList<WatchData> &locals,
QList<WatchData> &watches,
int stackFrameIndex)
{
WatchHandler *watchHandler = d->engine->watchHandler();
watchHandler->removeAllData();
if (stackFrameIndex < 0)
return;
const StackFrame frame = d->engine->stackHandler()->frameAt(stackFrameIndex);
if (!frame.isUsable())
return;
bool needPing = false;
foreach (WatchData data, watches) {
data.iname = watchHandler->watcherName(data.exp);
watchHandler->insertData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
foreach (WatchData data, locals) {
if (data.name == QLatin1String("<no initialized data>"))
data.name = tr("No Local Variables");
data.iname = "local." + data.exp;
watchHandler->insertData(data);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
if (needPing)
sendPing();
emit stackFrameCompleted();
}
void QScriptDebuggerClient::setEngine(QmlEngine *engine)
{
d->engine = engine;
connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
}
void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const
......
......@@ -86,6 +86,8 @@ protected:
private:
void sendPing();
void insertLocalsAndWatches(QList<WatchData> &locals, QList<WatchData> &watches,
int stackFrameIndex);
private:
QScriptDebuggerClientPrivate *d;
......
......@@ -193,7 +193,7 @@ private:
bool ancestorChanged(const QSet<QByteArray> &parentINames, WatchItem *item) const;
void insertBulkData(const QList<WatchData> &data);
QString displayForAutoTest(const QByteArray &iname) const;
void reinitialize();
void reinitialize(bool includeInspectData = false);
void destroyItem(WatchItem *item); // With model notification.
void destroyChildren(WatchItem *item); // With model notification.
void destroyHelper(const WatchItems &items); // Without model notification.
......@@ -315,7 +315,7 @@ WatchItem *WatchModel::createItem(const QByteArray &iname, const QString &name,
return item;
}
void WatchModel::reinitialize()
void WatchModel::reinitialize(bool includeInspectData)
{
CHECK(checkTree());
//MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
......@@ -324,8 +324,10 @@ void WatchModel::reinitialize()
destroyChildren(m_watchRoot);
destroyChildren(m_returnRoot);
destroyChildren(m_tooltipRoot);
destroyChildren(m_inspectorRoot);
QTC_CHECK(m_cache.size() == 6);
if (includeInspectData) {
destroyChildren(m_inspectorRoot);
QTC_CHECK(m_cache.size() == 6);
}
CHECK(checkTree());
}
......@@ -434,7 +436,7 @@ void WatchModel::reinsertAllData()
{
QList<WatchData> list;
reinsertAllDataHelper(m_root, &list);
reinitialize();
reinitialize(true);
insertBulkData(list);
}
......@@ -1516,9 +1518,9 @@ void WatchHandler::insertData(const QList<WatchData> &list)
updateWatchersWindow();
}
void WatchHandler::removeAllData()
void WatchHandler::removeAllData(bool includeInspectData)
{
m_model->reinitialize();
m_model->reinitialize(includeInspectData);
updateWatchersWindow();
}
......
......@@ -130,7 +130,7 @@ public:
void insertIncompleteData(const WatchData &data);
void removeData(const QByteArray &iname);
void removeChildren(const QByteArray &iname);
void removeAllData();
void removeAllData(bool includeInspectData = false);
void resetValueCache();
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment