logic: add include path validation to project settings
This commit is contained in:
@@ -56,6 +56,23 @@ std::set<FilePath> FileManager::getAllSourceFilePaths() const
|
|||||||
return m_allSourceFilePaths;
|
return m_allSourceFilePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<FilePath> FileManager::getAllSourceFilePathsRelative(const FilePath& baseDirectory) const
|
||||||
|
{
|
||||||
|
std::set<FilePath> absolutePaths;
|
||||||
|
for (const FilePath& path: getAllSourceFilePaths())
|
||||||
|
{
|
||||||
|
if (baseDirectory.exists())
|
||||||
|
{
|
||||||
|
absolutePaths.insert(path.relativeTo(baseDirectory));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
absolutePaths.insert(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return absolutePaths;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<FilePath> FileManager::makeCanonical(const std::vector<FilePath>& filePaths)
|
std::vector<FilePath> FileManager::makeCanonical(const std::vector<FilePath>& filePaths)
|
||||||
{
|
{
|
||||||
std::vector<FilePath> ret;
|
std::vector<FilePath> ret;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
|
|
||||||
// returns a list of paths to all files that reside in the non-excluded source paths
|
// returns a list of paths to all files that reside in the non-excluded source paths
|
||||||
std::set<FilePath> getAllSourceFilePaths() const;
|
std::set<FilePath> getAllSourceFilePaths() const;
|
||||||
|
std::set<FilePath> getAllSourceFilePathsRelative(const FilePath& baseDirectory) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<FilePath> makeCanonical(const std::vector<FilePath>& filePaths);
|
std::vector<FilePath> makeCanonical(const std::vector<FilePath>& filePaths);
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
#include "SharedUUIDManager.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "utility/file/FileSystem.h"
|
|
||||||
#include "utility/ConfigManager.h"
|
|
||||||
#include "utility/text/TextAccess.h"
|
|
||||||
|
|
||||||
#include "utility/UserPaths.h"
|
|
||||||
|
|
||||||
const std::string SharedUUIDManager::m_fileName("sharedUUIDs.xml");
|
|
||||||
const std::string SharedUUIDManager::m_instanceUUIDsKey("instances");
|
|
||||||
std::shared_ptr<SharedUUIDManager> SharedUUIDManager::m_instance(NULL);
|
|
||||||
|
|
||||||
std::shared_ptr<SharedUUIDManager> SharedUUIDManager::getInstance()
|
|
||||||
{
|
|
||||||
if (m_instance == NULL)
|
|
||||||
{
|
|
||||||
// m_instance = std::make_shared<SharedUUIDManager>();
|
|
||||||
SharedUUIDManager* sharedUUIDManager = new SharedUUIDManager();
|
|
||||||
m_instance = std::shared_ptr<SharedUUIDManager>(sharedUUIDManager);
|
|
||||||
m_instance->setFilePath(UserPaths::getUserDataPath().str());
|
|
||||||
m_instance->saveInstanceUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedUUIDManager::~SharedUUIDManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedUUIDManager::setFilePath(const std::string& filePath)
|
|
||||||
{
|
|
||||||
m_filePath = filePath;
|
|
||||||
FileSystem::createDirectory(FilePath(m_filePath));
|
|
||||||
|
|
||||||
refreshUUIDs();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SharedUUIDManager::getInstanceUUID() const
|
|
||||||
{
|
|
||||||
return UUIDUtility::UUIDtoString(m_instanceUUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SharedUUIDManager::getNewUUID()
|
|
||||||
{
|
|
||||||
std::string uuidString = UUIDUtility::getUUIDString();
|
|
||||||
|
|
||||||
std::vector<std::string> uuids;
|
|
||||||
m_uuids->getValues(UUIDUtility::UUIDtoString(m_instanceUUID), uuids);
|
|
||||||
|
|
||||||
uuids.push_back(uuidString);
|
|
||||||
|
|
||||||
m_uuids->setValues(UUIDUtility::UUIDtoString(m_instanceUUID), uuids);
|
|
||||||
|
|
||||||
m_uuids->save(m_filePath + m_fileName);
|
|
||||||
|
|
||||||
return uuidString;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> SharedUUIDManager::getUUIDsForInstance(const std::string& instanceUUID)
|
|
||||||
{
|
|
||||||
std::vector<std::string> uuids;
|
|
||||||
m_uuids->getValues(instanceUUID, uuids);
|
|
||||||
|
|
||||||
return uuids;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedUUIDManager::removeUUIDsForInstance(const std::string& instanceUUID)
|
|
||||||
{
|
|
||||||
m_uuids->removeValues(instanceUUID);
|
|
||||||
|
|
||||||
m_uuids->save(m_filePath + m_fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> SharedUUIDManager::getStoredInstanceUUIDs() const
|
|
||||||
{
|
|
||||||
std::vector<std::string> instanceUUIDs;
|
|
||||||
m_uuids->getValues(m_instanceUUIDsKey, instanceUUIDs);
|
|
||||||
|
|
||||||
return instanceUUIDs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedUUIDManager::removeInstanceUUID(const std::string& instanceUUID)
|
|
||||||
{
|
|
||||||
std::vector<std::string> instanceUUIDs;
|
|
||||||
m_uuids->getValues(m_instanceUUIDsKey, instanceUUIDs);
|
|
||||||
|
|
||||||
// instanceUUIDs
|
|
||||||
for (std::vector<std::string>::iterator it = instanceUUIDs.begin(); it != instanceUUIDs.end(); it++)
|
|
||||||
{
|
|
||||||
if (*it == instanceUUID)
|
|
||||||
{
|
|
||||||
instanceUUIDs.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_uuids->setValues(m_instanceUUIDsKey, instanceUUIDs);
|
|
||||||
m_uuids->save(m_filePath + m_fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedUUIDManager::SharedUUIDManager()
|
|
||||||
: m_filePath("user/")
|
|
||||||
, m_instanceUUID(UUIDUtility::getUUID())
|
|
||||||
, m_uuids(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedUUIDManager::saveInstanceUUID()
|
|
||||||
{
|
|
||||||
std::vector<std::string> instanceUUIDs;
|
|
||||||
m_uuids->getValues(m_instanceUUIDsKey, instanceUUIDs);
|
|
||||||
|
|
||||||
instanceUUIDs.push_back(getInstanceUUID());
|
|
||||||
m_uuids->setValues(m_instanceUUIDsKey, instanceUUIDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedUUIDManager::refreshUUIDs()
|
|
||||||
{
|
|
||||||
if (FilePath(m_filePath + m_fileName).exists())
|
|
||||||
{
|
|
||||||
m_uuids = ConfigManager::createAndLoad(TextAccess::createFromFile(FilePath(m_filePath + m_fileName)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -166,7 +166,8 @@ std::vector<T> utility::unique(const std::vector<T>& a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<T> r(i, T());
|
std::vector<T> r;
|
||||||
|
r.reserve(i);
|
||||||
for (const std::pair<T, size_t>& p : unique)
|
for (const std::pair<T, size_t>& p : unique)
|
||||||
{
|
{
|
||||||
r[p.second] = p.first;
|
r[p.second] = p.first;
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ add_files(
|
|||||||
data/storage/StorageTransformationAnonymousTypedef.cpp
|
data/storage/StorageTransformationAnonymousTypedef.cpp
|
||||||
data/storage/StorageTransformationAnonymousTypedef.h
|
data/storage/StorageTransformationAnonymousTypedef.h
|
||||||
|
|
||||||
|
project/IncludeDirective.cpp
|
||||||
|
project/IncludeDirective.h
|
||||||
|
project/IncludeValidation.cpp
|
||||||
|
project/IncludeValidation.h
|
||||||
project/SourceGroupCxx.cpp
|
project/SourceGroupCxx.cpp
|
||||||
project/SourceGroupCxx.h
|
project/SourceGroupCxx.h
|
||||||
project/SourceGroupFactoryModuleCpp.cpp
|
project/SourceGroupFactoryModuleCpp.cpp
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "project/IncludeDirective.h"
|
||||||
|
|
||||||
|
IncludeDirective::IncludeDirective(
|
||||||
|
const FilePath& includedFilePath,
|
||||||
|
const FilePath& includingFilePath,
|
||||||
|
unsigned int lineNumber,
|
||||||
|
bool usesBrackets
|
||||||
|
)
|
||||||
|
: m_includedFilePath(includedFilePath)
|
||||||
|
, m_includingFilePath(includingFilePath)
|
||||||
|
, m_lineNumber(lineNumber)
|
||||||
|
, m_usesBrackets(usesBrackets)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath IncludeDirective::getIncludedFile() const
|
||||||
|
{
|
||||||
|
return m_includedFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath IncludeDirective::getIncludingFile() const
|
||||||
|
{
|
||||||
|
return m_includingFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string IncludeDirective::getDirective() const
|
||||||
|
{
|
||||||
|
return std::string("#include ") + (m_usesBrackets ? "<" : "\"") + m_includedFilePath.str() + (m_usesBrackets ? ">" : "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int IncludeDirective::getLineNumber() const
|
||||||
|
{
|
||||||
|
return m_lineNumber;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef INCLUDE_DIRECTIVE_H
|
||||||
|
#define INCLUDE_DIRECTIVE_H
|
||||||
|
|
||||||
|
#include "utility/file/FilePath.h"
|
||||||
|
|
||||||
|
class IncludeDirective
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IncludeDirective(
|
||||||
|
const FilePath& includedFilePath,
|
||||||
|
const FilePath& includingFilePath,
|
||||||
|
unsigned int lineNumber,
|
||||||
|
bool usesBrackets);
|
||||||
|
|
||||||
|
FilePath getIncludedFile() const;
|
||||||
|
FilePath getIncludingFile() const;
|
||||||
|
std::string getDirective() const;
|
||||||
|
unsigned int getLineNumber() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FilePath m_includedFilePath;
|
||||||
|
const FilePath m_includingFilePath;
|
||||||
|
const unsigned int m_lineNumber;
|
||||||
|
bool m_usesBrackets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INCLUDE_DIRECTIVE_H
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
#include "project/IncludeValidation.h"
|
||||||
|
|
||||||
|
#include "project/IncludeDirective.h"
|
||||||
|
#include "utility/file/FilePath.h"
|
||||||
|
#include "utility/text/TextAccess.h"
|
||||||
|
#include "utility/utility.h"
|
||||||
|
#include "utility/utilityString.h"
|
||||||
|
|
||||||
|
std::vector<IncludeDirective> IncludeValidation::getUnresolvedIncludeDirectives(
|
||||||
|
const std::vector<FilePath>& sourceFilePaths,
|
||||||
|
const std::vector<FilePath>& indexedPaths,
|
||||||
|
const std::vector<FilePath>& headerSearchDirectories,
|
||||||
|
size_t quantileCount, std::function<void(float)> progress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
struct IncludeDirectiveComparator
|
||||||
|
{
|
||||||
|
bool operator()(const IncludeDirective& a, const IncludeDirective& b)
|
||||||
|
{
|
||||||
|
return a.getIncludedFile() < b.getIncludedFile();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::set<std::string> processedFilePaths;
|
||||||
|
std::set<IncludeDirective, IncludeDirectiveComparator> unresolvedIncludeDirectives;
|
||||||
|
|
||||||
|
quantileCount = std::min(quantileCount, sourceFilePaths.size());
|
||||||
|
|
||||||
|
std::vector<std::vector<FilePath>> quantiles;
|
||||||
|
for (size_t i = 0; i < quantileCount; i++)
|
||||||
|
{
|
||||||
|
quantiles.push_back(std::vector<FilePath>());
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < sourceFilePaths.size(); i++)
|
||||||
|
{
|
||||||
|
quantiles[i%quantileCount].push_back(sourceFilePaths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < quantiles.size(); i++)
|
||||||
|
{
|
||||||
|
const std::vector<FilePath>& quantile = quantiles[i];
|
||||||
|
|
||||||
|
progress(float(i) / quantiles.size());
|
||||||
|
|
||||||
|
std::set<FilePath> unprocessedFilePaths(quantile.begin(), quantile.end());
|
||||||
|
|
||||||
|
while (!unprocessedFilePaths.empty())
|
||||||
|
{
|
||||||
|
std::transform(unprocessedFilePaths.begin(), unprocessedFilePaths.end(), std::inserter(processedFilePaths, processedFilePaths.begin()), [](const FilePath& p){ return p.str(); });
|
||||||
|
std::set<FilePath> tempUnprocessedFilePaths;
|
||||||
|
|
||||||
|
for (const FilePath& filePath: unprocessedFilePaths)
|
||||||
|
{
|
||||||
|
for (const IncludeDirective& includeDirective: getIncludeDirectives(filePath))
|
||||||
|
{
|
||||||
|
const FilePath resolvedIncludePath = resolveIncludeDirective(includeDirective, headerSearchDirectories);
|
||||||
|
if (resolvedIncludePath.empty())
|
||||||
|
{
|
||||||
|
unresolvedIncludeDirectives.insert(includeDirective);
|
||||||
|
}
|
||||||
|
else if (processedFilePaths.find(resolvedIncludePath.str()) == processedFilePaths.end())
|
||||||
|
{
|
||||||
|
for (const FilePath& indexedPath: indexedPaths)
|
||||||
|
{
|
||||||
|
if (indexedPath.contains(resolvedIncludePath))
|
||||||
|
{
|
||||||
|
tempUnprocessedFilePaths.insert(resolvedIncludePath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unprocessedFilePaths = tempUnprocessedFilePaths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<IncludeDirective> ret;
|
||||||
|
|
||||||
|
for (const IncludeDirective& directive: unresolvedIncludeDirectives)
|
||||||
|
{
|
||||||
|
ret.push_back(directive);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress(1.0f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<IncludeDirective> IncludeValidation::getIncludeDirectives(const FilePath& filePath)
|
||||||
|
{
|
||||||
|
std::vector<IncludeDirective> includeDirectives;
|
||||||
|
|
||||||
|
if (filePath.exists())
|
||||||
|
{
|
||||||
|
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||||
|
const std::vector<std::string> lines = textAccess->getAllLines();
|
||||||
|
for (size_t i = 0; i < lines.size(); i++)
|
||||||
|
{
|
||||||
|
const std::string lineTrimmedToHash = utility::trim(lines[i]);
|
||||||
|
if (utility::isPrefix("#", lineTrimmedToHash))
|
||||||
|
{
|
||||||
|
const std::string lineTrimmedToInclude = utility::trim(lineTrimmedToHash.substr(1));
|
||||||
|
if (utility::isPrefix("include", lineTrimmedToInclude))
|
||||||
|
{
|
||||||
|
std::string includeString = utility::substrBetween(lineTrimmedToInclude, "<", ">");
|
||||||
|
bool usesBrackets = true;
|
||||||
|
if (includeString.empty())
|
||||||
|
{
|
||||||
|
includeString = utility::substrBetween(lineTrimmedToInclude, "\"", "\"");
|
||||||
|
usesBrackets = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!includeString.empty())
|
||||||
|
{
|
||||||
|
// lines are 1 based
|
||||||
|
includeDirectives.push_back(IncludeDirective(FilePath(includeString), filePath, i + 1, usesBrackets));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return includeDirectives;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath IncludeValidation::resolveIncludeDirective(const IncludeDirective& includeDirective, const std::vector<FilePath>& headerSearchDirectories)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// check for an absolute include path
|
||||||
|
if (includeDirective.getIncludedFile().exists())
|
||||||
|
{
|
||||||
|
return includeDirective.getIncludedFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check for an include path relative to the including path
|
||||||
|
FilePath resolvedIncludePath = includeDirective.getIncludingFile().parentDirectory().concat(includeDirective.getIncludedFile());
|
||||||
|
if (resolvedIncludePath.exists())
|
||||||
|
{
|
||||||
|
return resolvedIncludePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check for an include path relative to the header search directories
|
||||||
|
for (const FilePath& headerSearchDirectory: headerSearchDirectories)
|
||||||
|
{
|
||||||
|
FilePath resolvedIncludePath = headerSearchDirectory.concat(includeDirective.getIncludedFile());
|
||||||
|
if (resolvedIncludePath.exists())
|
||||||
|
{
|
||||||
|
return resolvedIncludePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilePath();
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef INCLUDE_VALIDATION_H
|
||||||
|
#define INCLUDE_VALIDATION_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class FilePath;
|
||||||
|
class IncludeDirective;
|
||||||
|
|
||||||
|
class IncludeValidation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::vector<IncludeDirective> getUnresolvedIncludeDirectives(
|
||||||
|
const std::vector<FilePath>& sourceFilePaths,
|
||||||
|
const std::vector<FilePath>& indexedPaths,
|
||||||
|
const std::vector<FilePath>& headerSearchDirectories,
|
||||||
|
size_t quantileCount, std::function<void(float)> progress);
|
||||||
|
private:
|
||||||
|
static std::vector<IncludeDirective> getIncludeDirectives(const FilePath& filePath);
|
||||||
|
static FilePath resolveIncludeDirective(const IncludeDirective& includeDirective, const std::vector<FilePath>& headerSearchDirectories);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INCLUDE_VALIDATION_H
|
||||||
@@ -6,15 +6,21 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "component/view/DialogView.h"
|
||||||
|
#include "project/IncludeDirective.h"
|
||||||
|
#include "project/IncludeValidation.h"
|
||||||
#include "qt/element/QtDirectoryListBox.h"
|
#include "qt/element/QtDirectoryListBox.h"
|
||||||
|
#include "qt/view/QtDialogView.h"
|
||||||
#include "qt/window/QtSelectPathsDialog.h"
|
#include "qt/window/QtSelectPathsDialog.h"
|
||||||
#include "settings/ApplicationSettings.h"
|
#include "settings/ApplicationSettings.h"
|
||||||
#include "settings/SourceGroupSettingsCxx.h"
|
#include "settings/SourceGroupSettingsCxx.h"
|
||||||
#include "settings/SourceGroupSettingsJava.h"
|
#include "settings/SourceGroupSettingsJava.h"
|
||||||
#include "utility/CompilationDatabase.h"
|
#include "utility/CompilationDatabase.h"
|
||||||
#include "utility/file/FileManager.h"
|
#include "utility/file/FileManager.h"
|
||||||
|
#include "utility/ScopedFunctor.h"
|
||||||
#include "utility/utility.h"
|
#include "utility/utility.h"
|
||||||
#include "utility/utilityPathDetection.h"
|
#include "utility/utilityPathDetection.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
QtProjectWizzardContentPaths::QtProjectWizzardContentPaths(std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window)
|
QtProjectWizzardContentPaths::QtProjectWizzardContentPaths(std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window)
|
||||||
: QtProjectWizzardContent(window)
|
: QtProjectWizzardContent(window)
|
||||||
@@ -177,18 +183,11 @@ std::vector<std::string> QtProjectWizzardContentPathsSource::getFileNames() cons
|
|||||||
m_settings->getSourceExtensions()
|
m_settings->getSourceExtensions()
|
||||||
);
|
);
|
||||||
|
|
||||||
const FilePath projectPath = m_settings->getProjectFileLocation();
|
const std::set<FilePath> filePaths = fileManager.getAllSourceFilePathsRelative(m_settings->getProjectFileLocation());
|
||||||
|
|
||||||
std::vector<std::string> list;
|
std::vector<std::string> list;
|
||||||
for (FilePath path: fileManager.getAllSourceFilePaths())
|
list.resize(filePaths.size());
|
||||||
{
|
std::transform(filePaths.begin(), filePaths.end(), list.begin(), [](const FilePath& p){ return p.str(); });
|
||||||
if (projectPath.exists())
|
|
||||||
{
|
|
||||||
path = path.relativeTo(projectPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
list.push_back(path.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -328,6 +327,7 @@ QtProjectWizzardContentPathsHeaderSearch::QtProjectWizzardContentPathsHeaderSear
|
|||||||
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool isCDB
|
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool isCDB
|
||||||
)
|
)
|
||||||
: QtProjectWizzardContentPaths(settings, window)
|
: QtProjectWizzardContentPaths(settings, window)
|
||||||
|
, m_showValidationResultFunctor(std::bind(&QtProjectWizzardContentPathsHeaderSearch::showValidationResult, this, std::placeholders::_1))
|
||||||
{
|
{
|
||||||
setTitleString(isCDB ? "Additional Include Paths" : "Include Paths");
|
setTitleString(isCDB ? "Additional Include Paths" : "Include Paths");
|
||||||
setHelpString(
|
setHelpString(
|
||||||
@@ -345,6 +345,18 @@ QtProjectWizzardContentPathsHeaderSearch::QtProjectWizzardContentPathsHeaderSear
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtProjectWizzardContentPathsHeaderSearch::populate(QGridLayout* layout, int& row)
|
||||||
|
{
|
||||||
|
QtProjectWizzardContentPaths::populate(layout, row);
|
||||||
|
|
||||||
|
QPushButton* button = new QPushButton("validate include directives");
|
||||||
|
button->setObjectName("windowButton");
|
||||||
|
connect(button, SIGNAL(clicked()), this, SLOT(validateButtonClicked()));
|
||||||
|
|
||||||
|
layout->addWidget(button, row, QtProjectWizzardWindow::BACK_COL, Qt::AlignRight | Qt::AlignTop);
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
void QtProjectWizzardContentPathsHeaderSearch::load()
|
void QtProjectWizzardContentPathsHeaderSearch::load()
|
||||||
{
|
{
|
||||||
std::shared_ptr<SourceGroupSettingsCxx> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxx>(m_settings);
|
std::shared_ptr<SourceGroupSettingsCxx> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxx>(m_settings);
|
||||||
@@ -368,6 +380,115 @@ bool QtProjectWizzardContentPathsHeaderSearch::isScrollAble() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtProjectWizzardContentPathsHeaderSearch::validateButtonClicked()
|
||||||
|
{
|
||||||
|
// TODO: regard Force Includes here, too!
|
||||||
|
m_window->saveContent();
|
||||||
|
|
||||||
|
std::thread([&]()
|
||||||
|
{
|
||||||
|
std::vector<IncludeDirective> unresolvedIncludes;
|
||||||
|
{
|
||||||
|
std::shared_ptr<DialogView> dialogView = Application::getInstance()->getDialogView();
|
||||||
|
std::dynamic_pointer_cast<QtDialogView>(dialogView)->setParentWindow(m_window);
|
||||||
|
ScopedFunctor dialogParentResetter([&dialogView](){
|
||||||
|
std::dynamic_pointer_cast<QtDialogView>(dialogView)->setParentWindow(nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<FilePath> sourceFilePaths;
|
||||||
|
std::vector<FilePath> indexedFilePaths;
|
||||||
|
std::vector<FilePath> headerSearchPaths;
|
||||||
|
|
||||||
|
{
|
||||||
|
dialogView->showUnknownProgressDialog("Processing", "Gathering Source Files");
|
||||||
|
ScopedFunctor dialogHider([&dialogView](){
|
||||||
|
dialogView->hideUnknownProgressDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
FileManager fileManager;
|
||||||
|
fileManager.update(
|
||||||
|
m_settings->getSourcePathsExpandedAndAbsolute(),
|
||||||
|
m_settings->getExcludePathsExpandedAndAbsolute(),
|
||||||
|
m_settings->getSourceExtensions()
|
||||||
|
);
|
||||||
|
sourceFilePaths = utility::toVector(fileManager.getAllSourceFilePaths());
|
||||||
|
|
||||||
|
headerSearchPaths = ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded();
|
||||||
|
|
||||||
|
if (std::shared_ptr<SourceGroupSettingsCxx> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxx>(m_settings))
|
||||||
|
{
|
||||||
|
indexedFilePaths = cxxSettings->getSourcePaths();
|
||||||
|
utility::append(headerSearchPaths, cxxSettings->getHeaderSearchPathsExpandedAndAbsolute());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ScopedFunctor dialogHider([&dialogView](){
|
||||||
|
dialogView->hideProgressDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
unresolvedIncludes = IncludeValidation::getUnresolvedIncludeDirectives(
|
||||||
|
sourceFilePaths,
|
||||||
|
indexedFilePaths,
|
||||||
|
headerSearchPaths,
|
||||||
|
log2(sourceFilePaths.size()),
|
||||||
|
[&](const float progress)
|
||||||
|
{
|
||||||
|
Application::getInstance()->getDialogView()->showProgressDialog(
|
||||||
|
"Processing", std::to_string(int(progress * sourceFilePaths.size())) + " Files", int(progress * 100.0f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_showValidationResultFunctor(unresolvedIncludes);
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProjectWizzardContentPathsHeaderSearch::showValidationResult(const std::vector<IncludeDirective>& unresolvedIncludes)
|
||||||
|
{
|
||||||
|
if (unresolvedIncludes.empty())
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText("<p>All include directives throughout the indexed files have been resolved.</p>");
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string detailedText = "";
|
||||||
|
for (const IncludeDirective& unresolvedInclude: unresolvedIncludes)
|
||||||
|
{
|
||||||
|
detailedText += unresolvedInclude.getIncludingFile().str() + "[" + std::to_string(unresolvedInclude.getLineNumber()) + "]: " + unresolvedInclude.getDirective() + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText(QString::fromStdString(
|
||||||
|
"<p>The indexed files contain <b>" + std::to_string(unresolvedIncludes.size()) + "</b> include directive" + (unresolvedIncludes.size() == 1 ? "" : "s") + " that could "
|
||||||
|
"not be resolved correctly. Please check the details and add the respective header search paths.</p>"
|
||||||
|
"<p><b>Note</b>: This is only a quick pass that does not regard block commenting or conditional preprocessor directives. This means that "
|
||||||
|
"some of the unresolved includes may actually not be required by the indexer.</p>"));
|
||||||
|
msgBox.setDetailedText(QString::fromStdString(detailedText));
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if (!m_filesDialog)
|
||||||
|
//{
|
||||||
|
// m_filesDialog = std::make_shared<QtTextEditDialog>(
|
||||||
|
// getFileNamesTitle(), QString::number(fileNames.size()) + " " + getFileNamesDescription());
|
||||||
|
// m_filesDialog->setup();
|
||||||
|
|
||||||
|
// m_filesDialog->setText(utility::join(fileNames, "\n"));
|
||||||
|
// m_filesDialog->setCloseVisible(false);
|
||||||
|
// m_filesDialog->setReadOnly(true);
|
||||||
|
|
||||||
|
// connect(m_filesDialog.get(), SIGNAL(finished()), this, SLOT(closedFilesDialog()));
|
||||||
|
// connect(m_filesDialog.get(), SIGNAL(canceled()), this, SLOT(closedFilesDialog()));
|
||||||
|
//}
|
||||||
|
|
||||||
|
//m_filesDialog->showWindow();
|
||||||
|
//m_filesDialog->raise();
|
||||||
|
}
|
||||||
|
|
||||||
QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHeaderSearchGlobal(
|
QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHeaderSearchGlobal(
|
||||||
QtProjectWizzardWindow* window
|
QtProjectWizzardWindow* window
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "qt/window/project_wizzard/QtProjectWizzardContent.h"
|
#include "qt/window/project_wizzard/QtProjectWizzardContent.h"
|
||||||
#include "utility/path_detector/CombinedPathDetector.h"
|
#include "utility/path_detector/CombinedPathDetector.h"
|
||||||
|
|
||||||
|
class IncludeDirective;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
@@ -99,15 +100,24 @@ public:
|
|||||||
class QtProjectWizzardContentPathsHeaderSearch
|
class QtProjectWizzardContentPathsHeaderSearch
|
||||||
: public QtProjectWizzardContentPaths
|
: public QtProjectWizzardContentPaths
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QtProjectWizzardContentPathsHeaderSearch(
|
QtProjectWizzardContentPathsHeaderSearch(
|
||||||
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool isCDB = false);
|
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool isCDB = false);
|
||||||
|
|
||||||
// QtProjectWizzardContent implementation
|
// QtProjectWizzardContent implementation
|
||||||
|
virtual void populate(QGridLayout* layout, int& row);
|
||||||
virtual void load() override;
|
virtual void load() override;
|
||||||
virtual void save() override;
|
virtual void save() override;
|
||||||
|
|
||||||
virtual bool isScrollAble() const override;
|
virtual bool isScrollAble() const override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void validateButtonClicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void showValidationResult(const std::vector<IncludeDirective>& unresolvedIncludes);
|
||||||
|
QtThreadedFunctor<std::vector<IncludeDirective>> m_showValidationResultFunctor;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtProjectWizzardContentPathsHeaderSearchGlobal
|
class QtProjectWizzardContentPathsHeaderSearchGlobal
|
||||||
|
|||||||
Reference in New Issue
Block a user