forked from qt-creator/qt-creator
ClangCodeModel: Show value in tool tips, if possible
When hovering over a constant expression, it's probably helpful to show that value to the user. Requires clang 11 to fully work. For now, it only shows the value for variable initializations. Fixes: QTCREATORBUG-23967 Change-Id: I6b844231bac50993c2fa2fa82c552ad9cef590df Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
#include <utf8string.h>
|
||||
#include <utf8stringvector.h>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ToolTipInfo
|
||||
@@ -54,6 +56,7 @@ public:
|
||||
out << message.qdocIdCandidates;
|
||||
out << message.qdocMark;
|
||||
out << static_cast<quint8>(message.qdocCategory);
|
||||
out << message.value;
|
||||
out << message.sizeInBytes;
|
||||
|
||||
return out;
|
||||
@@ -68,6 +71,7 @@ public:
|
||||
in >> message.qdocIdCandidates;
|
||||
in >> message.qdocMark;
|
||||
in >> qdocCategory;
|
||||
in >> message.value;
|
||||
in >> message.sizeInBytes;
|
||||
|
||||
message.qdocCategory = static_cast<QdocCategory>(qdocCategory);
|
||||
@@ -82,6 +86,7 @@ public:
|
||||
&& first.qdocIdCandidates == second.qdocIdCandidates
|
||||
&& first.qdocMark == second.qdocMark
|
||||
&& first.qdocCategory == second.qdocCategory
|
||||
&& first.value == second.value
|
||||
&& first.sizeInBytes == second.sizeInBytes;
|
||||
}
|
||||
|
||||
@@ -92,6 +97,7 @@ public:
|
||||
Utf8StringVector qdocIdCandidates;
|
||||
Utf8String qdocMark;
|
||||
QdocCategory qdocCategory = Unknown;
|
||||
QVariant value;
|
||||
|
||||
// For class definition and for class fields.
|
||||
Utf8String sizeInBytes;
|
||||
|
@@ -339,7 +339,7 @@ static CppTools::ToolTipInfo toToolTipInfo(const ToolTipMessage &message)
|
||||
info.qDocIdCandidates = toStringList(backendInfo.qdocIdCandidates);
|
||||
info.qDocMark = backendInfo.qdocMark;
|
||||
info.qDocCategory = toHelpItemCategory(backendInfo.qdocCategory);
|
||||
|
||||
info.value = backendInfo.value;
|
||||
info.sizeInBytes = backendInfo.sizeInBytes;
|
||||
|
||||
return info;
|
||||
|
@@ -181,6 +181,22 @@ void ClangHoverHandler::processToolTipInfo(const CppTools::ToolTipInfo &info)
|
||||
|
||||
if (!info.sizeInBytes.isEmpty())
|
||||
text.append("\n\n" + tr("%1 bytes").arg(info.sizeInBytes));
|
||||
if (info.value.isValid()) {
|
||||
text.append("\n\n" + tr("Value: "));
|
||||
switch (info.value.type()) {
|
||||
case static_cast<QVariant::Type>(QMetaType::LongLong):
|
||||
text.append(QString::number(info.value.toLongLong()));
|
||||
break;
|
||||
case static_cast<QVariant::Type>(QMetaType::ULongLong):
|
||||
text.append(QString::number(info.value.toULongLong()));
|
||||
break;
|
||||
case static_cast<QVariant::Type>(QMetaType::Double):
|
||||
text.append(QString::number(info.value.toDouble()));
|
||||
break;
|
||||
default:
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
setToolTip(text);
|
||||
m_reportPriority(priority());
|
||||
|
@@ -41,6 +41,8 @@
|
||||
|
||||
#include <QTextEdit>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace TextEditor {
|
||||
@@ -57,6 +59,7 @@ struct CPPTOOLS_EXPORT ToolTipInfo {
|
||||
QStringList qDocIdCandidates;
|
||||
QString qDocMark;
|
||||
Core::HelpItem::Category qDocCategory;
|
||||
QVariant value;
|
||||
|
||||
QString sizeInBytes;
|
||||
};
|
||||
|
@@ -149,6 +149,28 @@ Utf8String sizeInBytes(const Cursor &cursor)
|
||||
return Utf8String();
|
||||
}
|
||||
|
||||
QVariant value(const Cursor &cursor)
|
||||
{
|
||||
if (!clang_isDeclaration(cursor.cx().kind) && !clang_isExpression(cursor.cx().kind))
|
||||
return {};
|
||||
const CXEvalResult evalResult = clang_Cursor_Evaluate(cursor.cx());
|
||||
QVariant v;
|
||||
switch (clang_EvalResult_getKind(evalResult)) {
|
||||
case CXEval_Int:
|
||||
v = clang_EvalResult_isUnsignedInt(evalResult)
|
||||
? QVariant::fromValue(clang_EvalResult_getAsUnsigned(evalResult))
|
||||
: QVariant::fromValue(clang_EvalResult_getAsLongLong(evalResult));
|
||||
break;
|
||||
case CXEval_Float:
|
||||
v = QVariant::fromValue(clang_EvalResult_getAsDouble(evalResult));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
clang_EvalResult_dispose(evalResult);
|
||||
return v;
|
||||
}
|
||||
|
||||
Cursor referencedCursor(const Cursor &cursor)
|
||||
{
|
||||
// Query the referenced cursor directly instead of first testing with cursor.isReference().
|
||||
@@ -503,6 +525,7 @@ ToolTipInfo ToolTipInfoCollector::collect(uint line, uint column) const
|
||||
ToolTipInfo info;
|
||||
info.text = text(cursor, referenced);
|
||||
info.briefComment = referenced.briefComment();
|
||||
info.value = value(cursor);
|
||||
|
||||
{
|
||||
ToolTipInfo qDocToolTipInfo = qDocInfo(referenced);
|
||||
|
@@ -385,6 +385,15 @@ TEST_F(ToolTipInfo, SizeForUnion)
|
||||
ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("1"));
|
||||
}
|
||||
|
||||
TEST_F(ToolTipInfo, constexprValue)
|
||||
{
|
||||
// CLANG-UPGRADE-CHECK: Adapt the values below
|
||||
ASSERT_THAT(tooltip(204, 12).value.toInt(), 4);
|
||||
ASSERT_THAT(tooltip(204, 27).value.toInt(), 4); // 3 in clang 11
|
||||
ASSERT_THAT(tooltip(204, 30).value.toInt(), 4);
|
||||
ASSERT_THAT(tooltip(204, 32).value.toInt(), 4); // 1 in clang 11
|
||||
}
|
||||
|
||||
TEST_F(ToolTipInfo, Namespace)
|
||||
{
|
||||
::ToolTipInfo expected(Utf8StringLiteral("X"));
|
||||
|
@@ -199,3 +199,6 @@ Nuu **pointers(Nuu **p1)
|
||||
{
|
||||
return p1;
|
||||
}
|
||||
|
||||
static constexpr int calcValue() { return 1 + 2; }
|
||||
const auto val = calcValue() + sizeof(char);
|
||||
|
Reference in New Issue
Block a user