diff options
author | Christian Kandeler <[email protected]> | 2025-09-11 15:29:57 +0200 |
---|---|---|
committer | Christian Kandeler <[email protected]> | 2025-09-12 09:05:52 +0000 |
commit | c3fd344b9f7659fc9349ad84203625706b5c78ef (patch) | |
tree | a6a8c6ce123f9fae980d79429c5cfadf8466433b | |
parent | 89d247b93d10f4a5f3acf96aac73b5d69d54a1d6 (diff) |
ProjectExplorer: Look at all matching file nodes
... in Project::productNodeForFilePath().
But keep the return value to a single ProjectNode for now to avoid
boilerplate code at the call sites, using a heuristic approach. More
fine-grained control can always be added later.
Fixes: QTCREATORBUG-33224
Change-Id: I1023f8e217dcc50f8f741d9e2132e4560a6c7793
Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r-- | src/plugins/projectexplorer/project.cpp | 41 | ||||
-rw-r--r-- | src/plugins/projectexplorer/project.h | 2 |
2 files changed, 32 insertions, 11 deletions
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 20f2481097b..860f91ec48c 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -1126,28 +1126,47 @@ bool Project::isKnownFile(const FilePath &filename) const const Node *Project::nodeForFilePath(const FilePath &filePath, const NodeMatcher &extraMatcher) const { + const QList<const Node *> nodes = nodesForFilePath(filePath, extraMatcher); + return nodes.isEmpty() ? nullptr : nodes.first(); +} + +QList<const Node *> Project::nodesForFilePath(const Utils::FilePath &filePath, + const NodeMatcher &extraMatcher) const +{ const FileNode dummy(filePath, FileType::Unknown); const auto range = std::equal_range(d->m_sortedNodeList.cbegin(), d->m_sortedNodeList.cend(), - &dummy, &nodeLessThan); + &dummy, &nodeLessThan); + QList<const Node *> nodes; for (auto it = range.first; it != range.second; ++it) { if ((*it)->filePath() == filePath && (!extraMatcher || extraMatcher(*it))) - return *it; + nodes << *it; } - return nullptr; + return nodes; } ProjectNode *Project::productNodeForFilePath( const Utils::FilePath &filePath, const NodeMatcher &extraMatcher) const { - const Node * const fileNode = nodeForFilePath(filePath, extraMatcher); - if (!fileNode) - return nullptr; - for (ProjectNode *projectNode = fileNode->parentProjectNode(); projectNode; - projectNode = projectNode->parentProjectNode()) { - if (projectNode->isProduct()) - return projectNode; + const QList<const Node *> fileNodes = nodesForFilePath(filePath, extraMatcher); + QList<ProjectNode *> candidates; + for (const Node * const fileNode : fileNodes) { + for (ProjectNode *projectNode = fileNode->parentProjectNode(); projectNode; + projectNode = projectNode->parentProjectNode()) { + if (projectNode->isProduct()) { + + // If there are several candidates, we prefer real products to pseudo-products. + // See QTCREATORBUG-33224. For now, we assume this is what all callers want. + // If the need arises, we can make this configurable. + if (projectNode->productType() == ProductType::App + || projectNode->productType() == ProductType::Lib) { + return projectNode; + } + + candidates << projectNode; + } + } } - return nullptr; + return candidates.isEmpty() ? nullptr : candidates.first(); } FilePaths Project::binariesForSourceFile(const FilePath &sourceFile) const diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 69f59a8c7d6..d6992b9da2a 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -134,6 +134,8 @@ public: bool isKnownFile(const Utils::FilePath &filename) const; const Node *nodeForFilePath(const Utils::FilePath &filePath, const NodeMatcher &extraMatcher = {}) const; + QList<const Node *> nodesForFilePath(const Utils::FilePath &filePath, + const NodeMatcher &extraMatcher = {}) const; ProjectNode *productNodeForFilePath( const Utils::FilePath &filePath, const NodeMatcher &extraMatcher = {}) const; Utils::FilePaths binariesForSourceFile(const Utils::FilePath &sourceFile) const; |