diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-05-18 17:40:19 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-05-26 08:50:58 +0000 |
commit | 949bb0e67bbf6e7d8208dad9876382ef8ce5eb59 (patch) | |
tree | b850c89d83d3cffaba326dda7426b180b88212da | |
parent | 227904d4a691b99789f1dc43f9b31d857279c896 (diff) | |
download | qt-creator-949bb0e67bbf6e7d8208dad9876382ef8ce5eb59.tar.gz |
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>
-rw-r--r-- | src/libs/clangsupport/tooltipinfo.h | 6 | ||||
-rw-r--r-- | src/plugins/clangcodemodel/clangbackendreceiver.cpp | 2 | ||||
-rw-r--r-- | src/plugins/clangcodemodel/clanghoverhandler.cpp | 16 | ||||
-rw-r--r-- | src/plugins/cpptools/baseeditordocumentprocessor.h | 3 | ||||
-rw-r--r-- | src/tools/clangbackend/source/clangtooltipinfocollector.cpp | 23 | ||||
-rw-r--r-- | tests/unit/unittest/clangtooltipinfo-test.cpp | 9 | ||||
-rw-r--r-- | tests/unit/unittest/data/tooltipinfo.cpp | 3 |
7 files changed, 61 insertions, 1 deletions
diff --git a/src/libs/clangsupport/tooltipinfo.h b/src/libs/clangsupport/tooltipinfo.h index b8f828a52e..f50c93a53e 100644 --- a/src/libs/clangsupport/tooltipinfo.h +++ b/src/libs/clangsupport/tooltipinfo.h @@ -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; diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp index 181737d61b..47d624a147 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -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; diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp index ddd2940522..ff106ed16e 100644 --- a/src/plugins/clangcodemodel/clanghoverhandler.cpp +++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp @@ -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()); diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index cf08f7b5c4..88a91158d5 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -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; }; diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp index 36281674f7..a4ab626a8a 100644 --- a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp +++ b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp @@ -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); diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp index fb630e2aa3..26b6596cc5 100644 --- a/tests/unit/unittest/clangtooltipinfo-test.cpp +++ b/tests/unit/unittest/clangtooltipinfo-test.cpp @@ -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")); diff --git a/tests/unit/unittest/data/tooltipinfo.cpp b/tests/unit/unittest/data/tooltipinfo.cpp index bfad1fdd0f..6844a823cc 100644 --- a/tests/unit/unittest/data/tooltipinfo.cpp +++ b/tests/unit/unittest/data/tooltipinfo.cpp @@ -199,3 +199,6 @@ Nuu **pointers(Nuu **p1) { return p1; } + +static constexpr int calcValue() { return 1 + 2; } +const auto val = calcValue() + sizeof(char); |