aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <[email protected]>2025-09-11 15:29:57 +0200
committerChristian Kandeler <[email protected]>2025-09-12 09:05:52 +0000
commitc3fd344b9f7659fc9349ad84203625706b5c78ef (patch)
treea6a8c6ce123f9fae980d79429c5cfadf8466433b
parent89d247b93d10f4a5f3acf96aac73b5d69d54a1d6 (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.cpp41
-rw-r--r--src/plugins/projectexplorer/project.h2
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;