ClangCodeModel: Implement global renaming via clangd

Note that we do not use the LSP rename functionality. We do "manual"
renaming the same way as in the built-in code model, but based on the
references found by clangd.

Change-Id: Ifa5597efe5c89c8f9204a4f5323bc755544696cf
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-05-18 12:59:15 +02:00
parent 78274956d0
commit 12fd21a880
9 changed files with 186 additions and 77 deletions

View File

@@ -59,6 +59,8 @@ using namespace ProjectExplorer;
namespace CppTools {
namespace { static bool isAllLowerCase(const QString &text) { return text.toLower() == text; } }
SearchResultColor::Style colorStyleForUsageType(CPlusPlus::Usage::Type type)
{
switch (type) {
@@ -75,6 +77,51 @@ SearchResultColor::Style colorStyleForUsageType(CPlusPlus::Usage::Type type)
return SearchResultColor::Style::Default; // For dumb compilers.
}
void renameFilesForSymbol(const QString &oldSymbolName, const QString &newSymbolName,
const QVector<Node *> &files)
{
Internal::CppFileSettings settings;
settings.fromSettings(Core::ICore::settings());
const QStringList newPaths =
Utils::transform<QList>(files,
[&oldSymbolName, newSymbolName, &settings](const Node *node) -> QString {
const QFileInfo fi = node->filePath().toFileInfo();
const QString oldBaseName = fi.baseName();
QString newBaseName = newSymbolName;
// 1) new symbol lowercase: new base name lowercase
if (isAllLowerCase(newSymbolName)) {
newBaseName = newSymbolName;
// 2) old base name mixed case: new base name is verbatim symbol name
} else if (!isAllLowerCase(oldBaseName)) {
newBaseName = newSymbolName;
// 3) old base name lowercase, old symbol mixed case: new base name lowercase
} else if (!isAllLowerCase(oldSymbolName)) {
newBaseName = newSymbolName.toLower();
// 4) old base name lowercase, old symbol lowercase, new symbol mixed case:
// use the preferences setting for new base name case
} else if (settings.lowerCaseFiles) {
newBaseName = newSymbolName.toLower();
}
if (newBaseName == oldBaseName)
return QString();
return fi.absolutePath() + "/" + newBaseName + '.' + fi.completeSuffix();
});
for (int i = 0; i < files.size(); ++i) {
if (!newPaths.at(i).isEmpty()) {
Node *node = files.at(i);
ProjectExplorerPlugin::renameFile(node, newPaths.at(i));
}
}
}
QWidget *CppSearchResultFilter::createWidget()
{
const auto widget = new QWidget;
@@ -469,11 +516,6 @@ void CppFindReferences::findAll_helper(SearchResult *search, CPlusPlus::Symbol *
connect(progress, &FutureProgress::clicked, search, &SearchResult::popup);
}
static bool isAllLowerCase(const QString &text)
{
return text.toLower() == text;
}
void CppFindReferences::onReplaceButtonClicked(const QString &text,
const QList<SearchResultItem> &items,
bool preserveCase)
@@ -495,48 +537,7 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text,
if (!renameFilesCheckBox || !renameFilesCheckBox->isChecked())
return;
CppFileSettings settings;
settings.fromSettings(Core::ICore::settings());
const QStringList newPaths =
Utils::transform<QList>(parameters.filesToRename,
[&parameters, text, &settings](const Node *node) -> QString {
const QFileInfo fi = node->filePath().toFileInfo();
const QString oldSymbolName = parameters.prettySymbolName;
const QString oldBaseName = fi.baseName();
const QString newSymbolName = text;
QString newBaseName = newSymbolName;
// 1) new symbol lowercase: new base name lowercase
if (isAllLowerCase(newSymbolName)) {
newBaseName = newSymbolName;
// 2) old base name mixed case: new base name is verbatim symbol name
} else if (!isAllLowerCase(oldBaseName)) {
newBaseName = newSymbolName;
// 3) old base name lowercase, old symbol mixed case: new base name lowercase
} else if (!isAllLowerCase(oldSymbolName)) {
newBaseName = newSymbolName.toLower();
// 4) old base name lowercase, old symbol lowercase, new symbol mixed case:
// use the preferences setting for new base name case
} else if (settings.lowerCaseFiles) {
newBaseName = newSymbolName.toLower();
}
if (newBaseName == oldBaseName)
return QString();
return fi.absolutePath() + "/" + newBaseName + '.' + fi.completeSuffix();
});
for (int i = 0; i < parameters.filesToRename.size(); ++i) {
if (!newPaths.at(i).isEmpty()) {
Node *node = parameters.filesToRename.at(i);
ProjectExplorerPlugin::renameFile(node, newPaths.at(i));
}
}
renameFilesForSymbol(parameters.prettySymbolName, text, parameters.filesToRename);
}
void CppFindReferences::searchAgain()