Revert "ClangCodeModel: Rename via LSP facilities"

We cannot use clangd's rename facilities yet, as there is a
hardcoded limit of affected files.
This mostly reverts commit 7dc2c6b3b3.

Change-Id: Ie441796569b533948cc028c867175d6f9d4b9d54
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-10-11 17:32:38 +02:00
parent e18bd4b0f8
commit 48755cf7fd
3 changed files with 106 additions and 15 deletions

View File

@@ -260,7 +260,7 @@ public:
: q(q), settings(CppEditor::ClangdProjectSettings(project).settings()) {} : q(q), settings(CppEditor::ClangdProjectSettings(project).settings()) {}
void findUsages(TextDocument *document, const QTextCursor &cursor, void findUsages(TextDocument *document, const QTextCursor &cursor,
const QString &searchTerm, const QString &searchTerm, const std::optional<QString> &replacement,
bool categorize); bool categorize);
void handleDeclDefSwitchReplies(); void handleDeclDefSwitchReplies();
@@ -462,11 +462,13 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
if (searchTerm.isEmpty()) if (searchTerm.isEmpty())
return; return;
if (replacement) { // TODO: Fix hard file limit in clangd, then uncomment this with version check.
symbolSupport().renameSymbol(document, adjustedCursor, *replacement, // Will fix QTCREATORBUG-27978 and QTCREATORBUG-28109.
CppEditor::preferLowerCaseFileNames()); // if (replacement) {
return; // symbolSupport().renameSymbol(document, adjustedCursor, *replacement,
} // CppEditor::preferLowerCaseFileNames());
// return;
// }
const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences(); const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences();
@@ -474,19 +476,19 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
if (searchTerm != "operator" && Utils::allOf(searchTerm, [](const QChar &c) { if (searchTerm != "operator" && Utils::allOf(searchTerm, [](const QChar &c) {
return c.isLetterOrNumber() || c == '_'; return c.isLetterOrNumber() || c == '_';
})) { })) {
d->findUsages(document, adjustedCursor, searchTerm, categorize); d->findUsages(document, adjustedCursor, searchTerm, replacement, categorize);
return; return;
} }
// Otherwise get the proper spelling of the search term from clang, so we can put it into the // Otherwise get the proper spelling of the search term from clang, so we can put it into the
// search widget. // search widget.
const auto symbolInfoHandler = [this, doc = QPointer(document), adjustedCursor, categorize] const auto symbolInfoHandler = [this, doc = QPointer(document), adjustedCursor, replacement, categorize]
(const QString &name, const QString &, const MessageId &) { (const QString &name, const QString &, const MessageId &) {
if (!doc) if (!doc)
return; return;
if (name.isEmpty()) if (name.isEmpty())
return; return;
d->findUsages(doc.data(), adjustedCursor, name, categorize); d->findUsages(doc.data(), adjustedCursor, name, replacement, categorize);
}; };
requestSymbolInfo(document->filePath(), Range(adjustedCursor).start(), symbolInfoHandler); requestSymbolInfo(document->filePath(), Range(adjustedCursor).start(), symbolInfoHandler);
} }
@@ -642,9 +644,11 @@ QVersionNumber ClangdClient::versionNumber() const
CppEditor::ClangdSettings::Data ClangdClient::settingsData() const { return d->settings; } CppEditor::ClangdSettings::Data ClangdClient::settingsData() const { return d->settings; }
void ClangdClient::Private::findUsages(TextDocument *document, void ClangdClient::Private::findUsages(TextDocument *document,
const QTextCursor &cursor, const QString &searchTerm, bool categorize) const QTextCursor &cursor, const QString &searchTerm,
const std::optional<QString> &replacement, bool categorize)
{ {
const auto findRefs = new ClangdFindReferences(q, document, cursor, searchTerm, categorize); const auto findRefs = new ClangdFindReferences(q, document, cursor, searchTerm, replacement,
categorize);
if (isTesting) { if (isTesting) {
connect(findRefs, &ClangdFindReferences::foundReferences, connect(findRefs, &ClangdFindReferences::foundReferences,
q, &ClangdClient::foundReferences); q, &ClangdClient::foundReferences);

View File

@@ -44,12 +44,25 @@ public:
ClangdAstNode ast; ClangdAstNode ast;
}; };
class ReplacementData {
public:
QString oldSymbolName;
QString newSymbolName;
QSet<Utils::FilePath> fileRenameCandidates;
};
class ClangdFindReferences::Private class ClangdFindReferences::Private
{ {
public: public:
Private(ClangdFindReferences *q) : q(q) {} Private(ClangdFindReferences *q) : q(q) {}
ClangdClient *client() const { return qobject_cast<ClangdClient *>(q->parent()); } ClangdClient *client() const { return qobject_cast<ClangdClient *>(q->parent()); }
static void handleRenameRequest(
const SearchResult *search,
const ReplacementData &replacementData,
const QString &newSymbolName,
const QList<SearchResultItem> &checkedItems,
bool preserveCase);
void handleFindUsagesResult(const QList<Location> &locations); void handleFindUsagesResult(const QList<Location> &locations);
void finishSearch(); void finishSearch();
void reportAllSearchResultsAndFinish(); void reportAllSearchResultsAndFinish();
@@ -61,24 +74,50 @@ public:
QMap<DocumentUri, ReferencesFileData> fileData; QMap<DocumentUri, ReferencesFileData> fileData;
QList<MessageId> pendingAstRequests; QList<MessageId> pendingAstRequests;
QPointer<SearchResult> search; QPointer<SearchResult> search;
std::optional<ReplacementData> replacementData;
bool canceled = false; bool canceled = false;
bool categorize = false; bool categorize = false;
}; };
ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *document, ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *document,
const QTextCursor &cursor, const QString &searchTerm, bool categorize) const QTextCursor &cursor, const QString &searchTerm,
const std::optional<QString> &replacement, bool categorize)
: QObject(client), d(new ClangdFindReferences::Private(this)) : QObject(client), d(new ClangdFindReferences::Private(this))
{ {
d->categorize = categorize; d->categorize = categorize;
if (replacement) {
ReplacementData replacementData;
replacementData.oldSymbolName = searchTerm;
replacementData.newSymbolName = *replacement;
if (replacementData.newSymbolName.isEmpty())
replacementData.newSymbolName = replacementData.oldSymbolName;
d->replacementData = replacementData;
}
d->search = SearchResultWindow::instance()->startNewSearch( d->search = SearchResultWindow::instance()->startNewSearch(
tr("C++ Usages:"), tr("C++ Usages:"),
{}, {},
searchTerm, searchTerm,
SearchResultWindow::SearchOnly, replacement ? SearchResultWindow::SearchAndReplace : SearchResultWindow::SearchOnly,
SearchResultWindow::PreserveCaseDisabled, SearchResultWindow::PreserveCaseDisabled,
"CppEditor"); "CppEditor");
if (categorize) if (categorize)
d->search->setFilter(new CppSearchResultFilter); d->search->setFilter(new CppSearchResultFilter);
if (d->replacementData) {
d->search->setTextToReplace(d->replacementData->newSymbolName);
const auto renameFilesCheckBox = new QCheckBox;
renameFilesCheckBox->setVisible(false);
d->search->setAdditionalReplaceWidget(renameFilesCheckBox);
const auto renameHandler =
[search = d->search](const QString &newSymbolName,
const QList<SearchResultItem> &checkedItems,
bool preserveCase) {
const auto replacementData = search->userData().value<ReplacementData>();
Private::handleRenameRequest(search, replacementData, newSymbolName, checkedItems,
preserveCase);
};
connect(d->search, &SearchResult::replaceButtonClicked, renameHandler);
}
connect(d->search, &SearchResult::activated, [](const SearchResultItem& item) { connect(d->search, &SearchResult::activated, [](const SearchResultItem& item) {
EditorManager::openEditorAtSearchResult(item); EditorManager::openEditorAtSearchResult(item);
}); });
@@ -112,6 +151,31 @@ ClangdFindReferences::~ClangdFindReferences()
delete d; delete d;
} }
void ClangdFindReferences::Private::handleRenameRequest(
const SearchResult *search,
const ReplacementData &replacementData,
const QString &newSymbolName,
const QList<SearchResultItem> &checkedItems,
bool preserveCase)
{
const Utils::FilePaths filePaths = BaseFileFind::replaceAll(newSymbolName, checkedItems,
preserveCase);
if (!filePaths.isEmpty()) {
DocumentManager::notifyFilesChangedInternally(filePaths);
SearchResultWindow::instance()->hide();
}
const auto renameFilesCheckBox = qobject_cast<QCheckBox *>(search->additionalReplaceWidget());
QTC_ASSERT(renameFilesCheckBox, return);
if (!renameFilesCheckBox->isChecked())
return;
ProjectExplorerPlugin::renameFilesForSymbol(
replacementData.oldSymbolName, newSymbolName,
Utils::toList(replacementData.fileRenameCandidates),
CppEditor::preferLowerCaseFileNames());
}
void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location> &locations) void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location> &locations)
{ {
if (!search || canceled) { if (!search || canceled) {
@@ -154,7 +218,7 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location>
} }
qCDebug(clangdLog) << "document count is" << fileData.size(); qCDebug(clangdLog) << "document count is" << fileData.size();
if (!categorize) { if (replacementData || !categorize) {
qCDebug(clangdLog) << "skipping AST retrieval"; qCDebug(clangdLog) << "skipping AST retrieval";
reportAllSearchResultsAndFinish(); reportAllSearchResultsAndFinish();
return; return;
@@ -198,6 +262,18 @@ void ClangdFindReferences::Private::finishSearch()
if (!client()->testingEnabled() && search) { if (!client()->testingEnabled() && search) {
search->finishSearch(canceled); search->finishSearch(canceled);
search->disconnect(q); search->disconnect(q);
if (replacementData) {
const auto renameCheckBox = qobject_cast<QCheckBox *>(
search->additionalReplaceWidget());
QTC_CHECK(renameCheckBox);
const QSet<Utils::FilePath> files = replacementData->fileRenameCandidates;
renameCheckBox->setText(tr("Re&name %n files", nullptr, files.size()));
const QStringList filesForUser = Utils::transform<QStringList>(files,
[](const Utils::FilePath &fp) { return fp.toUserOutput(); });
renameCheckBox->setToolTip(tr("Files:\n%1").arg(filesForUser.join('\n')));
renameCheckBox->setVisible(true);
search->setUserData(QVariant::fromValue(*replacementData));
}
} }
emit q->done(); emit q->done();
q->deleteLater(); q->deleteLater();
@@ -231,6 +307,15 @@ void ClangdFindReferences::Private::addSearchResultsForFile(const FilePath &file
item.setUseTextEditorFont(true); item.setUseTextEditorFont(true);
item.setLineText(rangeWithText.second); item.setLineText(rangeWithText.second);
item.setContainingFunctionName(getContainingFunctionName(astPath, range)); item.setContainingFunctionName(getContainingFunctionName(astPath, range));
if (search->supportsReplace()) {
const bool fileInSession = SessionManager::projectForFile(file);
item.setSelectForReplacement(fileInSession);
if (fileInSession && file.baseName().compare(replacementData->oldSymbolName,
Qt::CaseInsensitive) == 0) {
replacementData->fileRenameCandidates << file;
}
}
items << item; items << item;
} }
if (client()->testingEnabled()) if (client()->testingEnabled())
@@ -484,3 +569,5 @@ void ClangdFindLocalReferences::Private::finish()
} }
} // namespace ClangCodeModel::Internal } // namespace ClangCodeModel::Internal
Q_DECLARE_METATYPE(ClangCodeModel::Internal::ReplacementData)

View File

@@ -25,7 +25,7 @@ class ClangdFindReferences : public QObject
public: public:
explicit ClangdFindReferences(ClangdClient *client, TextEditor::TextDocument *document, explicit ClangdFindReferences(ClangdClient *client, TextEditor::TextDocument *document,
const QTextCursor &cursor, const QString &searchTerm, const QTextCursor &cursor, const QString &searchTerm,
bool categorize); const std::optional<QString> &replacement, bool categorize);
~ClangdFindReferences(); ~ClangdFindReferences();
signals: signals: