forked from qt-creator/qt-creator
CompilationDatabase: Add folders to Project view
Change-Id: I4cd480535c203aa923b27596ea4ca74f83c12a9e Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -346,6 +346,13 @@ QString FileUtils::resolvePath(const QString &baseDir, const QString &fileName)
|
|||||||
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
|
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileName FileUtils::commonPath(const FileName &oldCommonPath, const FileName &fileName)
|
||||||
|
{
|
||||||
|
FileName newCommonPath = oldCommonPath;
|
||||||
|
while (!newCommonPath.isEmpty() && !fileName.isChildOf(newCommonPath))
|
||||||
|
newCommonPath = newCommonPath.parentDir();
|
||||||
|
return canonicalPath(newCommonPath);
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray FileReader::fetchQrc(const QString &fileName)
|
QByteArray FileReader::fetchQrc(const QString &fileName)
|
||||||
{
|
{
|
||||||
|
@@ -129,6 +129,7 @@ public:
|
|||||||
static bool isRelativePath(const QString &fileName);
|
static bool isRelativePath(const QString &fileName);
|
||||||
static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); }
|
static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); }
|
||||||
static QString resolvePath(const QString &baseDir, const QString &fileName);
|
static QString resolvePath(const QString &baseDir, const QString &fileName);
|
||||||
|
static FileName commonPath(const FileName &oldCommonPath, const FileName &fileName);
|
||||||
};
|
};
|
||||||
|
|
||||||
// for actually finding out if e.g. directories are writable on Windows
|
// for actually finding out if e.g. directories are writable on Windows
|
||||||
|
@@ -163,7 +163,7 @@ ToolChain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Co
|
|||||||
|
|
||||||
Utils::FileName jsonObjectFilename(const QJsonObject &object)
|
Utils::FileName jsonObjectFilename(const QJsonObject &object)
|
||||||
{
|
{
|
||||||
const QString workingDir = object["directory"].toString();
|
const QString workingDir = QDir::fromNativeSeparators(object["directory"].toString());
|
||||||
Utils::FileName fileName = Utils::FileName::fromString(
|
Utils::FileName fileName = Utils::FileName::fromString(
|
||||||
QDir::fromNativeSeparators(object["file"].toString()));
|
QDir::fromNativeSeparators(object["file"].toString()));
|
||||||
if (fileName.toFileInfo().isRelative()) {
|
if (fileName.toFileInfo().isRelative()) {
|
||||||
@@ -232,6 +232,76 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
|
|||||||
return rpp;
|
return rpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList relativeDirsList(Utils::FileName currentPath, const Utils::FileName &rootPath)
|
||||||
|
{
|
||||||
|
QStringList dirsList;
|
||||||
|
while (!currentPath.isEmpty() && currentPath != rootPath) {
|
||||||
|
QString dirName = currentPath.fileName();
|
||||||
|
if (dirName.isEmpty())
|
||||||
|
dirName = currentPath.toString();
|
||||||
|
dirsList.prepend(dirName);
|
||||||
|
currentPath = currentPath.parentDir();
|
||||||
|
}
|
||||||
|
return dirsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderNode *addChildFolderNode(FolderNode *parent, const QString &childName)
|
||||||
|
{
|
||||||
|
Utils::FileName parentPath = parent->filePath();
|
||||||
|
auto node = std::make_unique<FolderNode>(
|
||||||
|
parentPath.appendPath(childName), NodeType::Folder, childName);
|
||||||
|
FolderNode *childNode = node.get();
|
||||||
|
parent->addNode(std::move(node));
|
||||||
|
|
||||||
|
return childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderNode *addOrGetChildFolderNode(FolderNode *parent, const QString &childName)
|
||||||
|
{
|
||||||
|
Node *childNode = parent->findNode([childName](const Node *node) {
|
||||||
|
if (!node->asFolderNode())
|
||||||
|
return false;
|
||||||
|
QString nodeDirName = node->filePath().fileName();
|
||||||
|
if (nodeDirName.isEmpty())
|
||||||
|
nodeDirName = node->filePath().toString();
|
||||||
|
return nodeDirName == childName;
|
||||||
|
});
|
||||||
|
if (childNode)
|
||||||
|
return childNode->asFolderNode();
|
||||||
|
|
||||||
|
return addChildFolderNode(parent, childName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the node for folderPath.
|
||||||
|
FolderNode *createFoldersIfNeeded(FolderNode *root, const Utils::FileName &folderPath)
|
||||||
|
{
|
||||||
|
const QStringList dirsList = relativeDirsList(folderPath, root->filePath());
|
||||||
|
|
||||||
|
FolderNode *parent = root;
|
||||||
|
for (const QString &dir : dirsList)
|
||||||
|
parent = addOrGetChildFolderNode(parent, dir);
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createFolders(FolderNode *root, const Utils::FileName &rootPath)
|
||||||
|
{
|
||||||
|
root->setAbsoluteFilePathAndLine(rootPath, -1);
|
||||||
|
|
||||||
|
for (Node *child : root->nodes()) {
|
||||||
|
FileNode *fileNode = child->asFileNode();
|
||||||
|
if (!fileNode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FolderNode *parentNode = createFoldersIfNeeded(root,
|
||||||
|
fileNode->filePath().parentDir());
|
||||||
|
child->setParentFolderNode(nullptr);
|
||||||
|
std::unique_ptr<Node> childNode = root->takeNode(child);
|
||||||
|
if (!parentNode->fileNode(child->filePath()))
|
||||||
|
parentNode->addNode(std::move(childNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName &projectFile)
|
void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName &projectFile)
|
||||||
@@ -245,38 +315,22 @@ void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName
|
|||||||
const QJsonArray array = QJsonDocument::fromJson(file.readAll()).array();
|
const QJsonArray array = QJsonDocument::fromJson(file.readAll()).array();
|
||||||
|
|
||||||
auto root = std::make_unique<DBProjectNode>(projectDirectory());
|
auto root = std::make_unique<DBProjectNode>(projectDirectory());
|
||||||
root->addNode(std::make_unique<FileNode>(
|
|
||||||
projectFile,
|
|
||||||
FileType::Project,
|
|
||||||
false));
|
|
||||||
auto headers = std::make_unique<VirtualFolderNode>(
|
|
||||||
Utils::FileName::fromString("Headers"), 0);
|
|
||||||
auto sources = std::make_unique<VirtualFolderNode>(
|
|
||||||
Utils::FileName::fromString("Sources"), 0);
|
|
||||||
|
|
||||||
CppTools::RawProjectParts rpps;
|
CppTools::RawProjectParts rpps;
|
||||||
|
Utils::FileName commonPath;
|
||||||
ToolChain *cToolchain = nullptr;
|
ToolChain *cToolchain = nullptr;
|
||||||
ToolChain *cxxToolchain = nullptr;
|
ToolChain *cxxToolchain = nullptr;
|
||||||
for (const QJsonValue &element : array) {
|
for (const QJsonValue &element : array) {
|
||||||
const QJsonObject object = element.toObject();
|
const QJsonObject object = element.toObject();
|
||||||
|
|
||||||
Utils::FileName fileName = jsonObjectFilename(object);
|
Utils::FileName fileName = jsonObjectFilename(object);
|
||||||
const QStringList flags = jsonObjectFlags(object);
|
const QStringList flags = jsonObjectFlags(object);
|
||||||
const QString filePath = fileName.toString();
|
|
||||||
|
|
||||||
const CppTools::ProjectFile::Kind kind = CppTools::ProjectFile::classify(filePath);
|
commonPath = rpps.empty()
|
||||||
FolderNode *parent = nullptr;
|
? fileName.parentDir()
|
||||||
FileType type = FileType::Unknown;
|
: Utils::FileUtils::commonPath(commonPath, fileName);
|
||||||
if (CppTools::ProjectFile::isHeader(kind)) {
|
|
||||||
parent = headers.get();
|
ProjectExplorer::FileType type = ProjectExplorer::FileType::Unknown;
|
||||||
type = FileType::Header;
|
root->addNode(std::make_unique<FileNode>(fileName, type, false));
|
||||||
} else if (CppTools::ProjectFile::isSource(kind)) {
|
|
||||||
parent = sources.get();
|
|
||||||
type = FileType::Source;
|
|
||||||
} else {
|
|
||||||
parent = root.get();
|
|
||||||
}
|
|
||||||
parent->addNode(std::make_unique<FileNode>(fileName, type, false));
|
|
||||||
|
|
||||||
CppTools::RawProjectPart rpp = makeRawProjectPart(projectFile,
|
CppTools::RawProjectPart rpp = makeRawProjectPart(projectFile,
|
||||||
m_kit.get(),
|
m_kit.get(),
|
||||||
@@ -297,8 +351,12 @@ void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName
|
|||||||
rpps[rppIndex].files.append(rpp.files);
|
rpps[rppIndex].files.append(rpp.files);
|
||||||
}
|
}
|
||||||
|
|
||||||
root->addNode(std::move(headers));
|
createFolders(root.get(), commonPath);
|
||||||
root->addNode(std::move(sources));
|
|
||||||
|
root->addNode(std::make_unique<FileNode>(
|
||||||
|
projectFile,
|
||||||
|
FileType::Project,
|
||||||
|
false));
|
||||||
|
|
||||||
setRootProjectNode(std::move(root));
|
setRootProjectNode(std::move(root));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user