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;
|
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;
|
QList<IncludeLocation> result;
|
||||||
for (const_iterator cit = begin(), citEnd = end(); cit != citEnd; ++cit) {
|
for (const_iterator cit = begin(), citEnd = end(); cit != citEnd; ++cit) {
|
||||||
const Document::Ptr doc = cit.value();
|
const Document::Ptr doc = cit.value();
|
||||||
const QList<Document::Include> includeFiles = doc->resolvedIncludes();
|
const QList<Document::Include> includeFiles = doc->resolvedIncludes();
|
||||||
|
bool foundMatch = false;
|
||||||
for (const Document::Include &includeFile : includeFiles) {
|
for (const Document::Include &includeFile : includeFiles) {
|
||||||
if (includeFile.resolvedFileName() == fileName)
|
if (isMatch(includeFile)) {
|
||||||
|
foundMatch = true;
|
||||||
result.push_back({doc, includeFile.line()});
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -409,7 +409,8 @@ public:
|
|||||||
const QString &fileName) const;
|
const QString &fileName) const;
|
||||||
|
|
||||||
QSet<QString> allIncludesForDocument(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 Utils::FilePath &fileName) const;
|
||||||
Utils::FilePaths filesDependingOn(const QString &fileName) const
|
Utils::FilePaths filesDependingOn(const QString &fileName) const
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/projectmacro.h>
|
#include <projectexplorer/projectmacro.h>
|
||||||
|
#include <projectexplorer/projectnodes.h>
|
||||||
#include <projectexplorer/projecttree.h>
|
#include <projectexplorer/projecttree.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
@@ -1562,18 +1563,46 @@ void CppModelManager::renameIncludes(const Utils::FilePath &oldFilePath,
|
|||||||
|
|
||||||
const TextEditor::RefactoringChanges changes;
|
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(
|
const QList<Snapshot::IncludeLocation> locations = snapshot().includeLocationsOfDocument(
|
||||||
oldFilePath.toString());
|
isUiFile ? oldFileName : oldFilePath.toString());
|
||||||
for (const Snapshot::IncludeLocation &loc : locations) {
|
for (const Snapshot::IncludeLocation &loc : locations) {
|
||||||
TextEditor::RefactoringFilePtr file = changes.file(
|
const auto filePath = FilePath::fromString(loc.first->fileName());
|
||||||
Utils::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 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) {
|
if (replaceStart > -1) {
|
||||||
Utils::ChangeSet changeSet;
|
Utils::ChangeSet changeSet;
|
||||||
changeSet.replace(block.position() + replaceStart,
|
changeSet.replace(block.position() + replaceStart,
|
||||||
block.position() + replaceStart + oldFilePath.fileName().length(),
|
block.position() + replaceStart + oldFileName.length(),
|
||||||
newFilePath.fileName());
|
newFileName);
|
||||||
file->setChangeSet(changeSet);
|
file->setChangeSet(changeSet);
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user