logic: fixed indexed header paths for compilation database project screw up the processing order of includes (issue #571)

* prevented indexed header paths for CDB to be appended to compile command
* fixed exists check for relative paths in QtSelectPathsDialog
* indexed header paths will automatically be updated when a new compilation database is picked
This commit is contained in:
mlangkabel
2018-04-27 17:51:03 +02:00
parent 872d24bf6a
commit a7ef02459a
12 changed files with 145 additions and 78 deletions
@@ -7,6 +7,7 @@
#include <QPushButton>
#include "utility/file/FilePath.h"
#include "utility/utility.h"
QtSelectPathsDialog::QtSelectPathsDialog(const QString& title, const QString& description, QWidget* parent)
: QtTextEditDialog(title, description, parent)
@@ -28,11 +29,11 @@ std::vector<FilePath> QtSelectPathsDialog::getPathsList() const
return checkedPaths;
}
void QtSelectPathsDialog::setPathsList(const std::vector<FilePath>& paths, const std::vector<FilePath>& checkedPaths)
void QtSelectPathsDialog::setPathsList(const std::vector<FilePath>& paths, const std::vector<FilePath>& checkedPaths, const FilePath& rootPathForRelativePaths)
{
std::set<FilePath> checked(checkedPaths.begin(), checkedPaths.end());
for (const FilePath& s : paths)
for (FilePath s : utility::unique(utility::concat(paths, checkedPaths)))
{
QListWidgetItem* item = new QListWidgetItem(QString::fromStdWString(s.wstr()), m_list);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
@@ -46,6 +47,11 @@ void QtSelectPathsDialog::setPathsList(const std::vector<FilePath>& paths, const
item->setCheckState(Qt::Checked);
}
if (!s.isAbsolute())
{
s = rootPathForRelativePaths.getConcatenated(s);
}
if (!s.exists())
{
item->setTextColor(Qt::red);
+1 -1
View File
@@ -14,7 +14,7 @@ public:
QtSelectPathsDialog(const QString& title, const QString& description, QWidget* parent = 0);
std::vector<FilePath> getPathsList() const;
void setPathsList(const std::vector<FilePath>& paths, const std::vector<FilePath>& checkedPaths);
void setPathsList(const std::vector<FilePath>& paths, const std::vector<FilePath>& checkedPaths, const FilePath& rootPathForRelativePaths);
virtual void populateWindow(QWidget* widget) override;
virtual void windowReady() override;
@@ -9,6 +9,7 @@
#include "Application.h"
#include "qt/element/QtLocationPicker.h"
#include "qt/view/QtDialogView.h"
#include "qt/window/project_wizzard/QtProjectWizzardContentPaths.h"
#include "settings/ApplicationSettings.h"
#include "settings/SourceGroupSettingsCxxCdb.h"
#include "settings/SourceGroupSettingsJavaMaven.h"
@@ -164,6 +165,12 @@ void QtProjectWizzardContentPathCDB::save()
void QtProjectWizzardContentPathCDB::pickedCDBPath()
{
m_window->saveContent();
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings))
{
cdbSettings->setIndexedHeaderPaths(QtProjectWizzardContentPathsCDBHeader::getIndexedPathsDerivedFromCDB(cdbSettings));
}
m_window->loadContent();
}
@@ -253,25 +253,52 @@ QString QtProjectWizzardContentPathsSource::getFileNamesDescription() const
}
std::vector<FilePath> QtProjectWizzardContentPathsCDBHeader::getTopLevelHeaderSearchPaths(
std::vector<FilePath> QtProjectWizzardContentPathsCDBHeader::getIndexedPathsDerivedFromCDB(
std::shared_ptr<SourceGroupSettingsCxxCdb> settings)
{
const FilePath projectPath = settings->getProjectDirectoryPath();
const FilePath cdbPath = settings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.exists())
std::set<FilePath> indexedHeaderPaths;
if (!cdbPath.empty() && cdbPath.exists())
{
LOG_WARNING("Unable to fetch top level header search directories. The provided Compilation Database path does not exist.");
return std::vector<FilePath>();
for (const FilePath& path : IndexerCommandCxxCdb::getSourceFilesFromCDB(cdbPath))
{
indexedHeaderPaths.insert(path.getParentDirectory());
}
}
const std::vector<FilePath> sourcePaths = settings->getSourcePaths();
return utility::getTopLevelPaths(utility::unique(utility::concat(
sourcePaths, utility::CompilationDatabase(cdbPath).getAllHeaderPaths()
)));
else
{
LOG_WARNING("Unable to fetch indexed header paths. The provided Compilation Database path does not exist.");
}
for (const FilePath& path : utility::CompilationDatabase(cdbPath).getAllHeaderPaths())
{
if (path.exists() && projectPath.contains(path))
{
indexedHeaderPaths.insert(path);
}
}
std::vector<FilePath> rootPaths;
FilePath lastPath;
for (const FilePath& path : indexedHeaderPaths)
{
if (lastPath.empty() || !lastPath.contains(path)) // don't add subdirectories of already added paths
{
lastPath = path;
rootPaths.push_back(path.getRelativeTo(projectPath));
}
}
return rootPaths;
}
QtProjectWizzardContentPathsCDBHeader::QtProjectWizzardContentPathsCDBHeader(
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window
)
: QtProjectWizzardContentPathsSource(settings, window)
: QtProjectWizzardContentPaths(settings, window, QtPathListBox::SELECTION_POLICY_FILES_AND_DIRECTORIES)
{
m_showFilesString = "";
@@ -305,47 +332,23 @@ void QtProjectWizzardContentPathsCDBHeader::populate(QGridLayout* layout, int& r
void QtProjectWizzardContentPathsCDBHeader::load()
{
if (m_settings->getSourcePaths().empty())
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings))
{
std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings =
std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings);
std::set<FilePath> sourcePaths;
const FilePath projectPath = m_settings->getProjectDirectoryPath();
const FilePath cdbPath = cdbSettings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.empty() && cdbPath.exists())
if (cdbSettings->getIndexedHeaderPaths().empty())
{
for (const FilePath& path : IndexerCommandCxxCdb::getSourceFilesFromCDB(cdbPath))
{
sourcePaths.insert(path.getParentDirectory());
}
cdbSettings->setIndexedHeaderPaths(getIndexedPathsDerivedFromCDB(cdbSettings));
}
for (const FilePath& path : getTopLevelHeaderSearchPaths(cdbSettings))
{
if (path.exists() && projectPath.contains(path))
{
sourcePaths.insert(path);
}
}
std::vector<FilePath> rootPaths;
FilePath lastPath;
for (const FilePath& path : sourcePaths)
{
if (lastPath.empty() || !lastPath.contains(path)) // don't add subdirectories of already added paths
{
lastPath = path;
rootPaths.push_back(path.getRelativeTo(projectPath));
}
}
m_settings->setSourcePaths(rootPaths);
m_list->setPaths(cdbSettings->getIndexedHeaderPaths());
}
}
QtProjectWizzardContentPathsSource::load();
void QtProjectWizzardContentPathsCDBHeader::save()
{
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings))
{
cdbSettings->setIndexedHeaderPaths(m_list->getPathsAsDisplayed());
}
}
bool QtProjectWizzardContentPathsCDBHeader::check()
@@ -375,30 +378,33 @@ void QtProjectWizzardContentPathsCDBHeader::buttonClicked()
if (!m_filesDialog)
{
const FilePath cdbPath =
std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings)->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.exists())
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings))
{
QMessageBox msgBox;
msgBox.setText("The provided Compilation Database path does not exist.");
msgBox.setDetailedText(QString::fromStdWString(cdbPath.wstr()));
msgBox.exec();
return;
const FilePath cdbPath = cdbSettings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.exists())
{
QMessageBox msgBox;
msgBox.setText("The provided Compilation Database path does not exist.");
msgBox.setDetailedText(QString::fromStdWString(cdbPath.wstr()));
msgBox.exec();
return;
}
m_filesDialog = std::make_shared<QtSelectPathsDialog>(
"Select from Include Paths",
"The list contains all Include Paths found in the Compilation Database. Red paths do not exist. Select the "
"paths containing the header files you want to index with Sourcetrail.");
m_filesDialog->setup();
connect(m_filesDialog.get(), &QtSelectPathsDialog::finished, this, &QtProjectWizzardContentPathsCDBHeader::savedFilesDialog);
connect(m_filesDialog.get(), &QtSelectPathsDialog::canceled, this, &QtProjectWizzardContentPathsCDBHeader::closedFilesDialog);
dynamic_cast<QtSelectPathsDialog*>(m_filesDialog.get())->setPathsList(
getIndexedPathsDerivedFromCDB(cdbSettings),
cdbSettings->getIndexedHeaderPaths(),
m_settings->getProjectDirectoryPath()
);
}
m_filesDialog = std::make_shared<QtSelectPathsDialog>(
"Select from Include Paths",
"The list contains all Include Paths found in the Compilation Database. Red paths do not exist. Select the "
"paths containing the header files you want to index with Sourcetrail.");
m_filesDialog->setup();
connect(m_filesDialog.get(), &QtSelectPathsDialog::finished, this, &QtProjectWizzardContentPathsCDBHeader::savedFilesDialog);
connect(m_filesDialog.get(), &QtSelectPathsDialog::canceled, this, &QtProjectWizzardContentPathsCDBHeader::closedFilesDialog);
dynamic_cast<QtSelectPathsDialog*>(m_filesDialog.get())->setPathsList(
getTopLevelHeaderSearchPaths(std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings)),
m_settings->getSourcePaths()
);
}
m_filesDialog->showWindow();
@@ -407,9 +413,7 @@ void QtProjectWizzardContentPathsCDBHeader::buttonClicked()
void QtProjectWizzardContentPathsCDBHeader::savedFilesDialog()
{
// TODO: extend instead of replace
m_list->setPaths(dynamic_cast<QtSelectPathsDialog*>(m_filesDialog.get())->getPathsList());
closedFilesDialog();
}
@@ -79,19 +79,22 @@ public:
virtual QString getFileNamesDescription() const override;
};
class QtProjectWizzardContentPathsCDBHeader
: public QtProjectWizzardContentPathsSource
: public QtProjectWizzardContentPaths
{
Q_OBJECT
public:
static std::vector<FilePath> getTopLevelHeaderSearchPaths(std::shared_ptr<SourceGroupSettingsCxxCdb> settings);
static std::vector<FilePath> getIndexedPathsDerivedFromCDB(std::shared_ptr<SourceGroupSettingsCxxCdb> settings);
QtProjectWizzardContentPathsCDBHeader(std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window);
virtual void populate(QGridLayout* layout, int& row) override;
// QtProjectWizzardContent implementation
virtual void load() override;
virtual void save() override;
virtual bool check() override;