forked from qt-creator/qt-creator
CppEditor: Adapt include locations when renaming ui files
Fixes: QTCREATORBUG-14259 Change-Id: I5e8209338b531f0e65d85b423053bd19a8b47652 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -784,17 +784,33 @@ QSet<QString> Snapshot::allIncludesForDocument(const QString &fileName) const
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<Snapshot::IncludeLocation> Snapshot::includeLocationsOfDocument(const QString &fileName) const
|
||||
QList<Snapshot::IncludeLocation> Snapshot::includeLocationsOfDocument(
|
||||
const QString &fileNameOrPath) const
|
||||
{
|
||||
const bool matchFullPath = Utils::FilePath::fromString(fileNameOrPath).isAbsolutePath();
|
||||
const auto isMatch = [&](const Document::Include &include) {
|
||||
if (matchFullPath)
|
||||
return include.resolvedFileName() == fileNameOrPath;
|
||||
return Utils::FilePath::fromString(include.resolvedFileName()).fileName() == fileNameOrPath;
|
||||
};
|
||||
QList<IncludeLocation> result;
|
||||
for (const_iterator cit = begin(), citEnd = end(); cit != citEnd; ++cit) {
|
||||
const Document::Ptr doc = cit.value();
|
||||
const QList<Document::Include> includeFiles = doc->resolvedIncludes();
|
||||
bool foundMatch = false;
|
||||
for (const Document::Include &includeFile : includeFiles) {
|
||||
if (includeFile.resolvedFileName() == fileName)
|
||||
if (isMatch(includeFile)) {
|
||||
foundMatch = true;
|
||||
result.push_back({doc, includeFile.line()});
|
||||
}
|
||||
}
|
||||
if (!matchFullPath && !foundMatch) {
|
||||
for (const auto &includeFile : cit.value()->unresolvedIncludes()) {
|
||||
if (includeFile.unresolvedFileName() == fileNameOrPath)
|
||||
result.push_back({doc, includeFile.line()});
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -409,7 +409,8 @@ public:
|
||||
const QString &fileName) const;
|
||||
|
||||
QSet<QString> allIncludesForDocument(const QString &fileName) const;
|
||||
QList<IncludeLocation> includeLocationsOfDocument(const QString &fileName) const;
|
||||
|
||||
QList<IncludeLocation> includeLocationsOfDocument(const QString &fileNameOrPath) const;
|
||||
|
||||
Utils::FilePaths filesDependingOn(const Utils::FilePath &fileName) const;
|
||||
Utils::FilePaths filesDependingOn(const QString &fileName) const
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmacro.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
@@ -1562,18 +1563,46 @@ void CppModelManager::renameIncludes(const Utils::FilePath &oldFilePath,
|
||||
|
||||
const TextEditor::RefactoringChanges changes;
|
||||
|
||||
QString oldFileName = oldFilePath.fileName();
|
||||
QString newFileName = newFilePath.fileName();
|
||||
const bool isUiFile = oldFilePath.suffix() == "ui" && newFilePath.suffix() == "ui";
|
||||
if (isUiFile) {
|
||||
oldFileName = "ui_" + oldFilePath.baseName() + ".h";
|
||||
newFileName = "ui_" + newFilePath.baseName() + ".h";
|
||||
}
|
||||
static const auto getProductNode = [](const FilePath &filePath) -> const Node * {
|
||||
const Node * const fileNode = ProjectTree::nodeForFile(filePath);
|
||||
if (!fileNode)
|
||||
return nullptr;
|
||||
const ProjectNode *productNode = fileNode->parentProjectNode();
|
||||
while (productNode && !productNode->isProduct())
|
||||
productNode = productNode->parentProjectNode();
|
||||
if (!productNode)
|
||||
productNode = fileNode->getProject()->rootProjectNode();
|
||||
return productNode;
|
||||
};
|
||||
const Node * const productNodeForUiFile = isUiFile ? getProductNode(oldFilePath) : nullptr;
|
||||
if (isUiFile && !productNodeForUiFile)
|
||||
return;
|
||||
|
||||
const QList<Snapshot::IncludeLocation> locations = snapshot().includeLocationsOfDocument(
|
||||
oldFilePath.toString());
|
||||
isUiFile ? oldFileName : oldFilePath.toString());
|
||||
for (const Snapshot::IncludeLocation &loc : locations) {
|
||||
TextEditor::RefactoringFilePtr file = changes.file(
|
||||
Utils::FilePath::fromString(loc.first->fileName()));
|
||||
const auto filePath = FilePath::fromString(loc.first->fileName());
|
||||
|
||||
// Larger projects can easily have more than one ui file with the same name.
|
||||
// Replace only if ui file and including source file belong to the same product.
|
||||
if (isUiFile && getProductNode(filePath) != productNodeForUiFile)
|
||||
continue;
|
||||
|
||||
TextEditor::RefactoringFilePtr file = changes.file(filePath);
|
||||
const QTextBlock &block = file->document()->findBlockByNumber(loc.second - 1);
|
||||
const int replaceStart = block.text().indexOf(oldFilePath.fileName());
|
||||
const int replaceStart = block.text().indexOf(oldFileName);
|
||||
if (replaceStart > -1) {
|
||||
Utils::ChangeSet changeSet;
|
||||
changeSet.replace(block.position() + replaceStart,
|
||||
block.position() + replaceStart + oldFilePath.fileName().length(),
|
||||
newFilePath.fileName());
|
||||
block.position() + replaceStart + oldFileName.length(),
|
||||
newFileName);
|
||||
file->setChangeSet(changeSet);
|
||||
file->apply();
|
||||
}
|
||||
|
Reference in New Issue
Block a user