CMakePM: Remove <Headers> virtual project node

CMake projects need to add the headers as source files in order to get
exported from the CMake file-api json export.

Having header files that are not part of the project displayed in the
<Headers> node is error prone and confusing.

This also means that you won't get bogus files when doing git commit
for example.

Fixes: QTCREATORBUG-18206
Fixes: QTCREATORBUG-24609
Fixes: QTCREATORBUG-25407
Change-Id: I89ac4f8a80f452119f8a991b9e4ef14efb7a86b9
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Cristian Adam
2021-09-22 15:55:15 +02:00
parent 95907b0f7d
commit d341ab6371
6 changed files with 13 additions and 70 deletions

View File

@@ -503,8 +503,7 @@ void addCompileGroups(ProjectNode *targetRoot,
const Utils::FilePath &topSourceDirectory, const Utils::FilePath &topSourceDirectory,
const Utils::FilePath &sourceDirectory, const Utils::FilePath &sourceDirectory,
const Utils::FilePath &buildDirectory, const Utils::FilePath &buildDirectory,
const TargetDetails &td, const TargetDetails &td)
QSet<FilePath> &knownHeaderNodes)
{ {
const bool inSourceBuild = (sourceDirectory == buildDirectory); const bool inSourceBuild = (sourceDirectory == buildDirectory);
@@ -532,10 +531,6 @@ void addCompileGroups(ProjectNode *targetRoot,
auto node = std::make_unique<FileNode>(sourcePath, Node::fileTypeForFileName(sourcePath)); auto node = std::make_unique<FileNode>(sourcePath, Node::fileTypeForFileName(sourcePath));
node->setIsGenerated(si.isGenerated); node->setIsGenerated(si.isGenerated);
// Register headers:
if (node->fileType() == FileType::Header)
knownHeaderNodes.insert(node->filePath());
// Where does the file node need to go? // Where does the file node need to go?
if (sourcePath.isChildOf(buildDirectory) && !inSourceBuild) { if (sourcePath.isChildOf(buildDirectory) && !inSourceBuild) {
buildFileNodes.emplace_back(std::move(node)); buildFileNodes.emplace_back(std::move(node));
@@ -583,8 +578,7 @@ void addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cm
const Configuration &config, const Configuration &config,
const std::vector<TargetDetails> &targetDetails, const std::vector<TargetDetails> &targetDetails,
const FilePath &sourceDir, const FilePath &sourceDir,
const FilePath &buildDir, const FilePath &buildDir)
QSet<FilePath> &knownHeaderNodes)
{ {
for (const FileApiDetails::Target &t : config.targets) { for (const FileApiDetails::Target &t : config.targets) {
const TargetDetails &td = Utils::findOrDefault(targetDetails, const TargetDetails &td = Utils::findOrDefault(targetDetails,
@@ -598,42 +592,37 @@ void addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cm
tNode->setTargetInformation(td.artifacts, td.type); tNode->setTargetInformation(td.artifacts, td.type);
tNode->setBuildDirectory(directoryBuildDir(config, buildDir, t.directory)); tNode->setBuildDirectory(directoryBuildDir(config, buildDir, t.directory));
addCompileGroups(tNode, sourceDir, dir, tNode->buildDirectory(), td, knownHeaderNodes); addCompileGroups(tNode, sourceDir, dir, tNode->buildDirectory(), td);
} }
} }
std::pair<std::unique_ptr<CMakeProjectNode>, QSet<FilePath>> generateRootProjectNode( std::unique_ptr<CMakeProjectNode> generateRootProjectNode(
PreprocessedData &data, const FilePath &sourceDirectory, const FilePath &buildDirectory) PreprocessedData &data, const FilePath &sourceDirectory, const FilePath &buildDirectory)
{ {
std::pair<std::unique_ptr<CMakeProjectNode>, QSet<FilePath>> result; std::unique_ptr<CMakeProjectNode> result = std::make_unique<CMakeProjectNode>(sourceDirectory);
result.first = std::make_unique<CMakeProjectNode>(sourceDirectory);
const FileApiDetails::Project topLevelProject const FileApiDetails::Project topLevelProject
= findOrDefault(data.codemodel.projects, equal(&FileApiDetails::Project::parent, -1)); = findOrDefault(data.codemodel.projects, equal(&FileApiDetails::Project::parent, -1));
if (!topLevelProject.name.isEmpty()) if (!topLevelProject.name.isEmpty())
result.first->setDisplayName(topLevelProject.name); result->setDisplayName(topLevelProject.name);
else else
result.first->setDisplayName(sourceDirectory.fileName()); result->setDisplayName(sourceDirectory.fileName());
QHash<FilePath, ProjectNode *> cmakeListsNodes = addCMakeLists(result.first.get(), QHash<FilePath, ProjectNode *> cmakeListsNodes = addCMakeLists(result.get(),
std::move(data.cmakeListNodes)); std::move(data.cmakeListNodes));
data.cmakeListNodes.clear(); // Remove all the nullptr in the vector... data.cmakeListNodes.clear(); // Remove all the nullptr in the vector...
QSet<FilePath> knownHeaders;
addProjects(cmakeListsNodes, data.codemodel, sourceDirectory); addProjects(cmakeListsNodes, data.codemodel, sourceDirectory);
addTargets(cmakeListsNodes, addTargets(cmakeListsNodes,
data.codemodel, data.codemodel,
data.targetDetails, data.targetDetails,
sourceDirectory, sourceDirectory,
buildDirectory, buildDirectory);
knownHeaders);
// addHeaderNodes(root.get(), knownHeaders, allFiles);
if (!data.cmakeNodesSource.empty() || !data.cmakeNodesBuild.empty() if (!data.cmakeNodesSource.empty() || !data.cmakeNodesBuild.empty()
|| !data.cmakeNodesOther.empty()) || !data.cmakeNodesOther.empty())
addCMakeInputs(result.first.get(), addCMakeInputs(result.get(),
sourceDirectory, sourceDirectory,
buildDirectory, buildDirectory,
std::move(data.cmakeNodesSource), std::move(data.cmakeNodesSource),
@@ -644,8 +633,6 @@ std::pair<std::unique_ptr<CMakeProjectNode>, QSet<FilePath>> generateRootProject
data.cmakeNodesBuild.clear(); // Remove all the nullptr in the vector... data.cmakeNodesBuild.clear(); // Remove all the nullptr in the vector...
data.cmakeNodesOther.clear(); // Remove all the nullptr in the vector... data.cmakeNodesOther.clear(); // Remove all the nullptr in the vector...
result.second = knownHeaders;
return result; return result;
} }
@@ -720,10 +707,9 @@ FileApiQtcData extractData(FileApiData &input,
result.cmakeFiles = std::move(data.cmakeFiles); result.cmakeFiles = std::move(data.cmakeFiles);
result.projectParts = generateRawProjectParts(data, sourceDirectory); result.projectParts = generateRawProjectParts(data, sourceDirectory);
auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory); auto rootProjectNode = generateRootProjectNode(data, sourceDirectory, buildDirectory);
ProjectTree::applyTreeManager(pair.first.get()); // QRC nodes ProjectTree::applyTreeManager(rootProjectNode.get()); // QRC nodes
result.rootProjectNode = std::move(pair.first); result.rootProjectNode = std::move(rootProjectNode);
result.knownHeaders = std::move(pair.second);
setupLocationInfoForTargets(result.rootProjectNode.get(), result.buildTargets); setupLocationInfoForTargets(result.rootProjectNode.get(), result.buildTargets);

View File

@@ -67,7 +67,6 @@ public:
QList<CMakeBuildTarget> buildTargets; QList<CMakeBuildTarget> buildTargets;
ProjectExplorer::RawProjectParts projectParts; ProjectExplorer::RawProjectParts projectParts;
std::unique_ptr<CMakeProjectNode> rootProjectNode; std::unique_ptr<CMakeProjectNode> rootProjectNode;
QSet<Utils::FilePath> knownHeaders;
QString ctestPath; QString ctestPath;
bool isMultiConfig = false; bool isMultiConfig = false;
bool usesAllCapsTargets = false; bool usesAllCapsTargets = false;

View File

@@ -98,7 +98,6 @@ void FileApiReader::resetData()
m_buildTargets.clear(); m_buildTargets.clear();
m_projectParts.clear(); m_projectParts.clear();
m_rootProjectNode.reset(); m_rootProjectNode.reset();
m_knownHeaders.clear();
} }
void FileApiReader::parse(bool forceCMakeRun, void FileApiReader::parse(bool forceCMakeRun,
@@ -220,8 +219,6 @@ std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
{ {
if (failedToParse) if (failedToParse)
addFileSystemNodes(m_rootProjectNode.get(), allFiles.folderNode); addFileSystemNodes(m_rootProjectNode.get(), allFiles.folderNode);
else
addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles.allFiles);
return std::exchange(m_rootProjectNode, {}); return std::exchange(m_rootProjectNode, {});
} }
@@ -291,7 +288,6 @@ void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBac
m_buildTargets = std::move(value->buildTargets); m_buildTargets = std::move(value->buildTargets);
m_projectParts = std::move(value->projectParts); m_projectParts = std::move(value->projectParts);
m_rootProjectNode = std::move(value->rootProjectNode); m_rootProjectNode = std::move(value->rootProjectNode);
m_knownHeaders = std::move(value->knownHeaders);
m_ctestPath = std::move(value->ctestPath); m_ctestPath = std::move(value->ctestPath);
m_isMultiConfig = std::move(value->isMultiConfig); m_isMultiConfig = std::move(value->isMultiConfig);
m_usesAllCapsTargets = std::move(value->usesAllCapsTargets); m_usesAllCapsTargets = std::move(value->usesAllCapsTargets);

View File

@@ -105,7 +105,6 @@ private:
QList<CMakeBuildTarget> m_buildTargets; QList<CMakeBuildTarget> m_buildTargets;
ProjectExplorer::RawProjectParts m_projectParts; ProjectExplorer::RawProjectParts m_projectParts;
std::unique_ptr<CMakeProjectNode> m_rootProjectNode; std::unique_ptr<CMakeProjectNode> m_rootProjectNode;
QSet<Utils::FilePath> m_knownHeaders;
QString m_ctestPath; QString m_ctestPath;
bool m_isMultiConfig = false; bool m_isMultiConfig = false;
bool m_usesAllCapsTargets = false; bool m_usesAllCapsTargets = false;

View File

@@ -175,39 +175,6 @@ CMakeTargetNode *createTargetNode(const QHash<Utils::FilePath, ProjectNode *> &c
return tn; return tn;
} }
void addHeaderNodes(ProjectNode *root,
QSet<Utils::FilePath> &seenHeaders,
const QList<FileNode *> &allFiles)
{
QTC_ASSERT(root, return );
if (root->isEmpty())
return;
auto headerNode = std::make_unique<VirtualFolderNode>(root->filePath());
headerNode->setPriority(Node::DefaultPriority - 5);
headerNode->setDisplayName(
QCoreApplication::translate("CMakeProjectManager::Internal::ProjectTreeHelper",
"<Headers>"));
headerNode->setIcon(DirectoryIcon(ProjectExplorer::Constants::FILEOVERLAY_H));
// Add scanned headers:
for (const FileNode *fn : allFiles) {
if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath()))
continue;
const int count = seenHeaders.count();
seenHeaders.insert(fn->filePath());
if (seenHeaders.count() != count) {
std::unique_ptr<FileNode> node(fn->clone());
node->setEnabled(false);
headerNode->addNestedNode(std::move(node));
}
}
if (!headerNode->isEmpty())
root->addNode(std::move(headerNode));
}
template<typename Result> template<typename Result>
static std::unique_ptr<Result> cloneFolderNode(FolderNode *node) static std::unique_ptr<Result> cloneFolderNode(FolderNode *node)
{ {

View File

@@ -64,10 +64,6 @@ CMakeTargetNode *createTargetNode(
const Utils::FilePath &dir, const Utils::FilePath &dir,
const QString &displayName); const QString &displayName);
void addHeaderNodes(ProjectExplorer::ProjectNode *root,
QSet<Utils::FilePath> &seenHeaders,
const QList<ProjectExplorer::FileNode *> &allFiles);
void addFileSystemNodes(ProjectExplorer::ProjectNode *root, void addFileSystemNodes(ProjectExplorer::ProjectNode *root,
const std::shared_ptr<ProjectExplorer::FolderNode> &folderNode); const std::shared_ptr<ProjectExplorer::FolderNode> &folderNode);
} // namespace Internal } // namespace Internal