Display parent functions in the Find Usages menu

To display the parent function, first we find it in displayResults and
store the information to SearchResultItem, then
SearchResultTreeItemDelegate gets the information and renders it.

Similar approach is applied to ClangdClient, in addSearchResultsForFile.

This change also adds default style for containing function highlight in
the search.
Default foreground and background colors are same as usual text colors.

Task-number: QTCREATORBUG-27550
Change-Id: Id1251afa192f8d1232524742b7c211770bcb83fb
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Ihor Ivlev
2022-05-07 00:44:03 +03:00
parent 5da36104ab
commit 6f7e7980d2
22 changed files with 271 additions and 32 deletions

View File

@@ -62,6 +62,12 @@ bool ClangdAstNode::arcanaContains(const QString &s) const
return arcanaString && arcanaString->contains(s);
}
bool ClangdAstNode::isFunction() const
{
return role() == "declaration"
&& (kind() == "Function" || kind() == "FunctionProto" || kind() == "CXXMethod");
}
bool ClangdAstNode::isMemberFunctionCall() const
{
return role() == "expression" && (kind() == "CXXMemberCall"

View File

@@ -79,6 +79,7 @@ public:
bool hasRange() const;
bool arcanaContains(const QString &s) const;
bool detailIs(const QString &s) const { return detail() && *detail() == s; }
bool isFunction() const;
bool isMemberFunctionCall() const;
bool isPureVirtualDeclaration() const;
bool isPureVirtualDefinition() const;

View File

@@ -907,6 +907,8 @@ public:
void handleDeclDefSwitchReplies();
Utils::optional<QString> getContainingFunctionName(const ClangdAstPath &astPath, const Range& range);
static CppEditor::CppEditorWidget *widgetFromDocument(const TextDocument *doc);
QString searchTermFromCursor(const QTextCursor &cursor) const;
QTextCursor adjustedCursor(const QTextCursor &cursor, const TextDocument *doc);
@@ -1762,9 +1764,10 @@ void ClangdClient::Private::addSearchResultsForFile(ReferencesData &refData,
qCDebug(clangdLog) << file << "has valid AST:" << fileData.ast.isValid();
for (const auto &rangeWithText : fileData.rangesAndLineText) {
const Range &range = rangeWithText.first;
const Usage::Type usageType = fileData.ast.isValid()
? getUsageType(getAstPath(fileData.ast, qAsConst(range)))
: Usage::Type::Other;
const ClangdAstPath astPath = getAstPath(fileData.ast, range);
const Usage::Type usageType = fileData.ast.isValid() ? getUsageType(astPath)
: Usage::Type::Other;
SearchResultItem item;
item.setUserData(int(usageType));
item.setStyle(CppEditor::colorStyleForUsageType(usageType));
@@ -1772,6 +1775,8 @@ void ClangdClient::Private::addSearchResultsForFile(ReferencesData &refData,
item.setMainRange(SymbolSupport::convertRange(range));
item.setUseTextEditorFont(true);
item.setLineText(rangeWithText.second);
item.setContainingFunctionName(getContainingFunctionName(astPath, range));
if (refData.search->supportsReplace()) {
const bool fileInSession = SessionManager::projectForFile(file);
item.setSelectForReplacement(fileInSession);
@@ -2418,6 +2423,31 @@ void ClangdClient::Private::handleDeclDefSwitchReplies()
switchDeclDefData.reset();
}
Utils::optional<QString> ClangdClient::Private::getContainingFunctionName(
const ClangdAstPath &astPath, const Range& range)
{
const ClangdAstNode* containingFuncNode{nullptr};
const ClangdAstNode* lastCompoundStmtNode{nullptr};
for (auto it = astPath.crbegin(); it != astPath.crend(); ++it) {
if (it->arcanaContains("CompoundStmt"))
lastCompoundStmtNode = &*it;
if (it->isFunction()) {
if (lastCompoundStmtNode && lastCompoundStmtNode->hasRange()
&& lastCompoundStmtNode->range().contains(range)) {
containingFuncNode = &*it;
break;
}
}
}
if (!containingFuncNode || !containingFuncNode->isValid())
return Utils::nullopt;
return containingFuncNode->detail();
}
CppEditor::CppEditorWidget *ClangdClient::Private::widgetFromDocument(const TextDocument *doc)
{
IEditor * const editor = Utils::findOrDefault(EditorManager::visibleEditors(),