From 6f7e7980d2b604c79507f9165098f783db8ab2e3 Mon Sep 17 00:00:00 2001 From: Ihor Ivlev Date: Sat, 7 May 2022 00:44:03 +0300 Subject: 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 --- src/libs/cplusplus/CppDocument.cpp | 90 ++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 9 deletions(-) (limited to 'src/libs/cplusplus/CppDocument.cpp') diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 90660f2b55..60144b2320 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -96,6 +96,86 @@ protected: } }; +class ContainingFunctionAt: protected SymbolVisitor +{ + TranslationUnit *translationUnit; + Symbol *root; + int line; + int column; + Symbol *functionSymbol; + bool foundFunction; + bool foundBlock; + + bool scopeContains(Scope* scope, int line, int column){ + if (!scope) + return false; + + int scopeStartLine{-1}, scopeStartColumn{-1}, scopeEndLine{-1}, scopeEndColumn{-1}; + translationUnit->getPosition(scope->startOffset(), &scopeStartLine, &scopeStartColumn); + translationUnit->getPosition(scope->endOffset(), &scopeEndLine, &scopeEndColumn); + + if (line < scopeStartLine || line > scopeEndLine) + return false; + + if (line > scopeStartLine && line < scopeEndLine) + return true; + + if (scopeStartLine == line && column >= scopeStartColumn) + return true; + + if (scopeEndLine == line && column <= scopeEndColumn) + return true; + + return false; + } + +public: + ContainingFunctionAt(TranslationUnit *unit, Symbol *root) + : translationUnit(unit), root(root), line(0), column(0), functionSymbol(nullptr) + , foundFunction(false), foundBlock(false) {} + + Symbol *operator()(int line, int column) + { + this->line = line; + this->column = column; + this->functionSymbol = nullptr; + accept(root); + + return foundBlock ? functionSymbol : nullptr; + } + +protected: + bool preVisit(Symbol *s) final + { + if (foundBlock) + return false; + + if (foundFunction) { + auto block = s->asBlock(); + if (!block) + return true; + + if (scopeContains(block->asScope(), line, column)) { + foundBlock = true; + return false; + } + return true; + } + + auto asFunction = s->asFunction(); + if (asFunction) { + if (s->line() < line || (s->line() == line && s->column() <= column)) { + foundFunction = scopeContains(s->asScope(), line, column); + if (foundFunction) + functionSymbol = asFunction; + } + } + + return true; + } +}; + + class FindScopeAt: protected SymbolVisitor { TranslationUnit *_unit; @@ -512,19 +592,11 @@ QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorPar if (line < 1 || column < 1) return QString(); - Symbol *symbol = lastVisibleSymbolAt(line, column); + Symbol *symbol = ContainingFunctionAt{translationUnit(), globalNamespace()}(line, column); if (!symbol) return QString(); - // Find the enclosing function scope (which might be several levels up, or we might be standing - // on it) Scope *scope = symbol->asScope(); - if (!scope) - scope = symbol->enclosingScope(); - - while (scope && !scope->isFunction() ) - scope = scope->enclosingScope(); - if (!scope) return QString(); -- cgit v1.2.1