forked from qt-creator/qt-creator
CMake: Fix some more SOFT-ASSERTS in CMake server-mode
Fix two more SOFT-ASSERTs in CMake server-mode that could be triggered by complex projects. Move and simplify search functionality into FolderNode and use that instead of hand-crafting a custom tree search in CMake. Change-Id: If4bde5c4a7ff84c7d5dba4f595e99b39f54ac8aa Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -540,28 +540,16 @@ void ServerModeReader::addCMakeLists(CMakeProjectNode *root, const QList<FileNod
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMakeListsNode *findCMakeNode(FolderNode *root, const Utils::FileName &dir)
|
static ProjectNode *findCMakeNode(ProjectNode *root, const Utils::FileName &dir)
|
||||||
{
|
{
|
||||||
const Utils::FileName stepDir = dir;
|
Node *n = root->findNode([&dir](Node *n) { return n->asProjectNode() && n->filePath() == dir; });
|
||||||
const Utils::FileName topDir = root->filePath();
|
return n ? n->asProjectNode() : nullptr;
|
||||||
|
|
||||||
QStringList relative = stepDir.relativeChildPath(topDir).toString().split('/', QString::SkipEmptyParts);
|
|
||||||
|
|
||||||
FolderNode *result = root;
|
|
||||||
while (!relative.isEmpty()) {
|
|
||||||
Utils::FileName nextFullPath = result->filePath();
|
|
||||||
nextFullPath.appendPath(relative.takeFirst());
|
|
||||||
result = findOrDefault(result->folderNodes(), Utils::equal(&FolderNode::filePath, nextFullPath));
|
|
||||||
if (!result)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return dynamic_cast<CMakeListsNode *>(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMakeProjectNode *findOrCreateProjectNode(FolderNode *root, const Utils::FileName &dir,
|
static ProjectNode *findOrCreateProjectNode(ProjectNode *root, const Utils::FileName &dir,
|
||||||
const QString &displayName)
|
const QString &displayName)
|
||||||
{
|
{
|
||||||
CMakeListsNode *cmln = findCMakeNode(root, dir);
|
ProjectNode *cmln = findCMakeNode(root, dir);
|
||||||
QTC_ASSERT(cmln, return nullptr);
|
QTC_ASSERT(cmln, return nullptr);
|
||||||
|
|
||||||
Utils::FileName projectName = dir;
|
Utils::FileName projectName = dir;
|
||||||
@@ -588,17 +576,16 @@ void ServerModeReader::addProjects(CMakeProjectNode *root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const Project *p : projects) {
|
for (const Project *p : projects) {
|
||||||
CMakeProjectNode *pNode = findOrCreateProjectNode(root, p->sourceDirectory, p->name);
|
ProjectNode *pNode = findOrCreateProjectNode(root, p->sourceDirectory, p->name);
|
||||||
QTC_ASSERT(pNode, continue);
|
QTC_ASSERT(pNode, continue);
|
||||||
QTC_ASSERT(root, continue);
|
|
||||||
addTargets(root, p->targets, includeFiles);
|
addTargets(root, p->targets, includeFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMakeTargetNode *findOrCreateTargetNode(FolderNode *root, const Utils::FileName &dir,
|
static CMakeTargetNode *findOrCreateTargetNode(ProjectNode *root, const Utils::FileName &dir,
|
||||||
const QString &displayName)
|
const QString &displayName)
|
||||||
{
|
{
|
||||||
CMakeListsNode *cmln = findCMakeNode(root, dir);
|
ProjectNode *cmln = findCMakeNode(root, dir);
|
||||||
QTC_ASSERT(cmln, return nullptr);
|
QTC_ASSERT(cmln, return nullptr);
|
||||||
|
|
||||||
Utils::FileName targetName = dir;
|
Utils::FileName targetName = dir;
|
||||||
|
@@ -401,6 +401,37 @@ QIcon FolderNode::icon() const
|
|||||||
return m_icon;
|
return m_icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node *FolderNode::findNode(const std::function<bool(Node *)> &filter)
|
||||||
|
{
|
||||||
|
if (filter(this))
|
||||||
|
return this;
|
||||||
|
|
||||||
|
for (Node *n : m_nodes) {
|
||||||
|
if (n->asFileNode() && filter(n)) {
|
||||||
|
return n;
|
||||||
|
} else if (FolderNode *folder = n->asFolderNode()) {
|
||||||
|
Node *result = folder->findNode(filter);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Node *> FolderNode::findNodes(const std::function<bool(Node *)> &filter)
|
||||||
|
{
|
||||||
|
QList<Node *> result;
|
||||||
|
if (filter(this))
|
||||||
|
result.append(this);
|
||||||
|
for (Node *n : m_nodes) {
|
||||||
|
if (n->asFileNode() && filter(n))
|
||||||
|
result.append(n);
|
||||||
|
else if (FolderNode *folder = n->asFolderNode())
|
||||||
|
result.append(folder->findNode(filter));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void FolderNode::forEachNode(const std::function<void(FileNode *)> &fileTask,
|
void FolderNode::forEachNode(const std::function<void(FileNode *)> &fileTask,
|
||||||
const std::function<void(FolderNode *)> &folderTask,
|
const std::function<void(FolderNode *)> &folderTask,
|
||||||
const std::function<bool(const FolderNode *)> &folderFilterTask) const
|
const std::function<bool(const FolderNode *)> &folderFilterTask) const
|
||||||
|
@@ -192,6 +192,9 @@ public:
|
|||||||
QString displayName() const override;
|
QString displayName() const override;
|
||||||
QIcon icon() const;
|
QIcon icon() const;
|
||||||
|
|
||||||
|
Node *findNode(const std::function<bool(Node *)> &filter);
|
||||||
|
QList<Node *> findNodes(const std::function<bool(Node *)> &filter);
|
||||||
|
|
||||||
void forEachNode(const std::function<void(FileNode *)> &fileTask,
|
void forEachNode(const std::function<void(FileNode *)> &fileTask,
|
||||||
const std::function<void(FolderNode *)> &folderTask = {},
|
const std::function<void(FolderNode *)> &folderTask = {},
|
||||||
const std::function<bool(const FolderNode *)> &folderFilterTask = {}) const;
|
const std::function<bool(const FolderNode *)> &folderFilterTask = {}) const;
|
||||||
|
Reference in New Issue
Block a user