logic: added Gradle project setup (issue #379)

* added implementation for Gradle project setup (icon is still missing)
* refactored project loading/saving and SourceGroupSettings
* removed long deprecated Cxx UseSourcePathsForHeaderSearch option

fortune cookie message = There is true and sincere friendship between you and your friends.
This commit is contained in:
mlangkabel
2017-10-02 18:43:59 +02:00
parent 72ae4d5695
commit e604d24c40
83 changed files with 3518 additions and 1182 deletions
+3 -182
View File
@@ -14,8 +14,7 @@
#include "Application.h"
SourceGroupCxx::SourceGroupCxx(std::shared_ptr<SourceGroupSettingsCxx> settings)
: m_settings(settings)
SourceGroupCxx::SourceGroupCxx()
{
}
@@ -23,185 +22,7 @@ SourceGroupCxx::~SourceGroupCxx()
{
}
SourceGroupType SourceGroupCxx::getType() const
std::shared_ptr<SourceGroupSettings> SourceGroupCxx::getSourceGroupSettings()
{
return m_settings->getType();
}
bool SourceGroupCxx::prepareRefresh()
{
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.empty() && !cdbPath.exists())
{
MessageStatus("Can't refresh project").dispatch();
if (std::shared_ptr<Application> application = Application::getInstance())
{
if (application->hasGUI())
{
std::vector<std::string> options;
options.push_back("Ok");
application->handleDialog(
"Can't refresh. The compilation database of the project does not exist anymore: " + cdbPath.str(),
options
);
}
}
return false;
}
return true;
}
void SourceGroupCxx::fetchAllSourceFilePaths()
{
std::vector<FilePath> sourcePaths;
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (cdbPath.exists())
{
sourcePaths = IndexerCommandCxxCdb::getSourceFilesFromCDB(cdbPath);
}
else
{
sourcePaths = m_settings->getSourcePathsExpandedAndAbsolute();
}
m_sourceFilePathsToIndex.clear();
FileManager fileManager;
fileManager.update(sourcePaths, m_settings->getExcludePathsExpandedAndAbsolute(), m_settings->getSourceExtensions());
m_allSourceFilePaths = fileManager.getAllSourceFilePaths();
}
std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxx::getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh)
{
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
std::vector<FilePath> systemHeaderSearchPaths;
utility::append(systemHeaderSearchPaths, m_settings->getHeaderSearchPathsExpandedAndAbsolute());
utility::append(systemHeaderSearchPaths, appSettings->getHeaderSearchPathsExpanded());
// Add the source paths as HeaderSearchPaths as well, so clang will also look here when searching include files.
for (const FilePath& sourcePath: m_settings->getSourcePathsExpandedAndAbsolute())
{
if (sourcePath.isDirectory())
{
systemHeaderSearchPaths.push_back(sourcePath);
}
}
// Add all subdirectories of the header search paths
if (m_settings->getUseSourcePathsForHeaderSearch())
{
std::vector<FilePath> headerSearchSubPaths;
for (const FilePath& sourcePath : m_settings->getSourcePathsExpandedAndAbsolute())
{
utility::append(headerSearchSubPaths, FileSystem::getSubDirectories(sourcePath));
}
utility::append(systemHeaderSearchPaths, utility::unique(headerSearchSubPaths));
}
std::vector<FilePath> frameworkSearchPaths;
utility::append(frameworkSearchPaths, m_settings->getFrameworkSearchPathsExpandedAndAbsolute());
utility::append(frameworkSearchPaths, appSettings->getFrameworkSearchPathsExpanded());
std::vector<std::string> compilerFlags;
{
const std::string targetFlag = m_settings->getTargetFlag();
if (!targetFlag.empty())
{
compilerFlags.push_back(targetFlag);
}
}
utility::append(compilerFlags, m_settings->getCompilerFlags());
std::set<FilePath> indexedPaths;
for (const FilePath& p : m_settings->getSourcePathsExpandedAndAbsolute())
{
if (p.exists())
{
indexedPaths.insert(p);
}
}
std::set<FilePath> excludedPaths;
for (const FilePath& p: m_settings->getExcludePathsExpandedAndAbsolute())
{
if (p.exists())
{
excludedPaths.insert(p);
}
}
const std::set<FilePath>& sourceFilePathsToIndex = (fullRefresh ? getAllSourceFilePaths() : getSourceFilePathsToIndex());
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands;
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (cdbPath.exists())
{
std::string error;
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = std::shared_ptr<clang::tooling::JSONCompilationDatabase>
(clang::tooling::JSONCompilationDatabase::loadFromFile(cdbPath.str(), error, clang::tooling::JSONCommandLineSyntax::AutoDetect));
if (!error.empty())
{
const std::string message = "Loading Clang compilation database failed with error: \"" + error + "\"";
LOG_ERROR(message);
MessageStatus(message, true).dispatch();
}
for (const clang::tooling::CompileCommand& command: cdb->getAllCompileCommands())
{
FilePath sourcePath = FilePath(command.Filename).canonical();
if (!sourcePath.isAbsolute())
{
sourcePath = FilePath(command.Directory + '/' + command.Filename).canonical();
}
if (filesToIndex->find(sourcePath) != filesToIndex->end() &&
sourceFilePathsToIndex.find(sourcePath) != sourceFilePathsToIndex.end())
{
std::vector<std::string> currentCompilerFlags = compilerFlags;
currentCompilerFlags.insert(currentCompilerFlags.end(), command.CommandLine.begin(), command.CommandLine.end());
indexerCommands.push_back(std::make_shared<IndexerCommandCxxCdb>(
sourcePath,
indexedPaths,
excludedPaths,
FilePath(command.Directory),
currentCompilerFlags,
systemHeaderSearchPaths,
frameworkSearchPaths,
m_settings->getShouldApplyAnonymousTypedefTransformation()
));
filesToIndex->erase(sourcePath);
}
}
}
else
{
for (const FilePath& sourcePath: sourceFilePathsToIndex)
{
if (filesToIndex->find(sourcePath) != filesToIndex->end())
{
indexerCommands.push_back(std::make_shared<IndexerCommandCxxManual>(
sourcePath,
indexedPaths,
excludedPaths,
m_settings->getStandard(),
systemHeaderSearchPaths,
frameworkSearchPaths,
compilerFlags,
m_settings->getShouldApplyAnonymousTypedefTransformation()
));
filesToIndex->erase(sourcePath);
}
}
}
return indexerCommands;
return getSourceGroupSettingsCxx();
}
+3 -11
View File
@@ -10,20 +10,12 @@
class SourceGroupCxx: public SourceGroup
{
public:
SourceGroupCxx(std::shared_ptr<SourceGroupSettingsCxx> settings);
SourceGroupCxx();
virtual ~SourceGroupCxx();
virtual SourceGroupType getType() const;
virtual bool prepareRefresh();
virtual void fetchAllSourceFilePaths();
virtual std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh);
private:
std::shared_ptr<SourceGroupSettingsCxx> m_settings;
virtual std::shared_ptr<SourceGroupSettingsCxx> getSourceGroupSettingsCxx() = 0;
virtual std::shared_ptr<SourceGroupSettings> getSourceGroupSettings();
};
#endif // SOURCE_GROUP_CXX_H
+159
View File
@@ -0,0 +1,159 @@
#include "project/SourceGroupCxxCdb.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/JSONCompilationDatabase.h"
#include "data/indexer/IndexerCommandCxxCdb.h"
#include "settings/ApplicationSettings.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/utility.h"
#include "Application.h"
SourceGroupCxxCdb::SourceGroupCxxCdb(std::shared_ptr<SourceGroupSettingsCxxCdb> settings)
: m_settings(settings)
{
}
SourceGroupCxxCdb::~SourceGroupCxxCdb()
{
}
SourceGroupType SourceGroupCxxCdb::getType() const
{
return SOURCE_GROUP_CXX_CDB;
}
bool SourceGroupCxxCdb::prepareRefresh()
{
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.empty() && !cdbPath.exists())
{
MessageStatus("Can't refresh project").dispatch();
if (std::shared_ptr<Application> application = Application::getInstance())
{
if (application->hasGUI())
{
std::vector<std::string> options;
options.push_back("Ok");
application->handleDialog(
"Can't refresh. The compilation database of the project does not exist anymore: " + cdbPath.str(),
options
);
}
}
return false;
}
return true;
}
std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxCdb::getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh)
{
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
std::vector<FilePath> systemHeaderSearchPaths;
utility::append(systemHeaderSearchPaths, m_settings->getHeaderSearchPathsExpandedAndAbsolute());
utility::append(systemHeaderSearchPaths, appSettings->getHeaderSearchPathsExpanded());
// Add the source paths as HeaderSearchPaths as well, so clang will also look here when searching include files.
for (const FilePath& sourcePath: m_settings->getSourcePathsExpandedAndAbsolute())
{
if (sourcePath.isDirectory())
{
systemHeaderSearchPaths.push_back(sourcePath);
}
}
std::vector<FilePath> frameworkSearchPaths;
utility::append(frameworkSearchPaths, m_settings->getFrameworkSearchPathsExpandedAndAbsolute());
utility::append(frameworkSearchPaths, appSettings->getFrameworkSearchPathsExpanded());
std::vector<std::string> compilerFlags;
utility::append(compilerFlags, m_settings->getCompilerFlags());
std::set<FilePath> indexedPaths;
for (const FilePath& p : m_settings->getSourcePathsExpandedAndAbsolute())
{
if (p.exists())
{
indexedPaths.insert(p);
}
}
std::set<FilePath> excludedPaths;
for (const FilePath& p: m_settings->getExcludePathsExpandedAndAbsolute())
{
if (p.exists())
{
excludedPaths.insert(p);
}
}
const std::set<FilePath>& sourceFilePathsToIndex = (fullRefresh ? getAllSourceFilePaths() : getSourceFilePathsToIndex());
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands;
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (cdbPath.exists())
{
std::string error;
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = std::shared_ptr<clang::tooling::JSONCompilationDatabase>
(clang::tooling::JSONCompilationDatabase::loadFromFile(cdbPath.str(), error, clang::tooling::JSONCommandLineSyntax::AutoDetect));
if (!error.empty())
{
const std::string message = "Loading Clang compilation database failed with error: \"" + error + "\"";
LOG_ERROR(message);
MessageStatus(message, true).dispatch();
}
for (const clang::tooling::CompileCommand& command: cdb->getAllCompileCommands())
{
FilePath sourcePath = FilePath(command.Filename).canonical();
if (!sourcePath.isAbsolute())
{
sourcePath = FilePath(command.Directory + '/' + command.Filename).canonical();
}
if (filesToIndex->find(sourcePath) != filesToIndex->end() &&
sourceFilePathsToIndex.find(sourcePath) != sourceFilePathsToIndex.end())
{
std::vector<std::string> currentCompilerFlags = compilerFlags;
currentCompilerFlags.insert(currentCompilerFlags.end(), command.CommandLine.begin(), command.CommandLine.end());
indexerCommands.push_back(std::make_shared<IndexerCommandCxxCdb>(
sourcePath,
indexedPaths,
excludedPaths,
FilePath(command.Directory),
currentCompilerFlags,
systemHeaderSearchPaths,
frameworkSearchPaths,
m_settings->getShouldApplyAnonymousTypedefTransformation()
));
filesToIndex->erase(sourcePath);
}
}
}
return indexerCommands;
}
std::shared_ptr<SourceGroupSettingsCxx> SourceGroupCxxCdb::getSourceGroupSettingsCxx()
{
return m_settings;
}
std::vector<FilePath> SourceGroupCxxCdb::getAllSourcePaths() const
{
std::vector<FilePath> sourcePaths;
FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (cdbPath.exists())
{
sourcePaths = IndexerCommandCxxCdb::getSourceFilesFromCDB(cdbPath);
}
return sourcePaths;
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef SOURCE_GROUP_CXX_CDB_H
#define SOURCE_GROUP_CXX_CDB_H
#include <memory>
#include <set>
#include "project/SourceGroupCxx.h"
#include "settings/SourceGroupSettingsCxxCdb.h"
class SourceGroupCxxCdb: public SourceGroupCxx
{
public:
SourceGroupCxxCdb(std::shared_ptr<SourceGroupSettingsCxxCdb> settings);
virtual ~SourceGroupCxxCdb();
virtual SourceGroupType getType() const;
virtual bool prepareRefresh();
virtual std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh);
private:
virtual std::shared_ptr<SourceGroupSettingsCxx> getSourceGroupSettingsCxx();
virtual std::vector<FilePath> getAllSourcePaths() const;
std::shared_ptr<SourceGroupSettingsCxxCdb> m_settings;
};
#endif // SOURCE_GROUP_CXX_CDB_H
+106
View File
@@ -0,0 +1,106 @@
#include "project/SourceGroupCxxEmpty.h"
#include "data/indexer/IndexerCommandCxxManual.h"
#include "settings/ApplicationSettings.h"
#include "utility/utility.h"
#include "Application.h"
SourceGroupCxxEmpty::SourceGroupCxxEmpty(std::shared_ptr<SourceGroupSettingsCxxEmpty> settings)
: m_settings(settings)
{
}
SourceGroupCxxEmpty::~SourceGroupCxxEmpty()
{
}
SourceGroupType SourceGroupCxxEmpty::getType() const
{
return m_settings->getType(); // may be either C or Cpp
}
std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxEmpty::getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh)
{
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
std::vector<FilePath> systemHeaderSearchPaths;
utility::append(systemHeaderSearchPaths, m_settings->getHeaderSearchPathsExpandedAndAbsolute());
utility::append(systemHeaderSearchPaths, appSettings->getHeaderSearchPathsExpanded());
// Add the source paths as HeaderSearchPaths as well, so clang will also look here when searching include files.
for (const FilePath& sourcePath: m_settings->getSourcePathsExpandedAndAbsolute())
{
if (sourcePath.isDirectory())
{
systemHeaderSearchPaths.push_back(sourcePath);
}
}
std::vector<FilePath> frameworkSearchPaths;
utility::append(frameworkSearchPaths, m_settings->getFrameworkSearchPathsExpandedAndAbsolute());
utility::append(frameworkSearchPaths, appSettings->getFrameworkSearchPathsExpanded());
std::vector<std::string> compilerFlags;
{
const std::string targetFlag = m_settings->getTargetFlag();
if (!targetFlag.empty())
{
compilerFlags.push_back(targetFlag);
}
}
utility::append(compilerFlags, m_settings->getCompilerFlags());
std::set<FilePath> indexedPaths;
for (const FilePath& p : m_settings->getSourcePathsExpandedAndAbsolute())
{
if (p.exists())
{
indexedPaths.insert(p);
}
}
std::set<FilePath> excludedPaths;
for (const FilePath& p: m_settings->getExcludePathsExpandedAndAbsolute())
{
if (p.exists())
{
excludedPaths.insert(p);
}
}
const std::set<FilePath>& sourceFilePathsToIndex = (fullRefresh ? getAllSourceFilePaths() : getSourceFilePathsToIndex());
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands;
for (const FilePath& sourcePath: sourceFilePathsToIndex)
{
if (filesToIndex->find(sourcePath) != filesToIndex->end())
{
indexerCommands.push_back(std::make_shared<IndexerCommandCxxManual>(
sourcePath,
indexedPaths,
excludedPaths,
m_settings->getStandard(),
systemHeaderSearchPaths,
frameworkSearchPaths,
compilerFlags,
m_settings->getShouldApplyAnonymousTypedefTransformation()
));
filesToIndex->erase(sourcePath);
}
}
return indexerCommands;
}
std::shared_ptr<SourceGroupSettingsCxx> SourceGroupCxxEmpty::getSourceGroupSettingsCxx()
{
return m_settings;
}
std::vector<FilePath> SourceGroupCxxEmpty::getAllSourcePaths() const
{
return m_settings->getSourcePathsExpandedAndAbsolute();
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef SOURCE_GROUP_CXX_EMPTY_H
#define SOURCE_GROUP_CXX_EMPTY_H
#include <memory>
#include <set>
#include "project/SourceGroupCxx.h"
#include "settings/SourceGroupSettingsCxxEmpty.h"
class SourceGroupCxxEmpty: public SourceGroupCxx
{
public:
SourceGroupCxxEmpty(std::shared_ptr<SourceGroupSettingsCxxEmpty> settings);
virtual ~SourceGroupCxxEmpty();
virtual SourceGroupType getType() const;
virtual std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands(
std::set<FilePath>* filesToIndex, bool fullRefresh);
private:
virtual std::shared_ptr<SourceGroupSettingsCxx> getSourceGroupSettingsCxx();
virtual std::vector<FilePath> getAllSourcePaths() const;
std::shared_ptr<SourceGroupSettingsCxxEmpty> m_settings;
};
#endif // SOURCE_GROUP_CXX_EMPTY_H
@@ -1,30 +0,0 @@
#include "project/SourceGroupFactoryModuleC.h"
#include "project/SourceGroupCxx.h"
#include "settings/SourceGroupSettingsCxx.h"
SourceGroupFactoryModuleC::~SourceGroupFactoryModuleC()
{
}
bool SourceGroupFactoryModuleC::supports(SourceGroupType type) const
{
switch (type)
{
case SOURCE_GROUP_C_EMPTY:
return true;
default:
break;
}
return false;
}
std::shared_ptr<SourceGroup> SourceGroupFactoryModuleC::createSourceGroup(std::shared_ptr<SourceGroupSettings> settings)
{
std::shared_ptr<SourceGroup> sourceGroup;
if (std::shared_ptr<SourceGroupSettingsCxx> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxx>(settings))
{
sourceGroup = std::shared_ptr<SourceGroup>(new SourceGroupCxx(cxxSettings));
}
return sourceGroup;
}
@@ -1,14 +0,0 @@
#ifndef SOURCE_GROUP_FACTORY_MODULE_C_H
#define SOURCE_GROUP_FACTORY_MODULE_C_H
#include "project/SourceGroupFactoryModule.h"
class SourceGroupFactoryModuleC: public SourceGroupFactoryModule
{
public:
virtual ~SourceGroupFactoryModuleC();
virtual bool supports(SourceGroupType type) const;
virtual std::shared_ptr<SourceGroup> createSourceGroup(std::shared_ptr<SourceGroupSettings> settings);
};
#endif // SOURCE_GROUP_FACTORY_MODULE_C_H
@@ -1,31 +0,0 @@
#include "project/SourceGroupFactoryModuleCpp.h"
#include "project/SourceGroupCxx.h"
#include "settings/SourceGroupSettingsCxx.h"
SourceGroupFactoryModuleCpp::~SourceGroupFactoryModuleCpp()
{
}
bool SourceGroupFactoryModuleCpp::supports(SourceGroupType type) const
{
switch (type)
{
case SOURCE_GROUP_CPP_EMPTY:
case SOURCE_GROUP_CXX_CDB:
return true;
default:
break;
}
return false;
}
std::shared_ptr<SourceGroup> SourceGroupFactoryModuleCpp::createSourceGroup(std::shared_ptr<SourceGroupSettings> settings)
{
std::shared_ptr<SourceGroup> sourceGroup;
if (std::shared_ptr<SourceGroupSettingsCxx> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxx>(settings))
{
sourceGroup = std::shared_ptr<SourceGroup>(new SourceGroupCxx(cxxSettings));
}
return sourceGroup;
}
@@ -1,14 +0,0 @@
#ifndef SOURCE_GROUP_FACTORY_MODULE_CPP_H
#define SOURCE_GROUP_FACTORY_MODULE_CPP_H
#include "project/SourceGroupFactoryModule.h"
class SourceGroupFactoryModuleCpp: public SourceGroupFactoryModule
{
public:
virtual ~SourceGroupFactoryModuleCpp();
virtual bool supports(SourceGroupType type) const;
virtual std::shared_ptr<SourceGroup> createSourceGroup(std::shared_ptr<SourceGroupSettings> settings);
};
#endif // SOURCE_GROUP_FACTORY_MODULE_CPP_H
@@ -0,0 +1,38 @@
#include "project/SourceGroupFactoryModuleCxx.h"
#include "project/SourceGroupCxxCdb.h"
#include "project/SourceGroupCxxEmpty.h"
#include "settings/SourceGroupSettingsCxxCdb.h"
#include "settings/SourceGroupSettingsCxxEmpty.h"
SourceGroupFactoryModuleCxx::~SourceGroupFactoryModuleCxx()
{
}
bool SourceGroupFactoryModuleCxx::supports(SourceGroupType type) const
{
switch (type)
{
case SOURCE_GROUP_C_EMPTY:
case SOURCE_GROUP_CPP_EMPTY:
case SOURCE_GROUP_CXX_CDB:
return true;
default:
break;
}
return false;
}
std::shared_ptr<SourceGroup> SourceGroupFactoryModuleCxx::createSourceGroup(std::shared_ptr<SourceGroupSettings> settings)
{
std::shared_ptr<SourceGroup> sourceGroup;
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(settings))
{
sourceGroup = std::shared_ptr<SourceGroup>(new SourceGroupCxxCdb(cxxSettings));
}
else if (std::shared_ptr<SourceGroupSettingsCxxEmpty> cxxSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxEmpty>(settings))
{
sourceGroup = std::shared_ptr<SourceGroup>(new SourceGroupCxxEmpty(cxxSettings));
}
return sourceGroup;
}
@@ -0,0 +1,14 @@
#ifndef SOURCE_GROUP_FACTORY_MODULE_CXX_H
#define SOURCE_GROUP_FACTORY_MODULE_CXX_H
#include "project/SourceGroupFactoryModule.h"
class SourceGroupFactoryModuleCxx: public SourceGroupFactoryModule
{
public:
virtual ~SourceGroupFactoryModuleCxx();
virtual bool supports(SourceGroupType type) const;
virtual std::shared_ptr<SourceGroup> createSourceGroup(std::shared_ptr<SourceGroupSettings> settings);
};
#endif // SOURCE_GROUP_FACTORY_MODULE_CXX_H