Commit 011ddc09 authored by hjk's avatar hjk
Browse files

Debugger: Fix async tooltip handling



For now, only the gdb engine can handle complex tooltips
requiring async re-evaluation, cdb and lldb will show
and expand only items that are available in the Locals view.

This patch disables also the save/restore feature for
pinned tooltips.

Task-number: QTCREATORBUG-13255
Task-number: QTCREATORBUG-13052
Change-Id: Ic25616fede0f5c4343a92b631f01e60bfc5e9d81
Reviewed-by: default avatarDavid Schulz <david.schulz@theqtcompany.com>
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 620ded80
......@@ -442,28 +442,14 @@ void CdbEngine::syncVerboseLog(bool verboseLog)
}
bool CdbEngine::setToolTipExpression(TextEditor::TextEditorWidget *editorWidget,
const DebuggerToolTipContext &contextIn)
const DebuggerToolTipContext &context)
{
if (debug)
qDebug() << Q_FUNC_INFO;
// Need a stopped debuggee and a cpp file in a valid frame
if (state() != InferiorStopOk || !isCppEditor(editorWidget) || stackHandler()->currentIndex() < 0)
return false;
// Determine expression and function
int line;
int column;
DebuggerToolTipContext context = contextIn;
QString exp = fixCppExpression(cppExpressionAt(editorWidget, context.position, &line, &column, &context.function));
// Are we in the current stack frame
if (context.function.isEmpty() || exp.isEmpty() || context.function != stackHandler()->currentFrame().function)
return false;
// Show tooltips of local variables only. Anything else can slow debugging down.
const WatchData *localVariable = watchHandler()->findCppLocalVariable(exp);
if (!localVariable)
return false;
context.iname = localVariable->iname;
DebuggerToolTipManager::showToolTip(context, this);
return true;
Q_UNUSED(editorWidget);
Q_UNUSED(context);
// Tooltips matching local variables are already handled in the
// base class. We don't handle anything else here in CDB
// as it can slow debugging down.
return false;
}
// Determine full path to the CDB extension library.
......
......@@ -78,7 +78,7 @@ public:
// Factory function that returns 0 if the debug engine library cannot be found.
virtual bool setToolTipExpression(TextEditor::TextEditorWidget *editorWidget,
const DebuggerToolTipContext &ctx);
const DebuggerToolTipContext &context);
virtual void setupEngine();
virtual void setupInferior();
virtual void runEngine();
......
......@@ -269,6 +269,7 @@ public slots:
m_watchHandler.resetLocation();
m_threadsHandler.resetLocation();
m_disassemblerAgent.resetLocation();
DebuggerToolTipManager::resetLocation();
}
public:
......
......@@ -83,12 +83,7 @@ public:
static void updateEngine(DebuggerEngine *engine);
static bool hasToolTips();
// Collect all expressions of DebuggerTreeViewToolTipWidget
static DebuggerToolTipContexts treeWidgetExpressions(DebuggerEngine *engine,
const QString &fileName, const QString &function = QString());
static void showToolTip(const DebuggerToolTipContext &context,
DebuggerEngine *engine);
static DebuggerToolTipContexts pendingTooltips(DebuggerEngine *engine);
virtual bool eventFilter(QObject *, QEvent *);
......@@ -100,9 +95,12 @@ public:
static void loadSessionData();
static void saveSessionData();
static void closeAllToolTips();
static void resetLocation();
public slots:
static void slotUpdateVisibleToolTips();
void slotItemIsExpanded(const QModelIndex &idx);
void slotColumnAdjustmentRequested();
};
} // namespace Internal
......
......@@ -3632,43 +3632,16 @@ void GdbEngine::handleRegisterListValues(const GdbResponse &response)
//
//////////////////////////////////////////////////////////////////////
//void GdbEngine::showToolTip()
//{
// const QString expression = m_toolTipContext.expression;
// if (DebuggerToolTipManager::debug())
// qDebug() << "GdbEngine::showToolTip " << expression << m_toolTipContext.iname << m_toolTipContext;
// if (m_toolTipContext.iname.startsWith("tooltip")
// && (!boolSetting(UseToolTipsInMainEditor)
// || !watchHandler()->isValidToolTip(m_toolTipContext.iname))) {
// watchHandler()->removeData(m_toolTipContext.iname);
// return;
// }
// DebuggerToolTipManager::showToolTip(m_toolTipContext, this);
//}
void GdbEngine::resetLocation()
{
m_toolTipContext.expression.clear();
DebuggerEngine::resetLocation();
}
bool GdbEngine::setToolTipExpression(TextEditor::TextEditorWidget *editor,
const DebuggerToolTipContext &context)
{
if (state() != InferiorStopOk || !isCppEditor(editor)) {
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED "
// " OR NOT A CPPEDITOR";
if (state() != InferiorStopOk || !isCppEditor(editor))
return false;
}
m_toolTipContext = context;
// qDebug() << "GdbEngine::setToolTipExpression2 " << exp << m_toolTipContext;
UpdateParameters params;
params.tryPartial = true;
params.tooltipOnly = true;
params.tooltipExpression = context.expression;
params.varList = context.iname;
updateLocalsPython(params);
return true;
......@@ -3736,10 +3709,6 @@ void GdbEngine::rebuildWatchModel()
showMessage(_("<Rebuild Watchmodel %1>").arg(count), LogMiscInput);
showStatusMessage(tr("Finished retrieving data"), 400);
if (m_toolTipContext.isValid()) {
DebuggerToolTipManager::showToolTip(m_toolTipContext, this);
m_toolTipContext = DebuggerToolTipContext();
}
DebuggerToolTipManager::updateEngine(this);
}
......@@ -4829,42 +4798,16 @@ void GdbEngine::updateLocalsPython(const UpdateParameters &params)
+ " displaystringlimit:"
+ action(DisplayStringLimit)->value().toByteArray();
// Re-create tooltip items that are not filters on existing local variables in
// the tooltip model.
QByteArray watchers;
const QString fileName = stackHandler()->currentFrame().file;
const QString function = stackHandler()->currentFrame().function;
if (!fileName.isEmpty()) {
// Re-create tooltip items that are not filters on existing local variables in
// the tooltip model.
DebuggerToolTipContexts toolTips =
DebuggerToolTipManager::treeWidgetExpressions(this, fileName, function);
const QString currentExpression = m_toolTipContext.expression;
if (!currentExpression.isEmpty()) {
int currentIndex = -1;
for (int i = 0; i < toolTips.size(); ++i) {
if (toolTips.at(i).expression == currentExpression) {
currentIndex = i;
break;
}
}
if (currentIndex < 0) {
DebuggerToolTipContext context;
context.expression = currentExpression;
context.iname = tooltipIName(currentExpression);
toolTips.push_back(context);
}
}
foreach (const DebuggerToolTipContext &p, toolTips) {
if (p.iname.startsWith("tooltip")) {
if (!watchers.isEmpty())
watchers += "##";
watchers += p.expression.toLatin1();
watchers += '#';
watchers += p.iname;
}
}
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(this);
foreach (const DebuggerToolTipContext &p, toolTips) {
if (!watchers.isEmpty())
watchers += "##";
watchers += p.expression.toLatin1();
watchers += '#';
watchers += p.iname;
}
QHash<QByteArray, int> watcherNames = handler->watcherNames();
......
......@@ -298,7 +298,6 @@ private: ////////// View & Data Stuff //////////
void selectThread(ThreadId threadId);
void activateFrame(int index);
void resetLocation();
//
// Breakpoint specific stuff
......@@ -469,7 +468,6 @@ protected:
void showExecutionError(const QString &message);
static QByteArray tooltipIName(const QString &exp);
DebuggerToolTipContext m_toolTipContext;
// For short-circuiting stack and thread list evaluation.
bool m_stackNeeded;
......
......@@ -74,11 +74,6 @@ using namespace Utils;
namespace Debugger {
namespace Internal {
static QByteArray tooltipIName(const QString &exp)
{
return "tooltip." + exp.toLatin1().toHex();
}
///////////////////////////////////////////////////////////////////////
//
// LldbEngine
......@@ -815,41 +810,25 @@ void LldbEngine::refreshSymbols(const GdbMi &symbols)
//
//////////////////////////////////////////////////////////////////////
static WatchData m_toolTip;
static QPoint m_toolTipPos;
static QHash<QString, WatchData> m_toolTipCache;
void LldbEngine::showToolTip()
{
if (m_toolTipContext.expression.isEmpty())
return;
//const QString expression = m_toolTipContext->expression;
// qDebug() << "LldbEngine::showToolTip " << expression << m_toolTipContext->iname << (*m_toolTipContext);
DebuggerToolTipManager::showToolTip(m_toolTipContext, this);
// Prevent tooltip from re-occurring (classic GDB, QTCREATORBUG-4711).
m_toolTipContext.expression.clear();
}
void LldbEngine::resetLocation()
{
m_toolTipContext.expression.clear();
DebuggerEngine::resetLocation();
}
bool LldbEngine::setToolTipExpression(TextEditor::TextEditorWidget *editorWidget, const DebuggerToolTipContext &context)
{
return false; // FIXME
if (state() != InferiorStopOk || !isCppEditor(editorWidget)) {
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED "
// " OR NOT A CPPEDITOR";
return false;
}
m_toolTipContext = context;
UpdateParameters params;
params.tryPartial = true;
params.tooltipOnly = true;
params.tooltipExpression = context.expression;
params.varList = context.iname;
doUpdateLocals(params);
......@@ -924,6 +903,7 @@ void LldbEngine::doUpdateLocals(UpdateParameters params)
cmd.arg("tooltiponly", params.tooltipOnly);
cmd.beginList("watchers");
// Watchers
QHashIterator<QByteArray, int> it(WatchHandler::watcherNames());
while (it.hasNext()) {
......@@ -933,38 +913,16 @@ void LldbEngine::doUpdateLocals(UpdateParameters params)
.arg("exp", it.key().toHex())
.endGroup();
}
// Tooltip
const StackFrame frame = stackHandler()->currentFrame();
if (!frame.file.isEmpty()) {
// Re-create tooltip items that are not filters on existing local variables in
// the tooltip model.
DebuggerToolTipContexts toolTips =
DebuggerToolTipManager::treeWidgetExpressions(this, frame.file, frame.function);
const QString currentExpression = m_toolTipContext.expression;
if (!currentExpression.isEmpty()) {
int currentIndex = -1;
for (int i = 0; i < toolTips.size(); ++i) {
if (toolTips.at(i).expression == currentExpression) {
currentIndex = i;
break;
}
}
if (currentIndex < 0) {
DebuggerToolTipContext context;
context.expression = currentExpression;
context.iname = tooltipIName(currentExpression);
toolTips.push_back(context);
}
}
foreach (const DebuggerToolTipContext &p, toolTips) {
if (p.iname.startsWith("tooltip"))
cmd.beginGroup()
.arg("iname", p.iname)
.arg("exp", p.expression.toLatin1().toHex())
.endGroup();
}
// Tooltips
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(this);
foreach (const DebuggerToolTipContext &p, toolTips) {
cmd.beginGroup()
.arg("iname", p.iname)
.arg("exp", p.expression.toLatin1().toHex())
.endGroup();
}
cmd.endList();
//cmd.arg("resultvarname", m_resultVarName);
......@@ -1083,7 +1041,7 @@ void LldbEngine::refreshLocals(const GdbMi &vars)
}
handler->insertData(list);
showToolTip();
DebuggerToolTipManager::updateEngine(this);
}
void LldbEngine::refreshStack(const GdbMi &stack)
......
......@@ -218,9 +218,6 @@ private:
QMap<QPointer<DisassemblerAgent>, int> m_disassemblerAgents;
QMap<QPointer<MemoryAgent>, int> m_memoryAgents;
QHash<int, QPointer<QObject> > m_memoryAgentTokens;
DebuggerToolTipContext m_toolTipContext;
void showToolTip();
// Console handling.
Q_SLOT void stubError(const QString &msg);
......
......@@ -2015,10 +2015,10 @@ const WatchData *WatchHandler::findCppLocalVariable(const QString &name) const
QByteArray iname = localsPrefix + name.toLatin1();
if (const WatchData *wd = findData(iname))
return wd;
// Nope, try a 'local.this.m_foo'.
iname.insert(localsPrefix.size(), "this.");
if (const WatchData *wd = findData(iname))
return wd;
// // Nope, try a 'local.this.m_foo'.
// iname.insert(localsPrefix.size(), "this.");
// if (const WatchData *wd = findData(iname))
// return wd;
return 0;
}
......
......@@ -121,6 +121,7 @@ public:
bool tryPartial;
bool tooltipOnly;
QByteArray varList;
QString tooltipExpression;
};
typedef QHash<QString, QStringList> DumperTypeFormats; // Type name -> Dumper Formats
......
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