logic: added project setup support for Sonargraph projects (Java and CMake-JSON modules supported)

* added classes for loading a Sonargraph project
* added Sonargraph options to project setup wizard
* added test for generating indexer commands from Sonargraph modules
* fixed sqlite storage crashing in constructor when parent directory of provided path does not exist
* removed unused FileRegister from Java indexing
* removed unused info from IndexerCommandJava
* refactored loading and saving of SourceGroupSettings
* extracted sourcepaths settings to own class that can be re-used
* merged CDB wizard contentents for source file and indexed paths
* unified wizard content for sonargraph project path
* removed include filters from default source groups
* extracted generation of RefreshInfo from Project to RefreshInfoGenerator
* added tests for RefreshInfoGenerator
* added language and standard selection to sonargraph project setup
* added auto-detection for indexed header paths of sonargraph cmake json modules
* Sonargraph::Project can enable/disable support for specific modules
* warn if sonargraph project contains no matching modules
* indexed headers can be detected from sonargraph project
This commit is contained in:
mlangkabel
2018-05-18 16:07:57 +02:00
parent e55ae5ba31
commit 7b735cfd17
164 changed files with 24770 additions and 1684 deletions
+205
View File
@@ -0,0 +1,205 @@
#include "project/RefreshInfoGenerator.h"
#include "data/storage/PersistentStorage.h"
#include "project/RefreshInfo.h"
#include "project/SourceGroup.h"
#include "settings/SourceGroupStatusType.h"
#include "utility/file/FileInfo.h"
#include "utility/file/FileSystem.h"
#include "utility/text/TextAccess.h"
#include "utility/utility.h"
RefreshInfo RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups, std::shared_ptr<const PersistentStorage> storage)
{
const std::set<FilePath> allSourceFilePathsFromSourcegroups = getAllSourceFilePaths(sourceGroups);
std::set<FilePath> unchangedFilePaths;
std::set<FilePath> changedFilePaths;
{
const std::vector<FileInfo> fileInfosFromStorage = storage->getFileInfoForAllIndexedFiles();
std::set<FilePath> alreadyIndexedPaths;
{
const std::set<FilePath> filePathsFromStorage = utility::toSet(utility::convert<FileInfo, FilePath>(
fileInfosFromStorage, [](const FileInfo& info) { return info.path; }
));
for (std::shared_ptr<SourceGroup> sourceGroup : sourceGroups)
{
utility::append(alreadyIndexedPaths, sourceGroup->filterToContainedFilePaths(filePathsFromStorage));
}
}
// checking source and header files
for (const FileInfo& info : fileInfosFromStorage)
{
if (alreadyIndexedPaths.find(info.path) != alreadyIndexedPaths.end() && info.path.exists())
{
if (didFileChange(info, storage))
{
changedFilePaths.insert(info.path);
}
else
{
unchangedFilePaths.insert(info.path);
}
}
else // file has been removed
{
changedFilePaths.insert(info.path);
}
}
}
std::set<FilePath> filesToClear = changedFilePaths;
// handle referencing paths
utility::append(filesToClear, storage->getReferencing(changedFilePaths));
// handle referenced paths
std::set<FilePath> staticSourceFiles = allSourceFilePathsFromSourcegroups;
for (const FilePath& path : changedFilePaths)
{
staticSourceFiles.erase(path);
}
const std::set<FilePath> staticReferencedFilePaths = storage->getReferenced(staticSourceFiles);
const std::set<FilePath> dynamicReferencedFilePaths = storage->getReferenced(changedFilePaths);
for (const FilePath& path : dynamicReferencedFilePaths)
{
if (staticReferencedFilePaths.find(path) == staticReferencedFilePaths.end() &&
staticSourceFiles.find(path) == staticSourceFiles.end())
{
// file may not be referenced anymore and will be reindexed if still needed
filesToClear.insert(path);
}
}
for (const FilePath& path : unchangedFilePaths)
{
staticSourceFiles.erase(path);
}
const std::set<FilePath> filesToAdd = staticSourceFiles;
std::set<FilePath> staticSourceFilePaths;
for (const FilePath& path : allSourceFilePathsFromSourcegroups)
{
if (filesToClear.find(path) == filesToClear.end() && filesToAdd.find(path) == filesToAdd.end())
{
staticSourceFilePaths.insert(path);
}
}
RefreshInfo info;
info.mode = REFRESH_UPDATED_FILES;
info.filesToClear = filesToClear;
for (const std::shared_ptr<SourceGroup>& sourceGroup : sourceGroups)
{
if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED)
{
utility::append(info.filesToIndex, sourceGroup->filterToContainedSourceFilePath(staticSourceFilePaths));
}
}
return info;
}
RefreshInfo RefreshInfoGenerator::getRefreshInfoForIncompleteFiles(const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups, std::shared_ptr<const PersistentStorage> storage)
{
RefreshInfo info = getRefreshInfoForUpdatedFiles(sourceGroups, storage);
info.mode = REFRESH_UPDATED_AND_INCOMPLETE_FILES;
std::set<FilePath> incompleteFiles;
for (const FilePath& path : storage->getIncompleteFiles())
{
if (info.filesToClear.find(path) == info.filesToClear.end())
{
incompleteFiles.insert(path);
}
}
if (!incompleteFiles.empty())
{
utility::append(incompleteFiles, storage->getReferencing(incompleteFiles));
std::set<FilePath> staticSourceFilePaths = getAllSourceFilePaths(sourceGroups);
for (const FilePath& path : incompleteFiles)
{
staticSourceFilePaths.erase(path);
if (storage->getFilePathIndexed(path))
{
info.filesToClear.insert(path);
}
else
{
info.nonIndexedFilesToClear.insert(path);
}
}
for (const std::shared_ptr<const SourceGroup>& sourceGroup : sourceGroups)
{
if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED)
{
utility::append(info.filesToIndex, sourceGroup->filterToContainedSourceFilePath(staticSourceFilePaths));
}
}
}
return info;
}
RefreshInfo RefreshInfoGenerator::getRefreshInfoForAllFiles(const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups)
{
RefreshInfo info;
info.mode = REFRESH_ALL_FILES;
info.filesToIndex = getAllSourceFilePaths(sourceGroups);
return info;
}
std::set<FilePath> RefreshInfoGenerator::getAllSourceFilePaths(const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups)
{
std::set<FilePath> allSourceFilePaths;
for (const std::shared_ptr<const SourceGroup>& sourceGroup : sourceGroups)
{
if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED)
{
utility::append(allSourceFilePaths, sourceGroup->getAllSourceFilePaths());
}
}
return allSourceFilePaths;
}
bool RefreshInfoGenerator::didFileChange(const FileInfo& info, std::shared_ptr<const PersistentStorage> storage)
{
FileInfo diskFileInfo = FileSystem::getFileInfoForPath(info.path);
if (diskFileInfo.lastWriteTime > info.lastWriteTime)
{
std::shared_ptr<TextAccess> storedFileContent = storage->getFileContent(info.path);
std::shared_ptr<TextAccess> diskFileContent = TextAccess::createFromFile(diskFileInfo.path);
const std::vector<std::string>& diskFileLines = diskFileContent->getAllLines();
const std::vector<std::string>& storedFileLines = storedFileContent->getAllLines();
if (diskFileLines.size() == storedFileLines.size())
{
for (size_t i = 0; i < diskFileLines.size(); i++)
{
if (diskFileLines[i] != storedFileLines[i])
{
return true;
}
}
return false;
}
return true;
}
return false;
}