diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f8d33dc7..0b53297b 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -508,6 +508,8 @@ add_files( utility/UserPaths.h utility/utility.cpp utility/utility.h + utility/utilityFile.cpp + utility/utilityFile.h utility/utilityLibrary.h utility/utilityString.cpp utility/utilityString.h diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index 2b9ac7ff..4608bfed 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -124,7 +124,7 @@ std::string ProjectSettings::getProjectName() const return getFilePath().withoutExtension().fileName(); } -FilePath ProjectSettings::getProjectFileLocation() const +FilePath ProjectSettings::getProjectDirectoryPath() const { return getFilePath().parentDirectory(); } @@ -204,7 +204,7 @@ std::vector ProjectSettings::makePathsExpandedAndAbsolute(const std::v std::vector p = expandPaths(paths); std::vector absPaths; - FilePath basePath = getProjectFileLocation(); + FilePath basePath = getProjectDirectoryPath(); for (const FilePath& path : p) { if (path.isAbsolute()) @@ -229,7 +229,7 @@ FilePath ProjectSettings::makePathExpandedAndAbsolute(const FilePath& path) cons return p; } - return getProjectFileLocation().concat(p).canonical(); + return getProjectDirectoryPath().concat(p).canonical(); } SettingsMigrator ProjectSettings::getMigrations() const diff --git a/src/lib/settings/ProjectSettings.h b/src/lib/settings/ProjectSettings.h index b9dbeb2a..368265a2 100644 --- a/src/lib/settings/ProjectSettings.h +++ b/src/lib/settings/ProjectSettings.h @@ -33,7 +33,7 @@ public: void setProjectFilePath(std::string projectName, const FilePath& projectFileLocation); std::string getProjectName() const; - FilePath getProjectFileLocation() const; + FilePath getProjectDirectoryPath() const; std::string getDescription() const; diff --git a/src/lib/settings/SourceGroupSettings.cpp b/src/lib/settings/SourceGroupSettings.cpp index b5139954..419ce3e3 100644 --- a/src/lib/settings/SourceGroupSettings.cpp +++ b/src/lib/settings/SourceGroupSettings.cpp @@ -80,9 +80,9 @@ void SourceGroupSettings::setName(const std::string& name) m_name = name; } -FilePath SourceGroupSettings::getProjectFileLocation() const +FilePath SourceGroupSettings::getProjectDirectoryPath() const { - return m_projectSettings->getProjectFileLocation(); + return m_projectSettings->getProjectDirectoryPath(); } FilePath SourceGroupSettings::makePathExpandedAndAbsolute(const FilePath& path) const diff --git a/src/lib/settings/SourceGroupSettings.h b/src/lib/settings/SourceGroupSettings.h index de440ae1..e23656ea 100644 --- a/src/lib/settings/SourceGroupSettings.h +++ b/src/lib/settings/SourceGroupSettings.h @@ -28,7 +28,7 @@ public: std::string getName() const; void setName(const std::string& name); - FilePath getProjectFileLocation() const; + FilePath getProjectDirectoryPath() const; FilePath makePathExpandedAndAbsolute(const FilePath& path) const; std::vector makePathsExpandedAndAbsolute(const std::vector& paths) const; diff --git a/src/lib/utility/utilityFile.cpp b/src/lib/utility/utilityFile.cpp new file mode 100644 index 00000000..e32bff5f --- /dev/null +++ b/src/lib/utility/utilityFile.cpp @@ -0,0 +1,28 @@ +#include "utility/utilityFile.h" + +std::vector utility::getTopLevelPaths(const std::vector& paths) +{ + std::vector topLevelPaths; + for (const FilePath& path : paths) + { + bool addPath = true; + for (size_t i = 0; i < topLevelPaths.size(); i++) + { + if (topLevelPaths[i].contains(path)) + { + addPath = false; + break; + } + else if(path.contains(topLevelPaths[i])) + { + topLevelPaths.erase(topLevelPaths.begin() + i); + break; + } + } + if (addPath) + { + topLevelPaths.push_back(path); + } + } + return topLevelPaths; +} diff --git a/src/lib/utility/utilityFile.h b/src/lib/utility/utilityFile.h new file mode 100644 index 00000000..982a36a0 --- /dev/null +++ b/src/lib/utility/utilityFile.h @@ -0,0 +1,13 @@ +#ifndef UTILITY_FILE_H +#define UTILITY_FILE_H + +#include + +#include "utility/file/FilePath.h" + +namespace utility +{ + std::vector getTopLevelPaths(const std::vector& paths); +} + +#endif // UTILITY_FILE_H diff --git a/src/lib_cxx/utility/CompilationDatabase.cpp b/src/lib_cxx/utility/CompilationDatabase.cpp index 1ddc62ff..6bafe656 100644 --- a/src/lib_cxx/utility/CompilationDatabase.cpp +++ b/src/lib_cxx/utility/CompilationDatabase.cpp @@ -5,15 +5,16 @@ #include "clang/Tooling/JSONCompilationDatabase.h" #include "clang/Tooling/CompilationDatabase.h" #include "utility/file/FilePath.h" +#include "utility/utilityString.h" #include "utility/utility.h" -utility::CompilationDatabase::CompilationDatabase(std::string filename) - : m_filename(filename) +utility::CompilationDatabase::CompilationDatabase(const FilePath& filePath) + : m_filePath(filePath) { - getHeaders(); + init(); } -std::vector utility::CompilationDatabase::getAllHeaderPaths() +std::vector utility::CompilationDatabase::getAllHeaderPaths() const { std::vector paths = utility::concat(m_headers, m_systemHeaders); paths = utility::concat(paths, m_frameworkHeaders); @@ -21,47 +22,64 @@ std::vector utility::CompilationDatabase::getAllHeaderPaths() return paths; } -std::vector utility::CompilationDatabase::getHeaderPaths() +std::vector utility::CompilationDatabase::getHeaderPaths() const { return m_headers; } -std::vector utility::CompilationDatabase::getSystemHeaderPaths() +std::vector utility::CompilationDatabase::getSystemHeaderPaths() const { return m_systemHeaders; } -std::vector utility::CompilationDatabase::getFrameworkHeaderPaths() +std::vector utility::CompilationDatabase::getFrameworkHeaderPaths() const { return m_frameworkHeaders; } -void utility::CompilationDatabase::getHeaders() +void utility::CompilationDatabase::init() { std::string error; - std::shared_ptr cdb = std::shared_ptr - (clang::tooling::JSONCompilationDatabase::loadFromFile(m_filename, error, clang::tooling::JSONCommandLineSyntax::AutoDetect)); + std::shared_ptr cdb = std::shared_ptr( + clang::tooling::JSONCompilationDatabase::loadFromFile(m_filePath.str(), error, clang::tooling::JSONCommandLineSyntax::AutoDetect) + ); std::vector commands = cdb->getAllCompileCommands(); std::set frameworkHeaders; std::set systemHeaders; std::set headers; - for (clang::tooling::CompileCommand& command : commands) { - for( size_t i = 0; i < command.CommandLine.size(); i++) + const std::string frameworkIncludeFlag = "-iframework"; + const std::string systemIncludeFlag = "-isystem"; + const std::string quoteFlag = "-iquote"; + const std::string includeFlag = "-I"; + for (clang::tooling::CompileCommand& command : commands) { - if( command.CommandLine[i] == "-iframework" ) + for (size_t i = 0; i < command.CommandLine.size(); i++) { - frameworkHeaders.insert(FilePath(command.CommandLine[++i], command.Directory)); - } - if( command.CommandLine[i] == "-isystem" ) - { - systemHeaders.insert(FilePath(command.CommandLine[++i], command.Directory)); - } - if( command.CommandLine[i].substr(0,2) == "-I" ) - { - headers.insert(FilePath(command.CommandLine[i].substr(2), command.Directory)); + std::string argument = command.CommandLine[i]; + if (!utility::isPrefix("-", command.CommandLine[i + 1])) + { + argument += command.CommandLine[++i]; + } + + if (utility::isPrefix(frameworkIncludeFlag, argument)) + { + frameworkHeaders.insert(FilePath(utility::trim(argument.substr(frameworkIncludeFlag.size())), command.Directory)); + } + else if (utility::isPrefix(systemIncludeFlag, argument)) + { + systemHeaders.insert(FilePath(utility::trim(argument.substr(systemIncludeFlag.size())), command.Directory)); + } + else if (utility::isPrefix(quoteFlag, argument)) + { + headers.insert(FilePath(utility::trim(argument.substr(quoteFlag.size())), command.Directory)); + } + else if (utility::isPrefix(includeFlag, argument)) + { + headers.insert(FilePath(utility::trim(argument.substr(includeFlag.size())), command.Directory)); + } } } } diff --git a/src/lib_cxx/utility/CompilationDatabase.h b/src/lib_cxx/utility/CompilationDatabase.h index 0cac86f6..d47df461 100644 --- a/src/lib_cxx/utility/CompilationDatabase.h +++ b/src/lib_cxx/utility/CompilationDatabase.h @@ -4,27 +4,27 @@ #include #include -class FilePath; +#include "utility/file/FilePath.h" namespace utility { class CompilationDatabase { public: - CompilationDatabase(std::string filename); + CompilationDatabase(const FilePath& filePath); - std::vector getAllHeaderPaths(); - std::vector getHeaderPaths(); - std::vector getSystemHeaderPaths(); - std::vector getFrameworkHeaderPaths(); + std::vector getAllHeaderPaths() const; + std::vector getHeaderPaths() const; + std::vector getSystemHeaderPaths() const; + std::vector getFrameworkHeaderPaths() const; private: - std::string m_filename; + void init(); + + FilePath m_filePath; std::vector m_headers; std::vector m_systemHeaders; std::vector m_frameworkHeaders; - - void getHeaders(); }; } diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp index 2d8e7a17..0f3d1d29 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp @@ -32,7 +32,7 @@ void QtProjectWizzardContentCDBSource::load() { m_fileNames.clear(); - const FilePath projectPath = m_settings->getProjectFileLocation(); + const FilePath projectPath = m_settings->getProjectDirectoryPath(); std::vector excludePaths = m_settings->getExcludePathsExpandedAndAbsolute(); if (std::shared_ptr cxxSettings = std::dynamic_pointer_cast(m_settings)) diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp index a215de28..d9ee1c50 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp @@ -41,7 +41,7 @@ void QtProjectWizzardContentPath::populate(QGridLayout* layout, int& row) if (m_makePathRelativeToProjectFileLocation) { - m_picker->setRelativeRootDirectory(m_settings->getProjectFileLocation()); + m_picker->setRelativeRootDirectory(m_settings->getProjectDirectoryPath()); } layout->addWidget(m_picker, row, QtProjectWizzardWindow::BACK_COL); @@ -263,7 +263,7 @@ std::vector QtProjectWizzardContentPathSourceMaven::getFileNames() m_settings->getSourceExtensions() ); - const FilePath projectPath = m_settings->getProjectFileLocation(); + const FilePath projectPath = m_settings->getProjectDirectoryPath(); for (FilePath path: fileManager.getAllSourceFilePaths()) { @@ -394,7 +394,7 @@ std::vector QtProjectWizzardContentPathSourceGradle::getFileNames() m_settings->getSourceExtensions() ); - const FilePath projectPath = m_settings->getProjectFileLocation(); + const FilePath projectPath = m_settings->getProjectDirectoryPath(); for (FilePath path : fileManager.getAllSourceFilePaths()) { diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp index 159d4d7f..539e295f 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp @@ -19,6 +19,7 @@ #include "utility/file/FileManager.h" #include "utility/ScopedFunctor.h" #include "utility/utility.h" +#include "utility/utilityFile.h" #include "utility/utilityPathDetection.h" #include "Application.h" @@ -43,7 +44,7 @@ void QtProjectWizzardContentPaths::populate(QGridLayout* layout, int& row) if (m_makePathsRelativeToProjectFileLocation && m_settings) { - m_list->setRelativeRootDirectory(m_settings->getProjectFileLocation()); + m_list->setRelativeRootDirectory(m_settings->getProjectDirectoryPath()); } layout->addWidget(m_list, row, QtProjectWizzardWindow::BACK_COL); @@ -192,7 +193,7 @@ std::vector QtProjectWizzardContentPathsSource::getFileNames() cons m_settings->getSourceExtensions() ); - const std::set filePaths = fileManager.getAllSourceFilePathsRelative(m_settings->getProjectFileLocation()); + const std::set filePaths = fileManager.getAllSourceFilePathsRelative(m_settings->getProjectDirectoryPath()); std::vector list; list.resize(filePaths.size()); @@ -211,6 +212,22 @@ QString QtProjectWizzardContentPathsSource::getFileNamesDescription() const return " files will be indexed."; } + +std::vector QtProjectWizzardContentPathsCDBHeader::getTopLevelHeaderSearchPaths( + std::shared_ptr settings) +{ + const FilePath cdbPath = settings->getCompilationDatabasePathExpandedAndAbsolute(); + if (!cdbPath.exists()) + { + LOG_WARNING("Unable to fetch top level header search directories. The provided Compilation Database path does not exist."); + return std::vector(); + } + const std::vector sourcePaths = settings->getSourcePaths(); + return utility::getTopLevelPaths(utility::unique(utility::concat( + sourcePaths, utility::CompilationDatabase(cdbPath).getAllHeaderPaths() + ))); +} + QtProjectWizzardContentPathsCDBHeader::QtProjectWizzardContentPathsCDBHeader( std::shared_ptr settings, QtProjectWizzardWindow* window ) @@ -242,6 +259,25 @@ void QtProjectWizzardContentPathsCDBHeader::populate(QGridLayout* layout, int& r row++; } +void QtProjectWizzardContentPathsCDBHeader::load() +{ + if (m_settings->getSourcePaths().empty()) + { + std::shared_ptr cdbSettings = std::dynamic_pointer_cast(m_settings); + std::vector sourcePaths; + for (const FilePath& path : getTopLevelHeaderSearchPaths(cdbSettings)) + { + if (path.exists() && m_settings->getProjectDirectoryPath().contains(path)) + { + sourcePaths.push_back(path); + } + } + m_settings->setSourcePaths(sourcePaths); + } + + QtProjectWizzardContentPathsSource::load(); +} + bool QtProjectWizzardContentPathsCDBHeader::check() { if (!m_list->getList().size()) @@ -269,7 +305,7 @@ void QtProjectWizzardContentPathsCDBHeader::buttonClicked() if (!m_filesDialog) { - FilePath cdbPath = dynamic_cast(m_settings.get())->getCompilationDatabasePathExpandedAndAbsolute(); // TODO: remove this cast + const FilePath cdbPath = std::dynamic_pointer_cast(m_settings)->getCompilationDatabasePathExpandedAndAbsolute(); if (!cdbPath.exists()) { QMessageBox msgBox; @@ -287,31 +323,11 @@ void QtProjectWizzardContentPathsCDBHeader::buttonClicked() connect(m_filesDialog.get(), &QtSelectPathsDialog::finished, this, &QtProjectWizzardContentPathsCDBHeader::savedFilesDialog); connect(m_filesDialog.get(), &QtSelectPathsDialog::canceled, this, &QtProjectWizzardContentPathsCDBHeader::closedFilesDialog); - - - utility::CompilationDatabase cdb(cdbPath.str()); - - std::vector sourcePaths = m_settings->getSourcePaths(); - - std::vector cdbHeaderPaths; - for (const FilePath& path: utility::unique(utility::concat(sourcePaths, cdb.getAllHeaderPaths()))) - { - bool addPath = true; - for (const FilePath& cdbHeaderPath: cdbHeaderPaths) - { - if (cdbHeaderPath.contains(path)) - { - addPath = false; - break; - } - } - if (addPath) - { - cdbHeaderPaths.push_back(path); - } - } - - dynamic_cast(m_filesDialog.get())->setPathsList(cdbHeaderPaths, sourcePaths); + + dynamic_cast(m_filesDialog.get())->setPathsList( + getTopLevelHeaderSearchPaths(std::dynamic_pointer_cast(m_settings)), + m_settings->getSourcePaths() + ); } m_filesDialog->showWindow(); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h index ab9747bb..ba492931 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h @@ -10,6 +10,7 @@ class QComboBox; class QPushButton; class QtDirectoryListBox; class SourceGroupSettings; +class SourceGroupSettingsCxxCdb; class QtProjectWizzardContentPaths : public QtProjectWizzardContent @@ -75,10 +76,14 @@ class QtProjectWizzardContentPathsCDBHeader Q_OBJECT public: + static std::vector getTopLevelHeaderSearchPaths(std::shared_ptr settings); + QtProjectWizzardContentPathsCDBHeader(std::shared_ptr settings, QtProjectWizzardWindow* window); virtual void populate(QGridLayout* layout, int& row) override; + virtual void load() override; + virtual bool check() override; private slots: diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentProjectData.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentProjectData.cpp index 595d0294..92a141c0 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentProjectData.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentProjectData.cpp @@ -57,7 +57,7 @@ void QtProjectWizzardContentProjectData::populate(QGridLayout* layout, int& row) void QtProjectWizzardContentProjectData::load() { m_projectName->setText(QString::fromStdString(m_projectSettings->getProjectName())); - m_projectFileLocation->setText(QString::fromStdString(m_projectSettings->getProjectFileLocation().str())); + m_projectFileLocation->setText(QString::fromStdString(m_projectSettings->getProjectDirectoryPath().str())); } void QtProjectWizzardContentProjectData::save()