forked from qt-creator/qt-creator
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: Robert Loehning <robert.loehning@digia.com> Reviewed-by: Christiaan Janssen <christiaan.janssen@digia.com>
This commit is contained in:
@@ -91,6 +91,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newStatus(QmlDebug::ClientStatus status);
|
void newStatus(QmlDebug::ClientStatus status);
|
||||||
|
void stackFrameCompleted();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void statusChanged(QmlDebug::ClientStatus status);
|
virtual void statusChanged(QmlDebug::ClientStatus status);
|
||||||
|
|||||||
@@ -1013,9 +1013,8 @@ void QmlEngine::updateWatchData(const WatchData &data,
|
|||||||
synchronizeWatchers();
|
synchronizeWatchers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!data.isSomethingNeeded())
|
if (!data.isSomethingNeeded())
|
||||||
watchHandler()->insertIncompleteData(data);
|
watchHandler()->insertData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlEngine::synchronizeWatchers()
|
void QmlEngine::synchronizeWatchers()
|
||||||
|
|||||||
@@ -885,9 +885,6 @@ bool QmlInspectorAgent::isConnected() const
|
|||||||
|
|
||||||
void QmlInspectorAgent::clearObjectTree()
|
void QmlInspectorAgent::clearObjectTree()
|
||||||
{
|
{
|
||||||
// clear view
|
|
||||||
m_debuggerEngine->watchHandler()->cleanup();
|
|
||||||
|
|
||||||
m_objectTreeQueryIds.clear();
|
m_objectTreeQueryIds.clear();
|
||||||
m_fetchDataIds.clear();
|
m_fetchDataIds.clear();
|
||||||
int old_count = m_debugIdHash.count();
|
int old_count = m_debugIdHash.count();
|
||||||
|
|||||||
@@ -1186,6 +1186,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId
|
|||||||
void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
|
void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
|
||||||
{
|
{
|
||||||
d->engine = engine;
|
d->engine = engine;
|
||||||
|
connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::getSourceFiles()
|
void QmlV8DebuggerClient::getSourceFiles()
|
||||||
@@ -1682,8 +1683,17 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
|
|||||||
QVariantMap currentFrame = bodyVal.toMap();
|
QVariantMap currentFrame = bodyVal.toMap();
|
||||||
|
|
||||||
StackHandler *stackHandler = d->engine->stackHandler();
|
StackHandler *stackHandler = d->engine->stackHandler();
|
||||||
|
WatchHandler * watchHandler = d->engine->watchHandler();
|
||||||
d->clearCache();
|
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
|
//Set "this" variable
|
||||||
{
|
{
|
||||||
WatchData data;
|
WatchData data;
|
||||||
@@ -1702,7 +1712,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
|
|||||||
data.setHasChildren(true);
|
data.setHasChildren(true);
|
||||||
data.id = 0;
|
data.id = 0;
|
||||||
}
|
}
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
|
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
|
||||||
@@ -1716,6 +1726,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
|
|||||||
d->scope(scopeIndex);
|
d->scope(scopeIndex);
|
||||||
}
|
}
|
||||||
d->engine->gotoLocation(stackHandler->currentFrame());
|
d->engine->gotoLocation(stackHandler->currentFrame());
|
||||||
|
emit stackFrameCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &refsVal)
|
void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &refsVal)
|
||||||
|
|||||||
@@ -401,6 +401,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
stream >> command;
|
stream >> command;
|
||||||
|
|
||||||
WatchHandler *watchHandler = d->engine->watchHandler();
|
WatchHandler *watchHandler = d->engine->watchHandler();
|
||||||
|
StackHandler *stackHandler = d->engine->stackHandler();
|
||||||
|
|
||||||
if (command == "STOPPED") {
|
if (command == "STOPPED") {
|
||||||
d->engine->inferiorSpontaneousStop();
|
d->engine->inferiorSpontaneousStop();
|
||||||
@@ -426,35 +427,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
ideStackFrames << frame;
|
ideStackFrames << frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ideStackFrames.size() && ideStackFrames.back().function == QLatin1String("<global>"))
|
stackHandler->setFrames(ideStackFrames);
|
||||||
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();
|
|
||||||
|
|
||||||
bool becauseOfException;
|
bool becauseOfException;
|
||||||
stream >> becauseOfException;
|
stream >> becauseOfException;
|
||||||
@@ -502,6 +475,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
if (!ideStackFrames.isEmpty())
|
if (!ideStackFrames.isEmpty())
|
||||||
d->engine->gotoLocation(ideStackFrames.value(0));
|
d->engine->gotoLocation(ideStackFrames.value(0));
|
||||||
|
|
||||||
|
insertLocalsAndWatches(locals, watches, stackHandler->currentIndex());
|
||||||
|
|
||||||
} else if (command == "RESULT") {
|
} else if (command == "RESULT") {
|
||||||
WatchData data;
|
WatchData data;
|
||||||
QByteArray iname;
|
QByteArray iname;
|
||||||
@@ -511,12 +486,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
|
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
|
||||||
data.iname = iname;
|
data.iname = iname;
|
||||||
if (iname.startsWith("watch.")) {
|
if (iname.startsWith("watch.")) {
|
||||||
watchHandler->insertIncompleteData(data);
|
watchHandler->insertData(data);
|
||||||
} else if (iname == "console") {
|
} else if (iname == "console") {
|
||||||
d->engine->showMessage(data.value, QtMessageLogOutput);
|
d->engine->showMessage(data.value, QtMessageLogOutput);
|
||||||
} else if (iname.startsWith("local.")) {
|
} else if (iname.startsWith("local.")) {
|
||||||
data.name = data.name.left(data.name.indexOf(QLatin1Char(' ')));
|
data.name = data.name.left(data.name.indexOf(QLatin1Char(' ')));
|
||||||
watchHandler->insertIncompleteData(data);
|
watchHandler->insertData(data);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
|
qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
|
||||||
}
|
}
|
||||||
@@ -531,7 +506,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
|
|
||||||
foreach (WatchData data, result) {
|
foreach (WatchData data, result) {
|
||||||
data.iname = iname + '.' + data.exp;
|
data.iname = iname + '.' + data.exp;
|
||||||
watchHandler->insertIncompleteData(data);
|
watchHandler->insertData(data);
|
||||||
|
|
||||||
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
needPing = true;
|
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(
|
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg(
|
||||||
QLatin1String(command), QString::number(frameId),
|
QLatin1String(command), QString::number(frameId),
|
||||||
QString::number(locals.size()), QString::number(watches.size())));
|
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) {
|
insertLocalsAndWatches(locals, watches, frameId);
|
||||||
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();
|
|
||||||
|
|
||||||
} else if (command == "PONG") {
|
} else if (command == "PONG") {
|
||||||
int ping;
|
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)
|
void QScriptDebuggerClient::setEngine(QmlEngine *engine)
|
||||||
{
|
{
|
||||||
d->engine = engine;
|
d->engine = engine;
|
||||||
|
connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const
|
void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void sendPing();
|
void sendPing();
|
||||||
|
void insertLocalsAndWatches(QList<WatchData> &locals, QList<WatchData> &watches,
|
||||||
|
int stackFrameIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScriptDebuggerClientPrivate *d;
|
QScriptDebuggerClientPrivate *d;
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ private:
|
|||||||
bool ancestorChanged(const QSet<QByteArray> &parentINames, WatchItem *item) const;
|
bool ancestorChanged(const QSet<QByteArray> &parentINames, WatchItem *item) const;
|
||||||
void insertBulkData(const QList<WatchData> &data);
|
void insertBulkData(const QList<WatchData> &data);
|
||||||
QString displayForAutoTest(const QByteArray &iname) const;
|
QString displayForAutoTest(const QByteArray &iname) const;
|
||||||
void reinitialize();
|
void reinitialize(bool includeInspectData = false);
|
||||||
void destroyItem(WatchItem *item); // With model notification.
|
void destroyItem(WatchItem *item); // With model notification.
|
||||||
void destroyChildren(WatchItem *item); // With model notification.
|
void destroyChildren(WatchItem *item); // With model notification.
|
||||||
void destroyHelper(const WatchItems &items); // Without 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;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchModel::reinitialize()
|
void WatchModel::reinitialize(bool includeInspectData)
|
||||||
{
|
{
|
||||||
CHECK(checkTree());
|
CHECK(checkTree());
|
||||||
//MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
|
//MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
|
||||||
@@ -324,8 +324,10 @@ void WatchModel::reinitialize()
|
|||||||
destroyChildren(m_watchRoot);
|
destroyChildren(m_watchRoot);
|
||||||
destroyChildren(m_returnRoot);
|
destroyChildren(m_returnRoot);
|
||||||
destroyChildren(m_tooltipRoot);
|
destroyChildren(m_tooltipRoot);
|
||||||
destroyChildren(m_inspectorRoot);
|
if (includeInspectData) {
|
||||||
QTC_CHECK(m_cache.size() == 6);
|
destroyChildren(m_inspectorRoot);
|
||||||
|
QTC_CHECK(m_cache.size() == 6);
|
||||||
|
}
|
||||||
CHECK(checkTree());
|
CHECK(checkTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +436,7 @@ void WatchModel::reinsertAllData()
|
|||||||
{
|
{
|
||||||
QList<WatchData> list;
|
QList<WatchData> list;
|
||||||
reinsertAllDataHelper(m_root, &list);
|
reinsertAllDataHelper(m_root, &list);
|
||||||
reinitialize();
|
reinitialize(true);
|
||||||
insertBulkData(list);
|
insertBulkData(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1516,9 +1518,9 @@ void WatchHandler::insertData(const QList<WatchData> &list)
|
|||||||
updateWatchersWindow();
|
updateWatchersWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchHandler::removeAllData()
|
void WatchHandler::removeAllData(bool includeInspectData)
|
||||||
{
|
{
|
||||||
m_model->reinitialize();
|
m_model->reinitialize(includeInspectData);
|
||||||
updateWatchersWindow();
|
updateWatchersWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public:
|
|||||||
void insertIncompleteData(const WatchData &data);
|
void insertIncompleteData(const WatchData &data);
|
||||||
void removeData(const QByteArray &iname);
|
void removeData(const QByteArray &iname);
|
||||||
void removeChildren(const QByteArray &iname);
|
void removeChildren(const QByteArray &iname);
|
||||||
void removeAllData();
|
void removeAllData(bool includeInspectData = false);
|
||||||
void resetValueCache();
|
void resetValueCache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user