CppEditor: Consider symbol occurrences in comments

... when renaming.
For local renaming, we consider only function parameters.

Task-number: QTCREATORBUG-12051
Change-Id: I7948d69f11b97663c9bd747ae6241a82dd9bdd82
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2023-08-23 17:26:02 +02:00
parent 164cb389dc
commit 0a058bb657
28 changed files with 525 additions and 86 deletions

View File

@@ -402,6 +402,9 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir, c
setCompletionAssistProvider(new ClangdCompletionAssistProvider(this));
setQuickFixAssistProvider(new ClangdQuickFixProvider(this));
symbolSupport().setLimitRenamingToProjects(true);
symbolSupport().setRenameResultsEnhancer([](const SearchResultItems &symbolOccurrencesInCode) {
return CppEditor::symbolOccurrencesInDeclarationComments(symbolOccurrencesInCode);
});
if (!project) {
QJsonObject initOptions;
const Utils::FilePath includeDir
@@ -752,6 +755,13 @@ bool ClangdClient::fileBelongsToProject(const Utils::FilePath &filePath) const
return Client::fileBelongsToProject(filePath);
}
QList<Text::Range> ClangdClient::additionalDocumentHighlights(
TextEditorWidget *editorWidget, const QTextCursor &cursor)
{
return CppEditor::symbolOccurrencesInDeclarationComments(
qobject_cast<CppEditor::CppEditorWidget *>(editorWidget), cursor);
}
RefactoringChangesData *ClangdClient::createRefactoringChangesBackend() const
{
return new CppEditor::CppRefactoringChangesData(
@@ -1056,9 +1066,11 @@ void ClangdClient::switchHeaderSource(const Utils::FilePath &filePath, bool inNe
sendMessage(req);
}
void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cursor,
CppEditor::RenameCallback &&callback)
void ClangdClient::findLocalUsages(CppEditor::CppEditorWidget *editorWidget,
const QTextCursor &cursor, CppEditor::RenameCallback &&callback)
{
QTC_ASSERT(editorWidget, return);
TextDocument * const document = editorWidget->textDocument();
QTC_ASSERT(documentOpen(document), openDocument(document));
qCDebug(clangdLog) << "local references requested" << document->filePath()
@@ -1076,7 +1088,7 @@ void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cu
return;
}
d->findLocalRefs = new ClangdFindLocalReferences(this, document, cursor, callback);
d->findLocalRefs = new ClangdFindLocalReferences(this, editorWidget, cursor, callback);
connect(d->findLocalRefs, &ClangdFindLocalReferences::done, this, [this] {
d->findLocalRefs->deleteLater();
d->findLocalRefs = nullptr;

View File

@@ -74,7 +74,7 @@ public:
const Utils::LinkHandler &callback);
void switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit);
void findLocalUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
void findLocalUsages(CppEditor::CppEditorWidget *editorWidget, const QTextCursor &cursor,
CppEditor::RenameCallback &&callback);
void gatherHelpItemForTooltip(
@@ -148,6 +148,9 @@ private:
bool referencesShadowFile(const TextEditor::TextDocument *doc,
const Utils::FilePath &candidate) override;
bool fileBelongsToProject(const Utils::FilePath &filePath) const override;
QList<Utils::Text::Range> additionalDocumentHighlights(
TextEditor::TextEditorWidget *editorWidget, const QTextCursor &cursor) override;
class Private;
class VirtualFunctionAssistProcessor;

View File

@@ -14,6 +14,7 @@
#include <cplusplus/FindUsages.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cppeditorwidget.h>
#include <cppeditor/cppfindreferences.h>
#include <cppeditor/cpptoolsreuse.h>
@@ -670,10 +671,10 @@ ClangdFindReferences::CheckUnusedData::~CheckUnusedData()
class ClangdFindLocalReferences::Private
{
public:
Private(ClangdFindLocalReferences *q, TextDocument *document, const QTextCursor &cursor,
Private(ClangdFindLocalReferences *q, CppEditorWidget *editorWidget, const QTextCursor &cursor,
const RenameCallback &callback)
: q(q), document(document), cursor(cursor), callback(callback),
uri(client()->hostPathToServerUri(document->filePath())),
: q(q), editorWidget(editorWidget), document(editorWidget->textDocument()), cursor(cursor),
callback(callback), uri(client()->hostPathToServerUri(document->filePath())),
revision(document->document()->revision())
{}
@@ -685,6 +686,7 @@ public:
void finish();
ClangdFindLocalReferences * const q;
const QPointer<CppEditorWidget> editorWidget;
const QPointer<TextDocument> document;
const QTextCursor cursor;
RenameCallback callback;
@@ -694,9 +696,9 @@ public:
};
ClangdFindLocalReferences::ClangdFindLocalReferences(
ClangdClient *client, TextDocument *document, const QTextCursor &cursor,
const RenameCallback &callback)
: QObject(client), d(new Private(this, document, cursor, callback))
ClangdClient *client, CppEditorWidget *editorWidget, const QTextCursor &cursor,
const RenameCallback &callback)
: QObject(client), d(new Private(this, editorWidget, cursor, callback))
{
d->findDefinition();
}
@@ -780,7 +782,7 @@ void ClangdFindLocalReferences::Private::handleReferences(const QList<Location>
return loc.toLink(mapper);
};
const Utils::Links links = Utils::transform(references, transformLocation);
Utils::Links links = Utils::transform(references, transformLocation);
// The callback only uses the symbol length, so we just create a dummy.
// Note that the calculation will be wrong for identifiers with
@@ -788,7 +790,27 @@ void ClangdFindLocalReferences::Private::handleReferences(const QList<Location>
QString symbol;
if (!references.isEmpty()) {
const Range r = references.first().range();
symbol = QString(r.end().character() - r.start().character(), 'x');
const Position pos = r.start();
symbol = QString(r.end().character() - pos.character(), 'x');
if (editorWidget && document) {
QTextCursor cursor(document->document());
cursor.setPosition(Text::positionInText(document->document(), pos.line() + 1,
pos.character() + 1));
const QList<Text::Range> occurrencesInComments
= symbolOccurrencesInDeclarationComments(editorWidget, cursor);
for (const Text::Range &range : occurrencesInComments) {
static const auto cmp = [](const Link &l, const Text::Range &r) {
if (l.targetLine < r.begin.line)
return true;
if (l.targetLine > r.begin.line)
return false;
return l.targetColumn < r.begin.column;
};
const auto it = std::lower_bound(links.begin(), links.end(), range, cmp);
links.emplace(it, links.first().targetFilePath, range.begin.line,
range.begin.column);
}
}
}
callback(symbol, links, revision);
callback = {};

View File

@@ -48,9 +48,9 @@ class ClangdFindLocalReferences : public QObject
{
Q_OBJECT
public:
explicit ClangdFindLocalReferences(ClangdClient *client, TextEditor::TextDocument *document,
const QTextCursor &cursor,
const CppEditor::RenameCallback &callback);
explicit ClangdFindLocalReferences(
ClangdClient *client, CppEditor::CppEditorWidget *editorWidget, const QTextCursor &cursor,
const CppEditor::RenameCallback &callback);
~ClangdFindLocalReferences();
signals:

View File

@@ -309,7 +309,7 @@ void ClangModelManagerSupport::startLocalRenaming(const CursorInEditor &data,
{
if (ClangdClient * const client = clientForFile(data.filePath());
client && client->reachable()) {
client->findLocalUsages(data.textDocument(), data.cursor(),
client->findLocalUsages(data.editorWidget(), data.cursor(),
std::move(renameSymbolsCallback));
return;
}

View File

@@ -10,6 +10,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <cplusplus/FindUsages.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cppeditorwidget.h>
#include <cppeditor/cpptoolsreuse.h>
#include <cppeditor/cpptoolstestcase.h>
#include <cppeditor/semantichighlighter.h>
@@ -536,6 +537,8 @@ void ClangdTestLocalReferences::test_data()
QTest::newRow("overloaded operators arguments from outside") << 171 << 7
<< QList<Range>{{171, 6, 1}, {172, 6, 1}, {172, 11, 1},
{173, 6, 1}, {173, 9, 1}};
QTest::newRow("documented function parameter") << 181 << 32
<< QList<Range>{{177, 10, 6}, {179, 9, 6}, {181, 31, 6}, {183, 6, 6}, {184, 17, 6}};
}
void ClangdTestLocalReferences::test()
@@ -546,6 +549,11 @@ void ClangdTestLocalReferences::test()
TextEditor::TextDocument * const doc = document("references.cpp");
QVERIFY(doc);
const QList<BaseTextEditor *> editors = BaseTextEditor::textEditorsForDocument(doc);
QCOMPARE(editors.size(), 1);
const auto editorWidget = qobject_cast<CppEditor::CppEditorWidget *>(
editors.first()->editorWidget());
QVERIFY(editorWidget);
QTimer timer;
timer.setSingleShot(true);
@@ -561,7 +569,7 @@ void ClangdTestLocalReferences::test()
QTextCursor cursor(doc->document());
const int pos = Text::positionInText(doc->document(), sourceLine, sourceColumn);
cursor.setPosition(pos);
client()->findLocalUsages(doc, cursor, std::move(handler));
client()->findLocalUsages(editorWidget, cursor, std::move(handler));
timer.start(10000);
loop.exec();
QVERIFY(timer.isActive());

View File

@@ -172,3 +172,14 @@ int testOperator() {
vec[n] = n * 100;
vec(n, n) = 100;
}
/*
* @param param1
* @param param2
* @note param1 and param2 should be the same.
*/
void funcWithParamComments(int param1, int param2)
{
if (param1 != param2)
param2 = param1;
}