forked from qt-creator/qt-creator
Clang: Reduce database accesses
If we prefetch data from the database to the caches we reduce the database transaction calls which are quite expensive. Change-Id: I617a0d886807402e0a94291a913a77f989970b55 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "clangsupport_global.h"
|
#include "clangsupport_global.h"
|
||||||
#include "filepath.h"
|
#include "filepath.h"
|
||||||
|
#include "filepathid.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -39,13 +40,15 @@ public:
|
|||||||
FileContainer() = default;
|
FileContainer() = default;
|
||||||
|
|
||||||
FileContainer(FilePath &&filePath,
|
FileContainer(FilePath &&filePath,
|
||||||
|
FilePathId filePathId,
|
||||||
Utils::SmallString &&unsavedFileContent,
|
Utils::SmallString &&unsavedFileContent,
|
||||||
Utils::SmallStringVector &&commandLineArguments = {},
|
Utils::SmallStringVector &&commandLineArguments = {},
|
||||||
quint32 documentRevision = 0)
|
quint32 documentRevision = 0)
|
||||||
: filePath(std::move(filePath)),
|
: filePath(std::move(filePath))
|
||||||
unsavedFileContent(std::move(unsavedFileContent)),
|
, filePathId(filePathId)
|
||||||
commandLineArguments(std::move(commandLineArguments)),
|
, unsavedFileContent(std::move(unsavedFileContent))
|
||||||
documentRevision(documentRevision)
|
, commandLineArguments(std::move(commandLineArguments))
|
||||||
|
, documentRevision(documentRevision)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,16 +84,11 @@ public:
|
|||||||
< std::tie(second.filePath, second.documentRevision, second.unsavedFileContent, second.commandLineArguments);
|
< std::tie(second.filePath, second.documentRevision, second.unsavedFileContent, second.commandLineArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileContainer clone() const
|
FileContainer clone() const { return *this; }
|
||||||
{
|
|
||||||
return FileContainer(filePath.clone(),
|
|
||||||
unsavedFileContent.clone(),
|
|
||||||
commandLineArguments.clone(),
|
|
||||||
documentRevision);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FilePath filePath;
|
FilePath filePath;
|
||||||
|
FilePathId filePathId;
|
||||||
Utils::SmallString unsavedFileContent;
|
Utils::SmallString unsavedFileContent;
|
||||||
Utils::SmallStringVector commandLineArguments;
|
Utils::SmallStringVector commandLineArguments;
|
||||||
quint32 documentRevision = 0;
|
quint32 documentRevision = 0;
|
||||||
|
@@ -67,13 +67,20 @@ public:
|
|||||||
FilePathCache(FilePathStorage &filePathStorage)
|
FilePathCache(FilePathStorage &filePathStorage)
|
||||||
: m_filePathStorage(filePathStorage)
|
: m_filePathStorage(filePathStorage)
|
||||||
{
|
{
|
||||||
m_directoryPathCache.populate(filePathStorage.fetchAllDirectories());
|
populateIfEmpty();
|
||||||
m_fileNameCache.populate(filePathStorage.fetchAllSources());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePathCache(FilePathCache &&) = default;
|
FilePathCache(FilePathCache &&) = default;
|
||||||
FilePathCache &operator=(FilePathCache &&) = default;
|
FilePathCache &operator=(FilePathCache &&) = default;
|
||||||
|
|
||||||
|
void populateIfEmpty()
|
||||||
|
{
|
||||||
|
if (m_fileNameCache.isEmpty()) {
|
||||||
|
m_directoryPathCache.populate(m_filePathStorage.fetchAllDirectories());
|
||||||
|
m_fileNameCache.populate(m_filePathStorage.fetchAllSources());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Cache>
|
template<typename Cache>
|
||||||
Cache clone()
|
Cache clone()
|
||||||
{
|
{
|
||||||
@@ -126,8 +133,7 @@ public:
|
|||||||
return FileNameEntry{entry.sourceName, entry.directoryId};
|
return FileNameEntry{entry.sourceName, entry.directoryId};
|
||||||
};
|
};
|
||||||
|
|
||||||
FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
|
auto entry = m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId);
|
||||||
fetchSoureNameAndDirectoryId);
|
|
||||||
|
|
||||||
auto fetchDirectoryPath = [&] (int id) { return m_filePathStorage.fetchDirectoryPath(id); };
|
auto fetchDirectoryPath = [&] (int id) { return m_filePathStorage.fetchDirectoryPath(id); };
|
||||||
|
|
||||||
@@ -157,9 +163,6 @@ public:
|
|||||||
return FileNameEntry{entry.sourceName, entry.directoryId};
|
return FileNameEntry{entry.sourceName, entry.directoryId};
|
||||||
};
|
};
|
||||||
|
|
||||||
FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
|
|
||||||
fetchSoureNameAndDirectoryId);
|
|
||||||
|
|
||||||
return m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId).directoryId;
|
return m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId).directoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,6 +57,11 @@ void FilePathCaching::addFilePaths(const FilePaths &filePaths)
|
|||||||
m_cache.addFilePaths(filePaths);
|
m_cache.addFilePaths(filePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilePathCaching::populateIfEmpty()
|
||||||
|
{
|
||||||
|
m_cache.populateIfEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
FilePathId CopyableFilePathCaching::filePathId(FilePathView filePath) const
|
FilePathId CopyableFilePathCaching::filePathId(FilePathView filePath) const
|
||||||
{
|
{
|
||||||
return m_cache.filePathId(filePath);
|
return m_cache.filePathId(filePath);
|
||||||
@@ -87,4 +92,9 @@ void CopyableFilePathCaching::addFilePaths(const FilePaths &filePaths)
|
|||||||
m_cache.addFilePaths(filePaths);
|
m_cache.addFilePaths(filePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyableFilePathCaching::populateIfEmpty()
|
||||||
|
{
|
||||||
|
m_cache.populateIfEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -56,6 +56,7 @@ public:
|
|||||||
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
|
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
|
||||||
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
|
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
|
||||||
void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
|
void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
|
||||||
|
void populateIfEmpty() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Factory m_factory;
|
Factory m_factory;
|
||||||
@@ -80,6 +81,7 @@ public:
|
|||||||
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
|
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
|
||||||
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
|
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
|
||||||
void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
|
void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
|
||||||
|
void populateIfEmpty() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cache m_cache;
|
Cache m_cache;
|
||||||
|
@@ -45,6 +45,7 @@ public:
|
|||||||
virtual DirectoryPathId directoryPathId(FilePathId filePathId) const = 0;
|
virtual DirectoryPathId directoryPathId(FilePathId filePathId) const = 0;
|
||||||
virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0;
|
virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0;
|
||||||
virtual void addFilePaths(const ClangBackEnd::FilePaths &filePaths) = 0;
|
virtual void addFilePaths(const ClangBackEnd::FilePaths &filePaths) = 0;
|
||||||
|
virtual void populateIfEmpty() = 0;
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
FilePathIds filePathIds(Container &&filePaths) const
|
FilePathIds filePathIds(Container &&filePaths) const
|
||||||
|
@@ -53,7 +53,7 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
|
|||||||
V2::FileContainers unionFileContainers;
|
V2::FileContainers unionFileContainers;
|
||||||
unionFileContainers.reserve(m_fileContainers.size() + fileContainers.size());
|
unionFileContainers.reserve(m_fileContainers.size() + fileContainers.size());
|
||||||
|
|
||||||
auto compare = [] (const V2::FileContainer &first, const V2::FileContainer &second) {
|
auto compare = [](const V2::FileContainer &first, const V2::FileContainer &second) {
|
||||||
return first.filePath < second.filePath;
|
return first.filePath < second.filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,10 +69,7 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
|
|||||||
|
|
||||||
class Compare {
|
class Compare {
|
||||||
public:
|
public:
|
||||||
bool operator()(const FilePath &first, const FilePath &second)
|
bool operator()(const FilePath &first, const FilePath &second) { return first < second; }
|
||||||
{
|
|
||||||
return first < second;
|
|
||||||
}
|
|
||||||
bool operator()(const V2::FileContainer &first, const V2::FileContainer &second)
|
bool operator()(const V2::FileContainer &first, const V2::FileContainer &second)
|
||||||
{
|
{
|
||||||
return first.filePath < second.filePath;
|
return first.filePath < second.filePath;
|
||||||
@@ -116,4 +113,16 @@ const V2::FileContainers &GeneratedFiles::fileContainers() const
|
|||||||
return m_fileContainers;
|
return m_fileContainers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePathIds GeneratedFiles::filePathIds() const
|
||||||
|
{
|
||||||
|
auto ids = Utils::transform<FilePathIds>(m_fileContainers,
|
||||||
|
[](const V2::FileContainer &fileContainer) {
|
||||||
|
return fileContainer.filePathId;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::sort(ids.begin(), ids.end());
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -38,6 +38,7 @@ public:
|
|||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
const V2::FileContainers &fileContainers() const;
|
const V2::FileContainers &fileContainers() const;
|
||||||
|
FilePathIds filePathIds() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
V2::FileContainers m_fileContainers;
|
V2::FileContainers m_fileContainers;
|
||||||
|
@@ -38,6 +38,7 @@ public:
|
|||||||
virtual bool isValid() const = 0;
|
virtual bool isValid() const = 0;
|
||||||
|
|
||||||
virtual const V2::FileContainers &fileContainers() const = 0;
|
virtual const V2::FileContainers &fileContainers() const = 0;
|
||||||
|
virtual FilePathIds filePathIds() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~GeneratedFilesInterface() = default;
|
~GeneratedFilesInterface() = default;
|
||||||
|
@@ -109,26 +109,33 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectPartId fetchProjectPartIdUnguarded(Utils::SmallStringView projectPartName) const override
|
||||||
|
{
|
||||||
|
auto optionalProjectPartId = fetchProjectPartIdStatement.template value<ProjectPartId>(
|
||||||
|
projectPartName);
|
||||||
|
|
||||||
|
if (optionalProjectPartId) {
|
||||||
|
return *optionalProjectPartId;
|
||||||
|
} else {
|
||||||
|
insertProjectPartNameStatement.write(projectPartName);
|
||||||
|
|
||||||
|
return static_cast<int>(database.lastInsertedRowId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const override
|
ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const override
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Sqlite::DeferredTransaction transaction{database};
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
ProjectPartId projectPartId;
|
ProjectPartId projectPartId = fetchProjectPartIdUnguarded(projectPartName);
|
||||||
auto optionalProjectPartId = fetchProjectPartIdStatement.template value<ProjectPartId>(
|
|
||||||
projectPartName);
|
|
||||||
|
|
||||||
if (optionalProjectPartId) {
|
|
||||||
projectPartId = *optionalProjectPartId;
|
|
||||||
} else {
|
|
||||||
insertProjectPartNameStatement.write(projectPartName);
|
|
||||||
|
|
||||||
projectPartId = static_cast<int>(database.lastInsertedRowId());
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
return projectPartId;
|
return projectPartId;
|
||||||
|
|
||||||
} catch (const Sqlite::StatementIsBusy &) {
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
return fetchProjectPartId(projectPartName);
|
return fetchProjectPartId(projectPartName);
|
||||||
}
|
}
|
||||||
@@ -330,6 +337,23 @@ public:
|
|||||||
Utils::SmallString::number(projectPartId.projectPathId));
|
Utils::SmallString::number(projectPartId.projectPathId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Internal::ProjectPartNameIds fetchAllProjectPartNamesAndIds() const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
|
ReadStatement &statement = fetchAllProjectPartNamesAndIdsStatement;
|
||||||
|
|
||||||
|
auto values = statement.template values<Internal::ProjectPartNameId, 2>(256);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return values;
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
return fetchAllProjectPartNamesAndIds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
||||||
Database &database;
|
Database &database;
|
||||||
@@ -383,5 +407,7 @@ public:
|
|||||||
"SELECT projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?", database};
|
"SELECT projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?", database};
|
||||||
WriteStatement resetDependentIndexingTimeStampsStatement{
|
WriteStatement resetDependentIndexingTimeStampsStatement{
|
||||||
"UPDATE fileStatuses SET indexingTimeStamp = NULL WHERE sourceId = ?", database};
|
"UPDATE fileStatuses SET indexingTimeStamp = NULL WHERE sourceId = ?", database};
|
||||||
|
mutable ReadStatement fetchAllProjectPartNamesAndIdsStatement{
|
||||||
|
"SELECT projectPartName, projectPartId FROM projectParts", database};
|
||||||
};
|
};
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <projectpartcontainer.h>
|
#include "projectpartcontainer.h"
|
||||||
|
#include "projectpartstoragestructs.h"
|
||||||
|
|
||||||
#include <sqlitetransaction.h>
|
#include <sqlitetransaction.h>
|
||||||
#include <utils/optional.h>
|
#include <utils/optional.h>
|
||||||
@@ -46,8 +47,10 @@ public:
|
|||||||
|
|
||||||
virtual ProjectPartContainers fetchProjectParts() const = 0;
|
virtual ProjectPartContainers fetchProjectParts() const = 0;
|
||||||
virtual ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const = 0;
|
virtual ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const = 0;
|
||||||
|
virtual ProjectPartId fetchProjectPartIdUnguarded(Utils::SmallStringView projectPartName) const = 0;
|
||||||
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const = 0;
|
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const = 0;
|
||||||
virtual Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const = 0;
|
virtual Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const = 0;
|
||||||
|
virtual Internal::ProjectPartNameIds fetchAllProjectPartNamesAndIds() const = 0;
|
||||||
virtual void updateProjectPart(ProjectPartId projectPartId,
|
virtual void updateProjectPart(ProjectPartId projectPartId,
|
||||||
const Utils::SmallStringVector &commandLineArguments,
|
const Utils::SmallStringVector &commandLineArguments,
|
||||||
const CompilerMacros &compilerMacros,
|
const CompilerMacros &compilerMacros,
|
||||||
|
@@ -46,8 +46,11 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/namevalueitem.h>
|
#include <utils/namevalueitem.h>
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace ClangPchManager {
|
namespace ClangPchManager {
|
||||||
|
|
||||||
@@ -68,6 +71,7 @@ void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart
|
|||||||
Utils::SmallStringVector &&toolChainArguments)
|
Utils::SmallStringVector &&toolChainArguments)
|
||||||
{
|
{
|
||||||
addProjectFilesToFilePathCache(projectParts);
|
addProjectFilesToFilePathCache(projectParts);
|
||||||
|
fetchProjectPartIds(projectParts);
|
||||||
|
|
||||||
m_server.updateProjectParts(
|
m_server.updateProjectParts(
|
||||||
ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts),
|
ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts),
|
||||||
@@ -237,7 +241,7 @@ void updateWithSettings(ClangBackEnd::CompilerMacros ¯os,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(
|
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(
|
||||||
const ProjectExplorer::Macros &projectMacros, Utils::NameValueItems &&settingsMacros) const
|
const ProjectExplorer::Macros &projectMacros, Utils::NameValueItems &&settingsMacros)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
auto macros = Utils::transform<ClangBackEnd::CompilerMacros>(
|
auto macros = Utils::transform<ClangBackEnd::CompilerMacros>(
|
||||||
@@ -347,10 +351,10 @@ ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
|
|||||||
|
|
||||||
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
|
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
|
||||||
|
|
||||||
const QByteArray projectPartName = projectPart->id().toUtf8();
|
ClangBackEnd::ProjectPartId projectPartId = m_projectPartIdCache.stringId(
|
||||||
|
Utils::PathString{projectPart->id()}, [&](Utils::SmallStringView projectPartName) {
|
||||||
ClangBackEnd::ProjectPartId projectPartId = m_projectPartsStorage.fetchProjectPartId(
|
return m_projectPartsStorage.fetchProjectPartId(projectPartName);
|
||||||
projectPartName);
|
});
|
||||||
|
|
||||||
ClangIndexingProjectSettings *settings = m_settingsManager.settings(projectPart->project);
|
ClangIndexingProjectSettings *settings = m_settingsManager.settings(projectPart->project);
|
||||||
|
|
||||||
@@ -415,36 +419,31 @@ ClangBackEnd::FilePaths ProjectUpdater::createExcludedPaths(
|
|||||||
|
|
||||||
QString ProjectUpdater::fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const
|
QString ProjectUpdater::fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const
|
||||||
{
|
{
|
||||||
return m_projectPartsStorage.fetchProjectPartName(projectPartId).toQString();
|
return QString(m_projectPartIdCache.string(projectPartId.projectPathId,
|
||||||
|
[&](ClangBackEnd::ProjectPartId projectPartId) {
|
||||||
|
return m_projectPartsStorage.fetchProjectPartName(
|
||||||
|
projectPartId);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangBackEnd::ProjectPartIds ProjectUpdater::toProjectPartIds(
|
ClangBackEnd::ProjectPartIds ProjectUpdater::toProjectPartIds(
|
||||||
const QStringList &projectPartNames) const
|
const QStringList &projectPartNamesAsQString) const
|
||||||
{
|
{
|
||||||
ClangBackEnd::ProjectPartIds projectPartIds;
|
ClangBackEnd::ProjectPartIds projectPartIds;
|
||||||
projectPartIds.reserve(projectPartIds.size());
|
projectPartIds.reserve(projectPartIds.size());
|
||||||
|
|
||||||
std::transform(projectPartNames.begin(),
|
auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
|
||||||
projectPartNames.end(),
|
projectPartNamesAsQString, [&](const QString &projectPartName) { return projectPartName; });
|
||||||
std::back_inserter(projectPartIds),
|
|
||||||
[&](const QString &projectPartName) {
|
|
||||||
return m_projectPartsStorage.fetchProjectPartId(
|
|
||||||
Utils::SmallString{projectPartName});
|
|
||||||
});
|
|
||||||
|
|
||||||
return projectPartIds;
|
return m_projectPartIdCache.stringIds(projectPartNames, [&](Utils::SmallStringView projectPartName) {
|
||||||
|
return m_projectPartsStorage.fetchProjectPartId(projectPartName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts)
|
void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts)
|
||||||
{
|
{
|
||||||
std::size_t fileCount = std::accumulate(projectParts.begin(),
|
|
||||||
projectParts.end(),
|
|
||||||
std::size_t(0),
|
|
||||||
[](std::size_t value, CppTools::ProjectPart *projectPart) {
|
|
||||||
return value + std::size_t(projectPart->files.size());
|
|
||||||
});
|
|
||||||
ClangBackEnd::FilePaths filePaths;
|
ClangBackEnd::FilePaths filePaths;
|
||||||
filePaths.reserve(fileCount);
|
filePaths.reserve(10000);
|
||||||
|
|
||||||
for (CppTools::ProjectPart *projectPart : projectParts) {
|
for (CppTools::ProjectPart *projectPart : projectParts) {
|
||||||
for (const CppTools::ProjectFile &file : projectPart->files)
|
for (const CppTools::ProjectFile &file : projectPart->files)
|
||||||
@@ -455,4 +454,28 @@ void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::
|
|||||||
m_filePathCache.addFilePaths(filePaths);
|
m_filePathCache.addFilePaths(filePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectUpdater::fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts)
|
||||||
|
{
|
||||||
|
std::unique_ptr<Sqlite::DeferredTransaction> transaction;
|
||||||
|
|
||||||
|
auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
|
||||||
|
projectParts, [](CppTools::ProjectPart *projectPart) { return projectPart->id(); });
|
||||||
|
|
||||||
|
auto projectPartNameViews = Utils::transform<std::vector<Utils::SmallStringView>>(
|
||||||
|
projectPartNames,
|
||||||
|
[](const Utils::PathString &projectPartName) { return projectPartName.toStringView(); });
|
||||||
|
|
||||||
|
m_projectPartIdCache
|
||||||
|
.addStrings(std::move(projectPartNameViews), [&](Utils::SmallStringView projectPartName) {
|
||||||
|
if (!transaction)
|
||||||
|
transaction = std::make_unique<Sqlite::DeferredTransaction>(
|
||||||
|
m_projectPartsStorage.transactionBackend());
|
||||||
|
return m_projectPartsStorage.fetchProjectPartIdUnguarded(projectPartName);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (transaction)
|
||||||
|
transaction->commit();
|
||||||
|
|
||||||
|
} // namespace ClangPchManager
|
||||||
|
|
||||||
} // namespace ClangPchManager
|
} // namespace ClangPchManager
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
#include <includesearchpath.h>
|
#include <includesearchpath.h>
|
||||||
#include <projectpartcontainer.h>
|
#include <projectpartcontainer.h>
|
||||||
#include <projectpartsstorageinterface.h>
|
#include <projectpartsstorageinterface.h>
|
||||||
|
#include <projectpartstoragestructs.h>
|
||||||
|
#include <stringcache.h>
|
||||||
|
|
||||||
#include <projectexplorer/headerpath.h>
|
#include <projectexplorer/headerpath.h>
|
||||||
|
|
||||||
@@ -66,6 +68,14 @@ class ClangIndexingProjectSettings;
|
|||||||
|
|
||||||
class CLANGPCHMANAGER_EXPORT ProjectUpdater
|
class CLANGPCHMANAGER_EXPORT ProjectUpdater
|
||||||
{
|
{
|
||||||
|
using StringCache = ClangBackEnd::StringCache<Utils::PathString,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
ClangBackEnd::ProjectPartId,
|
||||||
|
ClangBackEnd::NonLockingMutex,
|
||||||
|
decltype(&Utils::reverseCompare),
|
||||||
|
Utils::reverseCompare,
|
||||||
|
ClangBackEnd::Internal::ProjectPartNameId>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct SystemAndProjectIncludeSearchPaths
|
struct SystemAndProjectIncludeSearchPaths
|
||||||
{
|
{
|
||||||
@@ -77,11 +87,13 @@ public:
|
|||||||
ClangBackEnd::FilePathCachingInterface &filePathCache,
|
ClangBackEnd::FilePathCachingInterface &filePathCache,
|
||||||
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
|
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
|
||||||
ClangIndexingSettingsManager &settingsManager)
|
ClangIndexingSettingsManager &settingsManager)
|
||||||
: m_server(server)
|
: m_filePathCache(filePathCache)
|
||||||
, m_filePathCache(filePathCache)
|
, m_server(server)
|
||||||
, m_projectPartsStorage(projectPartsStorage)
|
, m_projectPartsStorage(projectPartsStorage)
|
||||||
, m_settingsManager(settingsManager)
|
, m_settingsManager(settingsManager)
|
||||||
{}
|
{
|
||||||
|
m_projectPartIdCache.populate(m_projectPartsStorage.fetchAllProjectPartNamesAndIds());
|
||||||
|
}
|
||||||
|
|
||||||
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
||||||
Utils::SmallStringVector &&toolChainArguments);
|
Utils::SmallStringVector &&toolChainArguments);
|
||||||
@@ -104,8 +116,8 @@ public:
|
|||||||
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
|
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
|
||||||
const CppTools::ProjectFile &projectFile) const;
|
const CppTools::ProjectFile &projectFile) const;
|
||||||
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
|
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
|
||||||
ClangBackEnd::CompilerMacros createCompilerMacros(const ProjectExplorer::Macros &projectMacros,
|
static ClangBackEnd::CompilerMacros createCompilerMacros(const ProjectExplorer::Macros &projectMacros,
|
||||||
Utils::NameValueItems &&settingsMacros) const;
|
Utils::NameValueItems &&settingsMacros);
|
||||||
static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
|
static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
|
||||||
const CppTools::ProjectPart &projectPart);
|
const CppTools::ProjectPart &projectPart);
|
||||||
static ClangBackEnd::FilePaths createExcludedPaths(
|
static ClangBackEnd::FilePaths createExcludedPaths(
|
||||||
@@ -115,16 +127,19 @@ public:
|
|||||||
|
|
||||||
ClangBackEnd::ProjectPartIds toProjectPartIds(const QStringList &projectPartNames) const;
|
ClangBackEnd::ProjectPartIds toProjectPartIds(const QStringList &projectPartNames) const;
|
||||||
|
|
||||||
private:
|
|
||||||
void addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts);
|
void addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts);
|
||||||
|
void fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ClangBackEnd::FilePathCachingInterface &m_filePathCache;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClangBackEnd::GeneratedFiles m_generatedFiles;
|
ClangBackEnd::GeneratedFiles m_generatedFiles;
|
||||||
ClangBackEnd::FilePaths m_excludedPaths;
|
ClangBackEnd::FilePaths m_excludedPaths;
|
||||||
ClangBackEnd::ProjectManagementServerInterface &m_server;
|
ClangBackEnd::ProjectManagementServerInterface &m_server;
|
||||||
ClangBackEnd::FilePathCachingInterface &m_filePathCache;
|
|
||||||
ClangBackEnd::ProjectPartsStorageInterface &m_projectPartsStorage;
|
ClangBackEnd::ProjectPartsStorageInterface &m_projectPartsStorage;
|
||||||
ClangIndexingSettingsManager &m_settingsManager;
|
ClangIndexingSettingsManager &m_settingsManager;
|
||||||
|
mutable StringCache m_projectPartIdCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangPchManager
|
} // namespace ClangPchManager
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
|
#include <filepathcachinginterface.h>
|
||||||
|
|
||||||
namespace ClangPchManager {
|
namespace ClangPchManager {
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -38,16 +40,21 @@ CppTools::CppModelManager *cppModelManager()
|
|||||||
return CppTools::CppModelManager::instance();
|
return CppTools::CppModelManager::instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
|
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
|
||||||
|
ClangBackEnd::FilePathCachingInterface &filePathCache)
|
||||||
{
|
{
|
||||||
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
||||||
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
|
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
|
||||||
generatedFiles.reserve(std::size_t(abstractEditors.size()));
|
generatedFiles.reserve(std::size_t(abstractEditors.size()));
|
||||||
|
|
||||||
auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
|
auto toFileContainer = [&](const CppTools::AbstractEditorSupport *abstractEditor) {
|
||||||
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
|
ClangBackEnd::FilePath filePath(abstractEditor->fileName());
|
||||||
Utils::SmallString::fromQByteArray(abstractEditor->contents()),
|
ClangBackEnd::FilePathId filePathId = filePathCache.filePathId(filePath);
|
||||||
{});
|
return ClangBackEnd::V2::FileContainer(std::move(filePath),
|
||||||
|
filePathId,
|
||||||
|
Utils::SmallString::fromQByteArray(
|
||||||
|
abstractEditor->contents()),
|
||||||
|
{});
|
||||||
};
|
};
|
||||||
|
|
||||||
std::transform(abstractEditors.begin(),
|
std::transform(abstractEditors.begin(),
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <filecontainerv2.h>
|
#include <filecontainerv2.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -46,7 +48,8 @@ namespace ClangPchManager {
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
|
CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
|
||||||
CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
|
CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
|
||||||
|
ClangBackEnd::FilePathCachingInterface &filePathCache);
|
||||||
CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
|
CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,9 +86,13 @@ public:
|
|||||||
ProjectUpdaterType::removeProjectParts(projectPartIds);
|
ProjectUpdaterType::removeProjectParts(projectPartIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void abstractEditorUpdated(const QString &filePath, const QByteArray &contents)
|
void abstractEditorUpdated(const QString &qFilePath, const QByteArray &contents)
|
||||||
{
|
{
|
||||||
ProjectUpdaterType::updateGeneratedFiles({{ClangBackEnd::FilePath{filePath}, contents}});
|
ClangBackEnd::FilePath filePath{qFilePath};
|
||||||
|
ClangBackEnd::FilePathId filePathId = ProjectUpdaterType::m_filePathCache.filePathId(
|
||||||
|
filePath);
|
||||||
|
|
||||||
|
ProjectUpdaterType::updateGeneratedFiles({{std::move(filePath), filePathId, contents}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void abstractEditorRemoved(const QString &filePath)
|
void abstractEditorRemoved(const QString &filePath)
|
||||||
@@ -98,6 +105,14 @@ protected:
|
|||||||
const Utils::FilePath &,
|
const Utils::FilePath &,
|
||||||
const Utils::FilePathList &targets) override
|
const Utils::FilePathList &targets) override
|
||||||
{
|
{
|
||||||
|
auto filePaths = Utils::transform<ClangBackEnd::FilePaths>(targets,
|
||||||
|
[](const Utils::FilePath &filePath) {
|
||||||
|
return ClangBackEnd::FilePath{
|
||||||
|
filePath.toString()};
|
||||||
|
});
|
||||||
|
|
||||||
|
ProjectUpdater::m_filePathCache.addFilePaths(filePaths);
|
||||||
|
|
||||||
for (const Utils::FilePath &target : targets)
|
for (const Utils::FilePath &target : targets)
|
||||||
abstractEditorUpdated(target.toString(), {});
|
abstractEditorUpdated(target.toString(), {});
|
||||||
}
|
}
|
||||||
@@ -105,7 +120,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void connectToCppModelManager()
|
void connectToCppModelManager()
|
||||||
{
|
{
|
||||||
ProjectUpdaterType::updateGeneratedFiles(Internal::createGeneratedFiles());
|
ProjectUpdaterType::updateGeneratedFiles(
|
||||||
|
Internal::createGeneratedFiles(ProjectUpdaterType::m_filePathCache));
|
||||||
|
|
||||||
QObject::connect(Internal::cppModelManager(),
|
QObject::connect(Internal::cppModelManager(),
|
||||||
&CppTools::CppModelManager::projectPartsUpdated,
|
&CppTools::CppModelManager::projectPartsUpdated,
|
||||||
|
@@ -82,10 +82,9 @@ void ClangQueryProjectsFindFilter::requestSourceRangesAndDiagnostics(const QStri
|
|||||||
{
|
{
|
||||||
const QString filePath = temporaryFile.fileName();
|
const QString filePath = temporaryFile.fileName();
|
||||||
|
|
||||||
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(queryText,
|
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(
|
||||||
{ClangBackEnd::FilePath(filePath),
|
queryText,
|
||||||
exampleContent,
|
{ClangBackEnd::FilePath(filePath), 1, exampleContent, {"cc", "-std=c++1z", toNative(filePath)}});
|
||||||
{"cc", "-std=c++1z", toNative(filePath)}});
|
|
||||||
|
|
||||||
m_server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
|
m_server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
|
||||||
}
|
}
|
||||||
@@ -204,10 +203,9 @@ void appendSource(std::vector<ClangBackEnd::V2::FileContainer> &sources,
|
|||||||
|
|
||||||
if (!unsavedContentContains(sourceFilePath, unsavedContent) && !isCHeader(projectFile.kind)) {
|
if (!unsavedContentContains(sourceFilePath, unsavedContent) && !isCHeader(projectFile.kind)) {
|
||||||
sources.emplace_back(ClangBackEnd::FilePath(projectFile.path),
|
sources.emplace_back(ClangBackEnd::FilePath(projectFile.path),
|
||||||
|
-1,
|
||||||
"",
|
"",
|
||||||
createCommandLine(projectPart.data(),
|
createCommandLine(projectPart.data(), projectFile.path, projectFile.kind));
|
||||||
projectFile.path,
|
|
||||||
projectFile.kind));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -108,10 +108,12 @@ std::vector<ClangBackEnd::V2::FileContainer> createUnsavedContents()
|
|||||||
std::vector<ClangBackEnd::V2::FileContainer> unsavedContents;
|
std::vector<ClangBackEnd::V2::FileContainer> unsavedContents;
|
||||||
unsavedContents.reserve(std::size_t(abstractEditors.size()));
|
unsavedContents.reserve(std::size_t(abstractEditors.size()));
|
||||||
|
|
||||||
auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
|
auto toFileContainer = [](const CppTools::AbstractEditorSupport *abstractEditor) {
|
||||||
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
|
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
|
||||||
Utils::SmallString::fromQByteArray(abstractEditor->contents()),
|
-1,
|
||||||
{});
|
Utils::SmallString::fromQByteArray(
|
||||||
|
abstractEditor->contents()),
|
||||||
|
{});
|
||||||
};
|
};
|
||||||
|
|
||||||
std::transform(abstractEditors.begin(),
|
std::transform(abstractEditors.begin(),
|
||||||
|
@@ -37,16 +37,21 @@ CppTools::CppModelManager *cppModelManager()
|
|||||||
return CppTools::CppModelManager::instance();
|
return CppTools::CppModelManager::instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
|
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
|
||||||
|
ClangBackEnd::FilePathCachingInterface &filePathCache)
|
||||||
{
|
{
|
||||||
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
||||||
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
|
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
|
||||||
generatedFiles.reserve(std::size_t(abstractEditors.size()));
|
generatedFiles.reserve(std::size_t(abstractEditors.size()));
|
||||||
|
|
||||||
auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
|
auto toFileContainer = [&](const CppTools::AbstractEditorSupport *abstractEditor) {
|
||||||
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
|
ClangBackEnd::FilePath filePath{abstractEditor->fileName()};
|
||||||
Utils::SmallString::fromQByteArray(abstractEditor->contents()),
|
ClangBackEnd::FilePathId filePathId = filePathCache.filePathId(filePath);
|
||||||
{});
|
return ClangBackEnd::V2::FileContainer(std::move(filePath),
|
||||||
|
filePathId,
|
||||||
|
Utils::SmallString::fromQByteArray(
|
||||||
|
abstractEditor->contents()),
|
||||||
|
{});
|
||||||
};
|
};
|
||||||
|
|
||||||
std::transform(abstractEditors.begin(),
|
std::transform(abstractEditors.begin(),
|
||||||
@@ -76,9 +81,12 @@ QtCreatorRefactoringProjectUpdater::QtCreatorRefactoringProjectUpdater(
|
|||||||
connectToCppModelManager();
|
connectToCppModelManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtCreatorRefactoringProjectUpdater::abstractEditorUpdated(const QString &filePath, const QByteArray &contents)
|
void QtCreatorRefactoringProjectUpdater::abstractEditorUpdated(const QString &qFilePath,
|
||||||
|
const QByteArray &contents)
|
||||||
{
|
{
|
||||||
RefactoringProjectUpdater::updateGeneratedFiles({{ClangBackEnd::FilePath{filePath}, contents}});
|
ClangBackEnd::FilePath filePath{qFilePath};
|
||||||
|
ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(filePath);
|
||||||
|
RefactoringProjectUpdater::updateGeneratedFiles({{std::move(filePath), filePathId, contents}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtCreatorRefactoringProjectUpdater::abstractEditorRemoved(const QString &filePath)
|
void QtCreatorRefactoringProjectUpdater::abstractEditorRemoved(const QString &filePath)
|
||||||
@@ -88,7 +96,7 @@ void QtCreatorRefactoringProjectUpdater::abstractEditorRemoved(const QString &fi
|
|||||||
|
|
||||||
void QtCreatorRefactoringProjectUpdater::connectToCppModelManager()
|
void QtCreatorRefactoringProjectUpdater::connectToCppModelManager()
|
||||||
{
|
{
|
||||||
RefactoringProjectUpdater::updateGeneratedFiles(createGeneratedFiles());
|
RefactoringProjectUpdater::updateGeneratedFiles(createGeneratedFiles(m_filePathCache));
|
||||||
|
|
||||||
QObject::connect(cppModelManager(),
|
QObject::connect(cppModelManager(),
|
||||||
&CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
&CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
||||||
|
@@ -232,9 +232,8 @@ struct Data // because we have a cycle dependency
|
|||||||
pchTaskGenerator,
|
pchTaskGenerator,
|
||||||
projectParts,
|
projectParts,
|
||||||
generatedFiles,
|
generatedFiles,
|
||||||
buildDependencyStorage/*,
|
buildDependencyStorage,
|
||||||
buildDependencyProvider,
|
filePathCache};
|
||||||
filePathCache*/};
|
|
||||||
TaskScheduler systemTaskScheduler{pchCreatorManager,
|
TaskScheduler systemTaskScheduler{pchCreatorManager,
|
||||||
pchTaskQueue,
|
pchTaskQueue,
|
||||||
pchCreationProgressCounter,
|
pchCreationProgressCounter,
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include <utils/smallstring.h>
|
#include <utils/smallstring.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDirIterator>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -50,12 +51,14 @@ PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
|||||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||||
ProjectPartsManagerInterface &projectParts,
|
ProjectPartsManagerInterface &projectParts,
|
||||||
GeneratedFilesInterface &generatedFiles,
|
GeneratedFilesInterface &generatedFiles,
|
||||||
BuildDependenciesStorageInterface &buildDependenciesStorage)
|
BuildDependenciesStorageInterface &buildDependenciesStorage,
|
||||||
|
FilePathCachingInterface &filePathCache)
|
||||||
: m_fileSystemWatcher(fileSystemWatcher)
|
: m_fileSystemWatcher(fileSystemWatcher)
|
||||||
, m_pchTaskGenerator(pchTaskGenerator)
|
, m_pchTaskGenerator(pchTaskGenerator)
|
||||||
, m_projectPartsManager(projectParts)
|
, m_projectPartsManager(projectParts)
|
||||||
, m_generatedFiles(generatedFiles)
|
, m_generatedFiles(generatedFiles)
|
||||||
, m_buildDependenciesStorage(buildDependenciesStorage)
|
, m_buildDependenciesStorage(buildDependenciesStorage)
|
||||||
|
, m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
m_fileSystemWatcher.setNotifier(this);
|
m_fileSystemWatcher.setNotifier(this);
|
||||||
}
|
}
|
||||||
@@ -73,10 +76,43 @@ ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectParts)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePaths gatherPathsInIncludePaths(const ProjectPartContainers &projectParts)
|
||||||
|
{
|
||||||
|
FilePaths filePaths;
|
||||||
|
|
||||||
|
for (const ProjectPartContainer &projectPart : projectParts) {
|
||||||
|
for (const IncludeSearchPath &searchPath : projectPart.projectIncludeSearchPaths) {
|
||||||
|
QDirIterator directoryIterator(QString{searchPath.path},
|
||||||
|
{"*.h", "*.hpp"},
|
||||||
|
QDir::Files,
|
||||||
|
QDirIterator::FollowSymlinks
|
||||||
|
| QDirIterator::Subdirectories);
|
||||||
|
while (directoryIterator.hasNext()) {
|
||||||
|
filePaths.emplace_back(directoryIterator.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const IncludeSearchPath &searchPath : projectPart.systemIncludeSearchPaths) {
|
||||||
|
QDirIterator directoryIterator(QString{searchPath.path},
|
||||||
|
{"*.h", "*.hpp"},
|
||||||
|
QDir::Files,
|
||||||
|
QDirIterator::FollowSymlinks);
|
||||||
|
while (directoryIterator.hasNext()) {
|
||||||
|
filePaths.emplace_back(directoryIterator.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePaths;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
|
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
|
||||||
{
|
{
|
||||||
|
m_filePathCache.populateIfEmpty();
|
||||||
|
|
||||||
|
m_filePathCache.addFilePaths(gatherPathsInIncludePaths(message.projectsParts));
|
||||||
|
|
||||||
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
|
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
|
||||||
|
|
||||||
auto upToDateProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
|
auto upToDateProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
|
||||||
|
@@ -40,6 +40,7 @@ namespace ClangBackEnd {
|
|||||||
class SourceRangesAndDiagnosticsForQueryMessage;
|
class SourceRangesAndDiagnosticsForQueryMessage;
|
||||||
class PchTaskGeneratorInterface;
|
class PchTaskGeneratorInterface;
|
||||||
class BuildDependenciesStorageInterface;
|
class BuildDependenciesStorageInterface;
|
||||||
|
class FilePathCachingInterface;
|
||||||
|
|
||||||
class PchManagerServer : public PchManagerServerInterface,
|
class PchManagerServer : public PchManagerServerInterface,
|
||||||
public ClangPathWatcherNotifier,
|
public ClangPathWatcherNotifier,
|
||||||
@@ -51,7 +52,8 @@ public:
|
|||||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||||
ProjectPartsManagerInterface &projectParts,
|
ProjectPartsManagerInterface &projectParts,
|
||||||
GeneratedFilesInterface &generatedFiles,
|
GeneratedFilesInterface &generatedFiles,
|
||||||
BuildDependenciesStorageInterface &buildDependenciesStorage);
|
BuildDependenciesStorageInterface &buildDependenciesStorage,
|
||||||
|
FilePathCachingInterface &filePathCache);
|
||||||
|
|
||||||
void end() override;
|
void end() override;
|
||||||
void updateProjectParts(UpdateProjectPartsMessage &&message) override;
|
void updateProjectParts(UpdateProjectPartsMessage &&message) override;
|
||||||
@@ -76,6 +78,7 @@ private:
|
|||||||
GeneratedFilesInterface &m_generatedFiles;
|
GeneratedFilesInterface &m_generatedFiles;
|
||||||
BuildDependenciesStorageInterface &m_buildDependenciesStorage;
|
BuildDependenciesStorageInterface &m_buildDependenciesStorage;
|
||||||
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
|
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
|
||||||
|
FilePathCachingInterface &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -56,27 +56,6 @@ namespace {
|
|||||||
|
|
||||||
enum class Change { System, Project, No };
|
enum class Change { System, Project, No };
|
||||||
|
|
||||||
Change changedSourceType(const SourceEntries &sources)
|
|
||||||
{
|
|
||||||
Change change = Change::No;
|
|
||||||
for (SourceEntry sourceEntry : sources) {
|
|
||||||
switch (sourceEntry.sourceType) {
|
|
||||||
case SourceType::SystemInclude:
|
|
||||||
case SourceType::TopSystemInclude:
|
|
||||||
return Change::System;
|
|
||||||
case SourceType::ProjectInclude:
|
|
||||||
case SourceType::TopProjectInclude:
|
|
||||||
change = Change::Project;
|
|
||||||
break;
|
|
||||||
case SourceType::Source:
|
|
||||||
case SourceType::UserInclude:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
Change changedSourceType(SourceEntry sourceEntry, Change oldChange)
|
Change changedSourceType(SourceEntry sourceEntry, Change oldChange)
|
||||||
{
|
{
|
||||||
switch (sourceEntry.sourceType) {
|
switch (sourceEntry.sourceType) {
|
||||||
@@ -109,16 +88,6 @@ FilePathIds existingSources(const FilePathIds &sources, const FilePathIds &gener
|
|||||||
return existingSources;
|
return existingSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePathIds toFilePathIds(const V2::FileContainers &fileContainers,
|
|
||||||
FilePathCachingInterface &filePathCache)
|
|
||||||
{
|
|
||||||
auto filePaths = Utils::transform<std::vector<FilePathView>>(
|
|
||||||
fileContainers,
|
|
||||||
[](const V2::FileContainer &container) { return FilePathView(container.filePath); });
|
|
||||||
|
|
||||||
return filePathCache.filePathIds(filePaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ProjectPartsManager::UpToDataProjectParts ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
|
ProjectPartsManager::UpToDataProjectParts ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
|
||||||
@@ -175,7 +144,7 @@ ProjectPartsManagerInterface::UpToDataProjectParts ProjectPartsManager::checkDep
|
|||||||
|
|
||||||
auto systemSplit = updateSystemProjectParts.end();
|
auto systemSplit = updateSystemProjectParts.end();
|
||||||
|
|
||||||
FilePathIds generatedFiles = toFilePathIds(m_generatedFiles.fileContainers(), m_filePathCache);
|
FilePathIds generatedFiles = m_generatedFiles.filePathIds();
|
||||||
|
|
||||||
std::vector<IdPaths> watchedIdPaths;
|
std::vector<IdPaths> watchedIdPaths;
|
||||||
watchedIdPaths.reserve(upToDateProjectParts.size() * 4);
|
watchedIdPaths.reserve(upToDateProjectParts.size() * 4);
|
||||||
|
@@ -81,6 +81,7 @@ void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesFo
|
|||||||
|
|
||||||
void RefactoringServer::updateProjectParts(UpdateProjectPartsMessage &&message)
|
void RefactoringServer::updateProjectParts(UpdateProjectPartsMessage &&message)
|
||||||
{
|
{
|
||||||
|
m_filePathCache.populateIfEmpty();
|
||||||
m_symbolIndexing.updateProjectParts(message.takeProjectsParts());
|
m_symbolIndexing.updateProjectParts(message.takeProjectsParts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ public:
|
|||||||
, m_database(database)
|
, m_database(database)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
|
void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) override
|
||||||
{
|
{
|
||||||
auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
|
auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
|
||||||
first.callable = std::move(second.callable);
|
first.callable = std::move(second.callable);
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
|
|
||||||
m_progressCounter.addTotal(int(m_tasks.size() - oldSize));
|
m_progressCounter.addTotal(int(m_tasks.size() - oldSize));
|
||||||
}
|
}
|
||||||
void removeTasks(const std::vector<int> &projectPartIds)
|
void removeTasks(const ProjectPartIds &projectPartIds) override
|
||||||
{
|
{
|
||||||
auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
|
auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
|
||||||
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
|
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
|
||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
return m_tasks;
|
return m_tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void processEntries()
|
void processEntries() override
|
||||||
{
|
{
|
||||||
auto slotUsage = m_symbolIndexerScheduler.slotUsage();
|
auto slotUsage = m_symbolIndexerScheduler.slotUsage();
|
||||||
uint taskCount = slotUsage.free;
|
uint taskCount = slotUsage.free;
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <queueinterface.h>
|
#include <queueinterface.h>
|
||||||
|
|
||||||
|
#include <projectpartid.h>
|
||||||
|
|
||||||
#include <utils/smallstringvector.h>
|
#include <utils/smallstringvector.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -38,8 +40,8 @@ class SymbolIndexerTaskQueueInterface : public QueueInterface
|
|||||||
public:
|
public:
|
||||||
virtual void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) = 0
|
virtual void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) = 0
|
||||||
/* [[expects: std::is_sorted(tasks)]] */;
|
/* [[expects: std::is_sorted(tasks)]] */;
|
||||||
virtual void removeTasks(const std::vector<int> &projectPartIds) = 0
|
virtual void removeTasks(const ProjectPartIds &projectPartIds) = 0
|
||||||
/* [[expects: std::is_sorted(projectPartIds)]] */;
|
/* [[expects: std::is_sorted(projectPartIds)]] */;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SymbolIndexerTaskQueueInterface() = default;
|
~SymbolIndexerTaskQueueInterface() = default;
|
||||||
|
@@ -106,6 +106,7 @@ protected:
|
|||||||
|
|
||||||
collector.addUnsavedFiles(
|
collector.addUnsavedFiles(
|
||||||
{{{TESTDATA_DIR, "BuildDependencyCollector/project/generated_file.h"},
|
{{{TESTDATA_DIR, "BuildDependencyCollector/project/generated_file.h"},
|
||||||
|
id(TESTDATA_DIR "/BuildDependencyCollector/project/generated_file.h"),
|
||||||
"#pragma once",
|
"#pragma once",
|
||||||
{}}});
|
{}}});
|
||||||
|
|
||||||
@@ -741,6 +742,7 @@ TEST_F(BuildDependencyCollector, GeneratedFile)
|
|||||||
{
|
{
|
||||||
generatedFiles.update(
|
generatedFiles.update(
|
||||||
{{TESTDATA_DIR "/builddependencycollector/project/generated/generated_file.h",
|
{{TESTDATA_DIR "/builddependencycollector/project/generated/generated_file.h",
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/project/generated/generated_file.h"),
|
||||||
"#pragma once"}});
|
"#pragma once"}});
|
||||||
emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
|
emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
|
||||||
{"cc",
|
{"cc",
|
||||||
@@ -754,9 +756,9 @@ TEST_F(BuildDependencyCollector, GeneratedFile)
|
|||||||
|
|
||||||
emptyCollector.collect();
|
emptyCollector.collect();
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(emptyCollector.sourceEntries(),
|
||||||
emptyCollector.sourceEntries(),
|
UnorderedElementsAre(
|
||||||
ElementsAre(HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
|
HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
|
||||||
SourceType::Source),
|
SourceType::Source),
|
||||||
HasSource(id(TESTDATA_DIR
|
HasSource(id(TESTDATA_DIR
|
||||||
"/builddependencycollector/project/generated/generated_file.h"),
|
"/builddependencycollector/project/generated/generated_file.h"),
|
||||||
@@ -783,8 +785,9 @@ TEST_F(BuildDependencyCollector, Create)
|
|||||||
{
|
{
|
||||||
using ClangBackEnd::IncludeSearchPathType;
|
using ClangBackEnd::IncludeSearchPathType;
|
||||||
ClangBackEnd::BuildDependencyCollector collector{filePathCache, generatedFiles, environment};
|
ClangBackEnd::BuildDependencyCollector collector{filePathCache, generatedFiles, environment};
|
||||||
generatedFiles.update(
|
generatedFiles.update({{TESTDATA_DIR "/builddependencycollector/project/generated_file.h",
|
||||||
{{TESTDATA_DIR "/builddependencycollector/project/generated_file.h", "#pragma once"}});
|
id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
|
||||||
|
"#pragma once"}});
|
||||||
ClangBackEnd::ProjectPartContainer projectPart{
|
ClangBackEnd::ProjectPartContainer projectPart{
|
||||||
1,
|
1,
|
||||||
{},
|
{},
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
using ClangBackEnd::ClangQuery;
|
using ClangBackEnd::ClangQuery;
|
||||||
|
using ClangBackEnd::FilePath;
|
||||||
using ClangBackEnd::FilePathCaching;
|
using ClangBackEnd::FilePathCaching;
|
||||||
using ClangBackEnd::RefactoringDatabaseInitializer;
|
using ClangBackEnd::RefactoringDatabaseInitializer;
|
||||||
|
|
||||||
@@ -98,7 +99,11 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
|
|||||||
"#include \"unsaved.h\"",
|
"#include \"unsaved.h\"",
|
||||||
{"cc", "-std=c++14"});
|
{"cc", "-std=c++14"});
|
||||||
query.setQuery("functionDecl()");
|
query.setQuery("functionDecl()");
|
||||||
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}};
|
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"},
|
||||||
|
filePathCache.filePathId(
|
||||||
|
FilePath{TESTDATA_DIR, "unsaved.h"}),
|
||||||
|
"void unsaved();",
|
||||||
|
{}};
|
||||||
query.addUnsavedFiles({unsavedFile});
|
query.addUnsavedFiles({unsavedFile});
|
||||||
|
|
||||||
query.findLocations();
|
query.findLocations();
|
||||||
@@ -125,6 +130,8 @@ TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOver
|
|||||||
query.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, "void f() {}", {"cc", "-std=c++14"});
|
query.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, "void f() {}", {"cc", "-std=c++14"});
|
||||||
query.setQuery("functionDecl()");
|
query.setQuery("functionDecl()");
|
||||||
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR "/query_simplefunction.cpp"},
|
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR "/query_simplefunction.cpp"},
|
||||||
|
filePathCache.filePathId(
|
||||||
|
FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
|
||||||
"void unsaved();",
|
"void unsaved();",
|
||||||
{}};
|
{}};
|
||||||
query.addUnsavedFiles({unsavedFile});
|
query.addUnsavedFiles({unsavedFile});
|
||||||
|
@@ -59,10 +59,10 @@ using testing::SizeIs;
|
|||||||
using testing::UnorderedElementsAre;
|
using testing::UnorderedElementsAre;
|
||||||
using testing::_;
|
using testing::_;
|
||||||
|
|
||||||
using ClangBackEnd::V2::FileContainer;
|
using ClangBackEnd::FilePath;
|
||||||
|
using ClangBackEnd::SourceRangesContainer;
|
||||||
using ClangBackEnd::SourceRangesForQueryMessage;
|
using ClangBackEnd::SourceRangesForQueryMessage;
|
||||||
using ClangBackEnd::SourceRangesContainer;
|
using ClangBackEnd::V2::FileContainer;
|
||||||
using ClangBackEnd::SourceRangesContainer;
|
|
||||||
|
|
||||||
MATCHER_P2(Contains, line, column,
|
MATCHER_P2(Contains, line, column,
|
||||||
std::string(negation ? "isn't " : "is ")
|
std::string(negation ? "isn't " : "is ")
|
||||||
@@ -86,22 +86,20 @@ protected:
|
|||||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||||
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
|
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
|
||||||
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
|
||||||
sourceContent.clone(),
|
sourceContent.clone(),
|
||||||
{"cc",
|
{"cc", "-I", TESTDATA_DIR}};
|
||||||
"-I",
|
|
||||||
TESTDATA_DIR}};
|
|
||||||
FileContainer source2{{TESTDATA_DIR, "query_simplefunction2.cpp"},
|
FileContainer source2{{TESTDATA_DIR, "query_simplefunction2.cpp"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction2.cpp"}),
|
||||||
{},
|
{},
|
||||||
{"cc",
|
{"cc", "-I", TESTDATA_DIR}};
|
||||||
"-I",
|
|
||||||
TESTDATA_DIR}};
|
|
||||||
FileContainer source3{{TESTDATA_DIR, "query_simplefunction3.cpp"},
|
FileContainer source3{{TESTDATA_DIR, "query_simplefunction3.cpp"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction3.cpp"}),
|
||||||
{},
|
{},
|
||||||
{"cc",
|
{"cc", "-I", TESTDATA_DIR}};
|
||||||
"-I",
|
|
||||||
TESTDATA_DIR}};
|
|
||||||
Utils::SmallString unsavedContent{"void f();"};
|
Utils::SmallString unsavedContent{"void f();"};
|
||||||
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
|
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
|
||||||
unsavedContent.clone(),
|
unsavedContent.clone(),
|
||||||
{}};
|
{}};
|
||||||
Utils::SmallString query{"functionDecl()"};
|
Utils::SmallString query{"functionDecl()"};
|
||||||
|
@@ -122,9 +122,7 @@ protected:
|
|||||||
QString unsavedDocumentContent{"void f();"};
|
QString unsavedDocumentContent{"void f();"};
|
||||||
std::vector<Utils::SmallStringVector> commandLines;
|
std::vector<Utils::SmallStringVector> commandLines;
|
||||||
std::vector<CppTools::ProjectPart::Ptr> projectsParts;
|
std::vector<CppTools::ProjectPart::Ptr> projectsParts;
|
||||||
ClangBackEnd::V2::FileContainer unsavedContent{{"/path/to", "unsaved.cpp"},
|
ClangBackEnd::V2::FileContainer unsavedContent{{"/path/to", "unsaved.cpp"}, 1, "void f();", {}};
|
||||||
"void f();",
|
|
||||||
{}};
|
|
||||||
ProjectExplorer::Project project;
|
ProjectExplorer::Project project;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,17 +184,12 @@ TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRef
|
|||||||
|
|
||||||
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
|
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
|
||||||
{
|
{
|
||||||
ClangBackEnd::RequestSourceRangesForQueryMessage message(findDeclQueryText,
|
ClangBackEnd::RequestSourceRangesForQueryMessage message(
|
||||||
{{{"/path/to", "file1.h"},
|
findDeclQueryText,
|
||||||
"",
|
{{{"/path/to", "file1.h"}, 1, "", commandLines[0].clone()},
|
||||||
commandLines[0].clone()},
|
{{"/path/to", "file1.cpp"}, 2, "", commandLines[1].clone()},
|
||||||
{{"/path/to", "file1.cpp"},
|
{{"/path/to", "file2.cpp"}, 3, "", commandLines[2].clone()}},
|
||||||
"",
|
{unsavedContent.clone()});
|
||||||
commandLines[1].clone()},
|
|
||||||
{{"/path/to", "file2.cpp"},
|
|
||||||
"",
|
|
||||||
commandLines[2].clone()}},
|
|
||||||
{unsavedContent.clone()});
|
|
||||||
|
|
||||||
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
||||||
|
|
||||||
|
@@ -79,6 +79,7 @@ protected:
|
|||||||
NiceMock<MockFilePathStorage> mockStorage{mockDatabase};
|
NiceMock<MockFilePathStorage> mockStorage{mockDatabase};
|
||||||
Cache cache{mockStorage};
|
Cache cache{mockStorage};
|
||||||
NiceMock<MockFilePathStorage> mockStorageFilled{mockDatabase};
|
NiceMock<MockFilePathStorage> mockStorageFilled{mockDatabase};
|
||||||
|
Cache cacheNotFilled{mockStorageFilled};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(FilePathCache, FilePathIdWithOutAnyEntryCallDirectoryId)
|
TEST_F(FilePathCache, FilePathIdWithOutAnyEntryCallDirectoryId)
|
||||||
@@ -439,4 +440,51 @@ TEST_F(FilePathCache, UseTransactionIfAddingFilesOnlyInAddFilePathsCalls)
|
|||||||
|
|
||||||
cacheFilled.addFilePaths(FilePathViews{"/path/to/file.h"});
|
cacheFilled.addFilePaths(FilePathViews{"/path/to/file.h"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FilePathCache, GetFileIdInAfterPopulateIfEmpty)
|
||||||
|
{
|
||||||
|
cacheNotFilled.populateIfEmpty();
|
||||||
|
|
||||||
|
auto id = cacheNotFilled.filePathId("/path2/to/file.cpp");
|
||||||
|
|
||||||
|
ASSERT_THAT(id, Eq(72));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FilePathCache, DontPopulateIfNotEmpty)
|
||||||
|
{
|
||||||
|
cacheNotFilled.filePathId("/path/to/file.cpp");
|
||||||
|
cacheNotFilled.populateIfEmpty();
|
||||||
|
|
||||||
|
auto id = cacheNotFilled.filePathId("/path2/to/file.cpp");
|
||||||
|
|
||||||
|
ASSERT_FALSE(id.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FilePathCache, GetDirectoryIdAfterPopulateIfEmpty)
|
||||||
|
{
|
||||||
|
cacheNotFilled.populateIfEmpty();
|
||||||
|
|
||||||
|
auto id = cacheNotFilled.directoryPathId(42);
|
||||||
|
|
||||||
|
ASSERT_THAT(id, Eq(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FilePathCache, GetDirectoryPathAfterPopulateIfEmpty)
|
||||||
|
{
|
||||||
|
cacheNotFilled.populateIfEmpty();
|
||||||
|
|
||||||
|
auto path = cacheNotFilled.directoryPath(5);
|
||||||
|
|
||||||
|
ASSERT_THAT(path, Eq("/path/to"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FilePathCache, GetFilePathAfterPopulateIfEmptye)
|
||||||
|
{
|
||||||
|
cacheNotFilled.populateIfEmpty();
|
||||||
|
|
||||||
|
auto path = cacheNotFilled.filePath(42);
|
||||||
|
|
||||||
|
ASSERT_THAT(path, Eq("/path/to/file.cpp"));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -35,12 +35,12 @@ using ClangBackEnd::V2::FileContainers;
|
|||||||
class GeneratedFiles : public testing::Test
|
class GeneratedFiles : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
FileContainer file1{"/file1", "content1"};
|
FileContainer file1{"/file1", 1, "content1"};
|
||||||
FileContainer file1b{"/file1", "content1b"};
|
FileContainer file1b{"/file1", 1, "content1b"};
|
||||||
FileContainer file2{"/file2", "content2"};
|
FileContainer file2{"/file2", 2, "content2"};
|
||||||
FileContainer file2b{"/file2", "content2b"};
|
FileContainer file2b{"/file2", 2, "content2b"};
|
||||||
FileContainer file3{"/file3", "content3"};
|
FileContainer file3{"/file3", 3, "content3"};
|
||||||
FileContainer file4{"/file4", "content4"};
|
FileContainer file4{"/file4", 4, "content4"};
|
||||||
ClangBackEnd::GeneratedFiles generatedFiles;
|
ClangBackEnd::GeneratedFiles generatedFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ TEST_F(GeneratedFiles, IsValidForNoGeneratedFiles)
|
|||||||
|
|
||||||
TEST_F(GeneratedFiles, IsNotValidIfFilesWithNotContentExists)
|
TEST_F(GeneratedFiles, IsNotValidIfFilesWithNotContentExists)
|
||||||
{
|
{
|
||||||
generatedFiles.update({{"/file2", ""}});
|
generatedFiles.update({{"/file2", 2, ""}});
|
||||||
|
|
||||||
ASSERT_FALSE(generatedFiles.isValid());
|
ASSERT_FALSE(generatedFiles.isValid());
|
||||||
}
|
}
|
||||||
@@ -86,4 +86,15 @@ TEST_F(GeneratedFiles, IsValidIfAllFilesHasContent)
|
|||||||
generatedFiles.update({file1, file2, file3, file4});
|
generatedFiles.update({file1, file2, file3, file4});
|
||||||
|
|
||||||
ASSERT_TRUE(generatedFiles.isValid());
|
ASSERT_TRUE(generatedFiles.isValid());
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
TEST_F(GeneratedFiles, GetFilePathIds)
|
||||||
|
{
|
||||||
|
generatedFiles.update({file3, file2, file1, file4});
|
||||||
|
|
||||||
|
auto ids = generatedFiles.filePathIds();
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, ElementsAre(1, 2, 3, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
@@ -106,7 +106,7 @@ void PrintTo(Utils::SmallStringView text, ::std::ostream *os);
|
|||||||
void PrintTo(const Utils::SmallString &text, ::std::ostream *os);
|
void PrintTo(const Utils::SmallString &text, ::std::ostream *os);
|
||||||
void PrintTo(const Utils::PathString &text, ::std::ostream *os);
|
void PrintTo(const Utils::PathString &text, ::std::ostream *os);
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace Utils
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
class SourceLocationEntry;
|
class SourceLocationEntry;
|
||||||
|
@@ -43,4 +43,5 @@ public:
|
|||||||
MOCK_CONST_METHOD1(directoryPathId,
|
MOCK_CONST_METHOD1(directoryPathId,
|
||||||
ClangBackEnd::DirectoryPathId(ClangBackEnd::FilePathId filePathId));
|
ClangBackEnd::DirectoryPathId(ClangBackEnd::FilePathId filePathId));
|
||||||
MOCK_METHOD1(addFilePaths, void(const ClangBackEnd::FilePaths &filePaths));
|
MOCK_METHOD1(addFilePaths, void(const ClangBackEnd::FilePaths &filePaths));
|
||||||
|
MOCK_METHOD0(populateIfEmpty, void());
|
||||||
};
|
};
|
||||||
|
@@ -38,6 +38,7 @@ public:
|
|||||||
void (const ClangBackEnd::FilePaths &filePaths));
|
void (const ClangBackEnd::FilePaths &filePaths));
|
||||||
MOCK_CONST_METHOD0(fileContainers,
|
MOCK_CONST_METHOD0(fileContainers,
|
||||||
const ClangBackEnd::V2::FileContainers &());
|
const ClangBackEnd::V2::FileContainers &());
|
||||||
|
MOCK_CONST_METHOD0(filePathIds, ClangBackEnd::FilePathIds());
|
||||||
MOCK_CONST_METHOD0(isValid, bool());
|
MOCK_CONST_METHOD0(isValid, bool());
|
||||||
|
|
||||||
void update(ClangBackEnd::V2::FileContainers &&fileContainers)
|
void update(ClangBackEnd::V2::FileContainers &&fileContainers)
|
||||||
|
@@ -36,8 +36,11 @@ public:
|
|||||||
MOCK_CONST_METHOD1(
|
MOCK_CONST_METHOD1(
|
||||||
fetchProjectParts,
|
fetchProjectParts,
|
||||||
ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartIds &projectPartIds));
|
ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartIds &projectPartIds));
|
||||||
|
MOCK_CONST_METHOD0(fetchAllProjectPartNamesAndIds, ClangBackEnd::Internal::ProjectPartNameIds());
|
||||||
MOCK_CONST_METHOD1(fetchProjectPartId,
|
MOCK_CONST_METHOD1(fetchProjectPartId,
|
||||||
ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
|
ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
|
||||||
|
MOCK_CONST_METHOD1(fetchProjectPartIdUnguarded,
|
||||||
|
ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
|
||||||
MOCK_CONST_METHOD1(fetchProjectPartName,
|
MOCK_CONST_METHOD1(fetchProjectPartName,
|
||||||
Utils::PathString(ClangBackEnd::ProjectPartId projectPartId));
|
Utils::PathString(ClangBackEnd::ProjectPartId projectPartId));
|
||||||
MOCK_METHOD8(updateProjectPart,
|
MOCK_METHOD8(updateProjectPart,
|
||||||
|
@@ -109,6 +109,12 @@ std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 3>
|
|||||||
return valuesReturnStdVectorSource(reserveSize);
|
return valuesReturnStdVectorSource(reserveSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ProjectPartNameIds MockSqliteReadStatement::values<ProjectPartNameId, 2>(std::size_t reserveSize)
|
||||||
|
{
|
||||||
|
return valuesReturnProjectPartNameIds(reserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
Utils::optional<int>
|
Utils::optional<int>
|
||||||
MockSqliteReadStatement::value<int>(const Utils::SmallStringView &text)
|
MockSqliteReadStatement::value<int>(const Utils::SmallStringView &text)
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include <projectpartartefact.h>
|
#include <projectpartartefact.h>
|
||||||
#include <projectpartcontainer.h>
|
#include <projectpartcontainer.h>
|
||||||
#include <projectpartpch.h>
|
#include <projectpartpch.h>
|
||||||
|
#include <projectpartstoragestructs.h>
|
||||||
#include <sourceentry.h>
|
#include <sourceentry.h>
|
||||||
#include <stringcachefwd.h>
|
#include <stringcachefwd.h>
|
||||||
#include <symbol.h>
|
#include <symbol.h>
|
||||||
@@ -59,6 +60,8 @@ using std::int64_t;
|
|||||||
namespace Sources = ClangBackEnd::Sources;
|
namespace Sources = ClangBackEnd::Sources;
|
||||||
using ClangBackEnd::PrecompiledHeaderTimeStamps;
|
using ClangBackEnd::PrecompiledHeaderTimeStamps;
|
||||||
using ClangBackEnd::UsedMacros;
|
using ClangBackEnd::UsedMacros;
|
||||||
|
using ClangBackEnd::Internal::ProjectPartNameId;
|
||||||
|
using ClangBackEnd::Internal::ProjectPartNameIds;
|
||||||
using ClangRefactoring::Symbol;
|
using ClangRefactoring::Symbol;
|
||||||
using ClangRefactoring::Symbols;
|
using ClangRefactoring::Symbols;
|
||||||
|
|
||||||
@@ -91,6 +94,8 @@ public:
|
|||||||
|
|
||||||
MOCK_METHOD2(valuesReturnFilePathIds, FilePathIds(std::size_t, int));
|
MOCK_METHOD2(valuesReturnFilePathIds, FilePathIds(std::size_t, int));
|
||||||
|
|
||||||
|
MOCK_METHOD1(valuesReturnProjectPartNameIds, ProjectPartNameIds(std::size_t));
|
||||||
|
|
||||||
MOCK_METHOD1(valueReturnInt32, Utils::optional<int>(Utils::SmallStringView));
|
MOCK_METHOD1(valueReturnInt32, Utils::optional<int>(Utils::SmallStringView));
|
||||||
|
|
||||||
MOCK_METHOD2(valueReturnInt32, Utils::optional<int>(int, Utils::SmallStringView));
|
MOCK_METHOD2(valueReturnInt32, Utils::optional<int>(int, Utils::SmallStringView));
|
||||||
@@ -226,9 +231,11 @@ std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directo
|
|||||||
template<>
|
template<>
|
||||||
std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 3>(std::size_t reserveSize);
|
std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 3>(std::size_t reserveSize);
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
Utils::optional<int>
|
ProjectPartNameIds MockSqliteReadStatement::values<ProjectPartNameId, 2>(std::size_t reserveSize);
|
||||||
MockSqliteReadStatement::value<int>(const Utils::SmallStringView&);
|
|
||||||
|
template<>
|
||||||
|
Utils::optional<int> MockSqliteReadStatement::value<int>(const Utils::SmallStringView &);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
Utils::optional<int>
|
Utils::optional<int>
|
||||||
|
@@ -34,7 +34,6 @@ class MockSymbolIndexerTaskQueue : public ClangBackEnd::SymbolIndexerTaskQueueIn
|
|||||||
public:
|
public:
|
||||||
MOCK_METHOD1(addOrUpdateTasks,
|
MOCK_METHOD1(addOrUpdateTasks,
|
||||||
void (std::vector<ClangBackEnd::SymbolIndexerTask> &&tasks));
|
void (std::vector<ClangBackEnd::SymbolIndexerTask> &&tasks));
|
||||||
MOCK_METHOD1(removeTasks,
|
MOCK_METHOD1(removeTasks, void(const ClangBackEnd::ProjectPartIds &projectPartIds));
|
||||||
void (const std::vector<int> &projectPartIds));
|
|
||||||
MOCK_METHOD0(processEntries, void());
|
MOCK_METHOD0(processEntries, void());
|
||||||
};
|
};
|
||||||
|
@@ -91,7 +91,7 @@ protected:
|
|||||||
|
|
||||||
ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path)
|
ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path)
|
||||||
{
|
{
|
||||||
return creator.filePathCache().filePathId(path);
|
return filePathCache.filePathId(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePathIds sorted(FilePathIds &&filePathIds)
|
FilePathIds sorted(FilePathIds &&filePathIds)
|
||||||
@@ -104,17 +104,17 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
||||||
|
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||||
FilePath main1Path = TESTDATA_DIR "/builddependencycollector/project/main3.cpp";
|
FilePath main1Path = TESTDATA_DIR "/builddependencycollector/project/main3.cpp";
|
||||||
FilePath main2Path = TESTDATA_DIR "/builddependencycollector/project/main2.cpp";
|
FilePath main2Path = TESTDATA_DIR "/builddependencycollector/project/main2.cpp";
|
||||||
FilePath header1Path = TESTDATA_DIR "/builddependencycollector/project/header1.h";
|
FilePath header1Path = TESTDATA_DIR "/builddependencycollector/project/header1.h";
|
||||||
FilePath header2Path = TESTDATA_DIR "/builddependencycollector/project/header2.h";
|
FilePath header2Path = TESTDATA_DIR "/builddependencycollector/project/header2.h";
|
||||||
FilePath generatedFilePath = TESTDATA_DIR "/builddependencycollector/project/generated_file.h";
|
FilePath generatedFilePath = TESTDATA_DIR "/builddependencycollector/project/generated_file.h";
|
||||||
TestEnvironment environment;
|
TestEnvironment environment;
|
||||||
FileContainer generatedFile{generatedFilePath.clone(), "#pragma once", {}};
|
FileContainer generatedFile{generatedFilePath.clone(), id(generatedFilePath), "#pragma once", {}};
|
||||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||||
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
||||||
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
|
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
|
||||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
|
||||||
ClangBackEnd::PchCreator creator{environment,
|
ClangBackEnd::PchCreator creator{environment,
|
||||||
filePathCache,
|
filePathCache,
|
||||||
mockPchManagerClient,
|
mockPchManagerClient,
|
||||||
|
@@ -117,7 +117,7 @@ TEST_F(PchManagerClientServerInProcess, SendUpdateProjectPartsMessage)
|
|||||||
|
|
||||||
TEST_F(PchManagerClientServerInProcess, SendUpdateGeneratedFilesMessage)
|
TEST_F(PchManagerClientServerInProcess, SendUpdateGeneratedFilesMessage)
|
||||||
{
|
{
|
||||||
FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
|
FileContainer fileContainer{{"/path/to/", "file"}, 1, "content", {}};
|
||||||
UpdateGeneratedFilesMessage message{{fileContainer}};
|
UpdateGeneratedFilesMessage message{{fileContainer}};
|
||||||
|
|
||||||
EXPECT_CALL(mockPchManagerServer, updateGeneratedFiles(message));
|
EXPECT_CALL(mockPchManagerServer, updateGeneratedFiles(message));
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "mockbuilddependenciesstorage.h"
|
#include "mockbuilddependenciesstorage.h"
|
||||||
#include "mockclangpathwatcher.h"
|
#include "mockclangpathwatcher.h"
|
||||||
|
#include "mockfilepathcaching.h"
|
||||||
#include "mockgeneratedfiles.h"
|
#include "mockgeneratedfiles.h"
|
||||||
#include "mockpchmanagerclient.h"
|
#include "mockpchmanagerclient.h"
|
||||||
#include "mockpchtaskgenerator.h"
|
#include "mockpchtaskgenerator.h"
|
||||||
@@ -77,11 +78,13 @@ protected:
|
|||||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
||||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||||
|
NiceMock<MockFilePathCaching> mockFilePathCache;
|
||||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
||||||
mockPchTaskGenerator,
|
mockPchTaskGenerator,
|
||||||
mockProjectPartsManager,
|
mockProjectPartsManager,
|
||||||
mockGeneratedFiles,
|
mockGeneratedFiles,
|
||||||
mockBuildDependenciesStorage};
|
mockBuildDependenciesStorage,
|
||||||
|
mockFilePathCache};
|
||||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||||
ClangBackEnd::ProjectPartId projectPartId1{1};
|
ClangBackEnd::ProjectPartId projectPartId1{1};
|
||||||
ClangBackEnd::ProjectPartId projectPartId2{2};
|
ClangBackEnd::ProjectPartId projectPartId2{2};
|
||||||
@@ -98,7 +101,7 @@ protected:
|
|||||||
projectPartId1,
|
projectPartId1,
|
||||||
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||||
{{"DEFINE", "1", 1}},
|
{{"DEFINE", "1", 1}},
|
||||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
{{TESTDATA_DIR "/symbolscollector/include", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
{id(header1Path)},
|
{id(header1Path)},
|
||||||
{id(main1Path)},
|
{id(main1Path)},
|
||||||
@@ -110,7 +113,7 @@ protected:
|
|||||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||||
{{"DEFINE", "1", 1}},
|
{{"DEFINE", "1", 1}},
|
||||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
{{TESTDATA_DIR "/builddependencycollector", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
{id(header2Path)},
|
{id(header2Path)},
|
||||||
{id(main2Path)},
|
{id(main2Path)},
|
||||||
Utils::Language::C,
|
Utils::Language::C,
|
||||||
@@ -165,7 +168,7 @@ protected:
|
|||||||
std::vector<ProjectPartContainer> projectParts2{projectPart2};
|
std::vector<ProjectPartContainer> projectParts2{projectPart2};
|
||||||
std::vector<ProjectPartContainer> projectParts3{projectPart3};
|
std::vector<ProjectPartContainer> projectParts3{projectPart3};
|
||||||
std::vector<ProjectPartContainer> projectParts4{projectPart3, projectPart4};
|
std::vector<ProjectPartContainer> projectParts4{projectPart3, projectPart4};
|
||||||
FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
|
FileContainer generatedFile{{"/path/to/", "file"}, id("/path/to/file"), "content", {}};
|
||||||
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
|
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
|
||||||
Utils::clone(projectParts), {"toolChainArgument"}};
|
Utils::clone(projectParts), {"toolChainArgument"}};
|
||||||
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{
|
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{
|
||||||
@@ -226,7 +229,8 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
|
|||||||
mockPchTaskGenerator,
|
mockPchTaskGenerator,
|
||||||
mockProjectPartsManager,
|
mockProjectPartsManager,
|
||||||
mockGeneratedFiles,
|
mockGeneratedFiles,
|
||||||
mockBuildDependenciesStorage};
|
mockBuildDependenciesStorage,
|
||||||
|
filePathCache};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
|
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
|
||||||
@@ -419,4 +423,20 @@ TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient)
|
|||||||
|
|
||||||
server.updateProjectParts(updateProjectPartsMessage.clone());
|
server.updateProjectParts(updateProjectPartsMessage.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PchManagerServer, AddingIncludesToFileCacheForProjectUpdates)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFilePathCache, populateIfEmpty());
|
||||||
|
EXPECT_CALL(mockFilePathCache,
|
||||||
|
addFilePaths(AllOf(
|
||||||
|
Contains(Eq(TESTDATA_DIR "/symbolscollector/include/unmodified_header.h")),
|
||||||
|
Contains(Eq(TESTDATA_DIR "/symbolscollector/include/unmodified_header2.h")),
|
||||||
|
Contains(Eq(TESTDATA_DIR "/builddependencycollector/project/header2.h")),
|
||||||
|
Contains(Eq(TESTDATA_DIR "/builddependencycollector/external/external3.h")))));
|
||||||
|
EXPECT_CALL(mockProjectPartsManager, update(_));
|
||||||
|
|
||||||
|
server.updateProjectParts(updateProjectPartsMessage.clone());
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -29,11 +29,13 @@
|
|||||||
|
|
||||||
#include <builddependenciesstorage.h>
|
#include <builddependenciesstorage.h>
|
||||||
#include <projectpartsstorage.h>
|
#include <projectpartsstorage.h>
|
||||||
|
#include <projectpartstoragestructs.h>
|
||||||
#include <refactoringdatabaseinitializer.h>
|
#include <refactoringdatabaseinitializer.h>
|
||||||
#include <sqlitedatabase.h>
|
#include <sqlitedatabase.h>
|
||||||
#include <sqlitereadstatement.h>
|
#include <sqlitereadstatement.h>
|
||||||
#include <sqlitewritestatement.h>
|
#include <sqlitewritestatement.h>
|
||||||
#include <symbolstorage.h>
|
#include <symbolstorage.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ClangBackEnd::FilePathId;
|
using ClangBackEnd::FilePathId;
|
||||||
@@ -107,6 +109,7 @@ protected:
|
|||||||
MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
|
MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
|
||||||
MockSqliteReadStatement &fetchProjectPrecompiledHeaderBuildTimeStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
|
MockSqliteReadStatement &fetchProjectPrecompiledHeaderBuildTimeStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
|
||||||
MockSqliteWriteStatement &resetDependentIndexingTimeStampsStatement = storage.resetDependentIndexingTimeStampsStatement;
|
MockSqliteWriteStatement &resetDependentIndexingTimeStampsStatement = storage.resetDependentIndexingTimeStampsStatement;
|
||||||
|
MockSqliteReadStatement &fetchAllProjectPartNamesAndIdsStatement = storage.fetchAllProjectPartNamesAndIdsStatement;
|
||||||
IncludeSearchPaths systemIncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
IncludeSearchPaths systemIncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
||||||
{"/other/includes", 2, IncludeSearchPathType::System}};
|
{"/other/includes", 2, IncludeSearchPathType::System}};
|
||||||
IncludeSearchPaths projectIncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User},
|
IncludeSearchPaths projectIncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User},
|
||||||
@@ -124,6 +127,7 @@ protected:
|
|||||||
Utils::Language::Cxx,
|
Utils::Language::Cxx,
|
||||||
Utils::LanguageVersion::CXX11,
|
Utils::LanguageVersion::CXX11,
|
||||||
Utils::LanguageExtension::None};
|
Utils::LanguageExtension::None};
|
||||||
|
ClangBackEnd::Internal::ProjectPartNameIds projectPartNameIds{{"projectPartName", 2}};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
|
||||||
@@ -139,6 +143,17 @@ TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
|
|||||||
storage.fetchProjectPartId("test");
|
storage.fetchProjectPartId("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartNameUnguarded)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
||||||
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")));
|
||||||
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")));
|
||||||
|
|
||||||
|
storage.fetchProjectPartIdUnguarded("test");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
@@ -153,6 +168,18 @@ TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
|
|||||||
storage.fetchProjectPartId("test");
|
storage.fetchProjectPartId("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPartUnguarded)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
||||||
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
||||||
|
.WillOnce(Return(Utils::optional<ProjectPartId>{20}));
|
||||||
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test"))).Times(0);
|
||||||
|
|
||||||
|
storage.fetchProjectPartIdUnguarded("test");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithBusyDatabaset)
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithBusyDatabaset)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
@@ -184,6 +211,18 @@ TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartName)
|
|||||||
ASSERT_THAT(id.projectPathId, 21);
|
ASSERT_THAT(id.projectPathId, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameUnguarded)
|
||||||
|
{
|
||||||
|
ON_CALL(fetchProjectPartIdStatement,
|
||||||
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
||||||
|
.WillByDefault(Return(Utils::optional<ProjectPartId>{}));
|
||||||
|
ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(21));
|
||||||
|
|
||||||
|
auto id = storage.fetchProjectPartIdUnguarded("test");
|
||||||
|
|
||||||
|
ASSERT_THAT(id.projectPathId, 21);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameAndIsBusy)
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameAndIsBusy)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
@@ -211,6 +250,17 @@ TEST_F(ProjectPartsStorage, FetchProjectIdWithExistingProjectPartName)
|
|||||||
ASSERT_THAT(id.projectPathId, 20);
|
ASSERT_THAT(id.projectPathId, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithExistingProjectPartNameUnguarded)
|
||||||
|
{
|
||||||
|
ON_CALL(fetchProjectPartIdStatement,
|
||||||
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
||||||
|
.WillByDefault(Return(Utils::optional<ProjectPartId>{20}));
|
||||||
|
|
||||||
|
auto id = storage.fetchProjectPartIdUnguarded("test");
|
||||||
|
|
||||||
|
ASSERT_THAT(id.projectPathId, 20);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, FetchProjectPartName)
|
TEST_F(ProjectPartsStorage, FetchProjectPartName)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
@@ -418,6 +468,7 @@ TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatem
|
|||||||
|
|
||||||
storage.fetchProjectPartArtefact(FilePathId{1});
|
storage.fetchProjectPartArtefact(FilePathId{1});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdReturnArtefact)
|
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdReturnArtefact)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
|
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
|
||||||
@@ -495,6 +546,34 @@ TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStampsIsBusy)
|
|||||||
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, FetchAllProjectPartNamesAndIdsCalls)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
|
||||||
|
.WillRepeatedly(Return(projectPartNameIds));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.fetchAllProjectPartNamesAndIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorage, FetchAllProjectPartNamesAndIdsCallsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockDatabase, rollback());
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
|
||||||
|
.WillRepeatedly(Return(projectPartNameIds));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.fetchAllProjectPartNamesAndIds();
|
||||||
|
}
|
||||||
|
|
||||||
class ProjectPartsStorageSlow : public testing::Test, public Data
|
class ProjectPartsStorageSlow : public testing::Test, public Data
|
||||||
{
|
{
|
||||||
using Storage = ClangBackEnd::ProjectPartsStorage<Sqlite::Database>;
|
using Storage = ClangBackEnd::ProjectPartsStorage<Sqlite::Database>;
|
||||||
@@ -530,6 +609,15 @@ TEST_F(ProjectPartsStorageSlow, FetchProjectPartId)
|
|||||||
ASSERT_THAT(first, Eq(second));
|
ASSERT_THAT(first, Eq(second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorageSlow, FetchProjectPartIdUnguarded)
|
||||||
|
{
|
||||||
|
auto first = storage.fetchProjectPartId("test");
|
||||||
|
|
||||||
|
auto second = storage.fetchProjectPartIdUnguarded("test");
|
||||||
|
|
||||||
|
ASSERT_THAT(first, Eq(second));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectPartsStorageSlow, FetchProjectParts)
|
TEST_F(ProjectPartsStorageSlow, FetchProjectParts)
|
||||||
{
|
{
|
||||||
projectPart1.projectPartId = storage.fetchProjectPartId("project1");
|
projectPart1.projectPartId = storage.fetchProjectPartId("project1");
|
||||||
@@ -563,4 +651,16 @@ TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps)
|
|||||||
SourceTimeStamp{10, 34}));
|
SourceTimeStamp{10, 34}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectPartsStorageSlow, FetchAllProjectPartNamesAndIdsy)
|
||||||
|
{
|
||||||
|
using ClangBackEnd::Internal::ProjectPartNameId;
|
||||||
|
auto id = storage.fetchProjectPartId("projectPartName");
|
||||||
|
auto id2 = storage.fetchProjectPartId("projectPartName2");
|
||||||
|
|
||||||
|
auto values = storage.fetchAllProjectPartNamesAndIds();
|
||||||
|
|
||||||
|
ASSERT_THAT(values,
|
||||||
|
UnorderedElementsAre(ProjectPartNameId{"projectPartName", id},
|
||||||
|
ProjectPartNameId{"projectPartName2", id2}));
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -66,10 +66,11 @@ using testing::NiceMock;
|
|||||||
using testing::AnyNumber;
|
using testing::AnyNumber;
|
||||||
|
|
||||||
using ClangBackEnd::CompilerMacro;
|
using ClangBackEnd::CompilerMacro;
|
||||||
|
using ClangBackEnd::FilePath;
|
||||||
using ClangBackEnd::IncludeSearchPath;
|
using ClangBackEnd::IncludeSearchPath;
|
||||||
using ClangBackEnd::IncludeSearchPathType;
|
using ClangBackEnd::IncludeSearchPathType;
|
||||||
using ClangBackEnd::V2::FileContainer;
|
|
||||||
using ClangBackEnd::ProjectPartContainer;
|
using ClangBackEnd::ProjectPartContainer;
|
||||||
|
using ClangBackEnd::V2::FileContainer;
|
||||||
using CppTools::CompilerOptionsBuilder;
|
using CppTools::CompilerOptionsBuilder;
|
||||||
using ProjectExplorer::HeaderPath;
|
using ProjectExplorer::HeaderPath;
|
||||||
|
|
||||||
@@ -182,9 +183,18 @@ protected:
|
|||||||
CppTools::ProjectPart nonBuildingProjectPart;
|
CppTools::ProjectPart nonBuildingProjectPart;
|
||||||
ProjectPartContainer expectedContainer;
|
ProjectPartContainer expectedContainer;
|
||||||
ProjectPartContainer expectedContainer2;
|
ProjectPartContainer expectedContainer2;
|
||||||
FileContainer generatedFile{{"/path/to", "header1.h"}, "content", {}};
|
FileContainer generatedFile{{"/path/to", "header1.h"},
|
||||||
FileContainer generatedFile2{{"/path/to2", "header1.h"}, "content", {}};
|
filePathCache.filePathId(FilePath{"/path/to", "header1.h"}),
|
||||||
FileContainer generatedFile3{{"/path/to", "header2.h"}, "content", {}};
|
"content",
|
||||||
|
{}};
|
||||||
|
FileContainer generatedFile2{{"/path/to2", "header1.h"},
|
||||||
|
filePathCache.filePathId(FilePath{"/path/to2", "header1.h"}),
|
||||||
|
"content",
|
||||||
|
{}};
|
||||||
|
FileContainer generatedFile3{{"/path/to", "header2.h"},
|
||||||
|
filePathCache.filePathId(FilePath{"/path/to", "header2.h"}),
|
||||||
|
"content",
|
||||||
|
{}};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ProjectUpdater, CallUpdateProjectParts)
|
TEST_F(ProjectUpdater, CallUpdateProjectParts)
|
||||||
@@ -271,6 +281,7 @@ TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
|
|||||||
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
|
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
|
||||||
{
|
{
|
||||||
updater.setExcludedPaths({"/path/to/header1.h"});
|
updater.setExcludedPaths({"/path/to/header1.h"});
|
||||||
|
updater.fetchProjectPartIds({&projectPart});
|
||||||
|
|
||||||
auto container = updater.toProjectPartContainer(&projectPart);
|
auto container = updater.toProjectPartContainer(&projectPart);
|
||||||
|
|
||||||
@@ -279,21 +290,23 @@ TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
|
|||||||
|
|
||||||
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainersHaveSameSizeLikeProjectParts)
|
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainersHaveSameSizeLikeProjectParts)
|
||||||
{
|
{
|
||||||
|
updater.fetchProjectPartIds({&projectPart, &nonBuildingProjectPart});
|
||||||
|
|
||||||
auto containers = updater.toProjectPartContainers(
|
auto containers = updater.toProjectPartContainers(
|
||||||
{&projectPart, &projectPart, &nonBuildingProjectPart});
|
{&projectPart, &projectPart, &nonBuildingProjectPart});
|
||||||
|
|
||||||
ASSERT_THAT(containers, SizeIs(2));
|
ASSERT_THAT(containers, SizeIs(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectUpdater, CallStorageInsideTransaction)
|
TEST_F(ProjectUpdater, ProjectPartIdsPrefetchingInsideTransaction)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
CppTools::ProjectPart projectPart;
|
CppTools::ProjectPart projectPart;
|
||||||
projectPart.project = &project;
|
projectPart.project = &project;
|
||||||
projectPart.displayName = "project";
|
projectPart.displayName = "project";
|
||||||
Utils::SmallString projectPartName = projectPart.id();
|
Utils::SmallString projectPartName = projectPart.id();
|
||||||
MockSqliteTransactionBackend mockSqliteTransactionBackend;
|
NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
|
||||||
MockProjectPartsStorage mockProjectPartsStorage;
|
NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
|
||||||
ON_CALL(mockProjectPartsStorage, transactionBackend())
|
ON_CALL(mockProjectPartsStorage, transactionBackend())
|
||||||
.WillByDefault(ReturnRef(mockSqliteTransactionBackend));
|
.WillByDefault(ReturnRef(mockSqliteTransactionBackend));
|
||||||
ClangPchManager::ClangIndexingSettingsManager settingsManager;
|
ClangPchManager::ClangIndexingSettingsManager settingsManager;
|
||||||
@@ -302,9 +315,11 @@ TEST_F(ProjectUpdater, CallStorageInsideTransaction)
|
|||||||
mockProjectPartsStorage,
|
mockProjectPartsStorage,
|
||||||
settingsManager};
|
settingsManager};
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(Eq(projectPartName)));
|
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
|
||||||
|
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartIdUnguarded(Eq(projectPartName)));
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||||
|
|
||||||
updater.toProjectPartContainers({&projectPart});
|
updater.fetchProjectPartIds({&projectPart});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectUpdater, CreateSortedExcludedPaths)
|
TEST_F(ProjectUpdater, CreateSortedExcludedPaths)
|
||||||
@@ -476,7 +491,8 @@ TEST_F(ProjectUpdater, AddProjectFilesToFilePathCache)
|
|||||||
NiceMock<MockFilePathCaching> mockFilePathCaching;
|
NiceMock<MockFilePathCaching> mockFilePathCaching;
|
||||||
ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
|
ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
|
||||||
mockFilePathCaching,
|
mockFilePathCaching,
|
||||||
projectPartsStorage};
|
projectPartsStorage,
|
||||||
|
settingsManager};
|
||||||
|
|
||||||
EXPECT_CALL(mockFilePathCaching,
|
EXPECT_CALL(mockFilePathCaching,
|
||||||
addFilePaths(UnorderedElementsAre(Eq(headerPaths[0]),
|
addFilePaths(UnorderedElementsAre(Eq(headerPaths[0]),
|
||||||
@@ -487,6 +503,39 @@ TEST_F(ProjectUpdater, AddProjectFilesToFilePathCache)
|
|||||||
updater.updateProjectParts({&projectPart}, {});
|
updater.updateProjectParts({&projectPart}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for update many time and get the same id
|
TEST_F(ProjectUpdater, FillProjectPartIdCacheAtCreation)
|
||||||
|
{
|
||||||
|
NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockProjectPartsStorage, fetchAllProjectPartNamesAndIds());
|
||||||
|
|
||||||
|
ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
|
||||||
|
filePathCache,
|
||||||
|
mockProjectPartsStorage,
|
||||||
|
settingsManager};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectUpdater, DontFetchProjectPartIdFromDatabaseIfItIsInCache)
|
||||||
|
{
|
||||||
|
projectPart.files.clear();
|
||||||
|
NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
|
||||||
|
NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
|
||||||
|
ON_CALL(mockProjectPartsStorage, transactionBackend())
|
||||||
|
.WillByDefault(ReturnRef(mockSqliteTransactionBackend));
|
||||||
|
ON_CALL(mockProjectPartsStorage, fetchAllProjectPartNamesAndIds())
|
||||||
|
.WillByDefault(Return(
|
||||||
|
ClangBackEnd::Internal::ProjectPartNameIds{{Utils::PathString(projectPart.id()), 55}}));
|
||||||
|
ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
|
||||||
|
filePathCache,
|
||||||
|
mockProjectPartsStorage,
|
||||||
|
settingsManager};
|
||||||
|
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()).Times(0);
|
||||||
|
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(_)).Times(0);
|
||||||
|
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartIdUnguarded(_)).Times(0);
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
|
||||||
|
|
||||||
|
updater.updateProjectParts({&projectPart}, {});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -129,8 +129,8 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQue
|
|||||||
{
|
{
|
||||||
RequestSourceRangesForQueryMessage message{
|
RequestSourceRangesForQueryMessage message{
|
||||||
"functionDecl()",
|
"functionDecl()",
|
||||||
{{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void f();", {"cc"}, 1}},
|
{{{TESTDATA_DIR, "query_simplefunction.cpp"}, 1, "void f();", {"cc"}, 1}},
|
||||||
{{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}, 1}}};
|
{{{TESTDATA_DIR, "query_simplefunction.h"}, 2, "void f();", {}, 1}}};
|
||||||
|
|
||||||
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
||||||
|
|
||||||
@@ -143,12 +143,13 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage)
|
|||||||
RequestSourceRangesForQueryMessage message{
|
RequestSourceRangesForQueryMessage message{
|
||||||
"functionDecl()",
|
"functionDecl()",
|
||||||
{{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
{{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
||||||
|
1,
|
||||||
"void f();",
|
"void f();",
|
||||||
{
|
{
|
||||||
"cc",
|
"cc",
|
||||||
},
|
},
|
||||||
1}},
|
1}},
|
||||||
{{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}, 1}}};
|
{{{TESTDATA_DIR, "query_simplefunction.h"}, 2, "void f();", {}, 1}}};
|
||||||
|
|
||||||
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
|
||||||
|
|
||||||
@@ -182,7 +183,7 @@ TEST_F(RefactoringClientServerInProcess, SendUpdateProjectPartsMessage)
|
|||||||
|
|
||||||
TEST_F(RefactoringClientServerInProcess, SendUpdateGeneratedFilesMessage)
|
TEST_F(RefactoringClientServerInProcess, SendUpdateGeneratedFilesMessage)
|
||||||
{
|
{
|
||||||
FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
|
FileContainer fileContainer{{"/path/to/", "file"}, 1, "content", {}};
|
||||||
UpdateGeneratedFilesMessage message{{fileContainer}};
|
UpdateGeneratedFilesMessage message{{fileContainer}};
|
||||||
|
|
||||||
EXPECT_CALL(mockRefactoringServer, updateGeneratedFiles(message));
|
EXPECT_CALL(mockRefactoringServer, updateGeneratedFiles(message));
|
||||||
|
@@ -64,6 +64,10 @@ MATCHER_P(IsProjectPartContainer,
|
|||||||
class RefactoringProjectUpdater : public testing::Test
|
class RefactoringProjectUpdater : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
RefactoringProjectUpdater()
|
||||||
|
{
|
||||||
|
ON_CALL(mockProjectPartsStorage, transactionBackend()).WillByDefault(ReturnRef(database));
|
||||||
|
}
|
||||||
ProjectPart::Ptr createProjectPart(const char *name)
|
ProjectPart::Ptr createProjectPart(const char *name)
|
||||||
{
|
{
|
||||||
ProjectPart::Ptr projectPart{new ProjectPart};
|
ProjectPart::Ptr projectPart{new ProjectPart};
|
||||||
@@ -115,8 +119,6 @@ TEST_F(RefactoringProjectUpdater, UpdateProjectPart)
|
|||||||
.WillRepeatedly(Return(QString(" project1")));
|
.WillRepeatedly(Return(QString(" project1")));
|
||||||
EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString(" project1"))))
|
EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString(" project1"))))
|
||||||
.WillRepeatedly(Return(createProjectPart("project1")));
|
.WillRepeatedly(Return(createProjectPart("project1")));
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(Eq(" project1")))
|
|
||||||
.WillOnce(Return(ClangBackEnd::ProjectPartId{3}));
|
|
||||||
EXPECT_CALL(mockRefactoringServer,
|
EXPECT_CALL(mockRefactoringServer,
|
||||||
updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts,
|
updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts,
|
||||||
ElementsAre(IsProjectPartContainer(3)))));
|
ElementsAre(IsProjectPartContainer(3)))));
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
#include "filesystem-utilities.h"
|
#include "filesystem-utilities.h"
|
||||||
|
#include "mockfilepathcaching.h"
|
||||||
#include "mockrefactoringclient.h"
|
#include "mockrefactoringclient.h"
|
||||||
#include "mocksymbolindexing.h"
|
#include "mocksymbolindexing.h"
|
||||||
#include "sourcerangecontainer-matcher.h"
|
#include "sourcerangecontainer-matcher.h"
|
||||||
@@ -98,7 +99,11 @@ protected:
|
|||||||
ClangBackEnd::GeneratedFiles generatedFiles;
|
ClangBackEnd::GeneratedFiles generatedFiles;
|
||||||
ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing, filePathCache, generatedFiles};
|
ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing, filePathCache, generatedFiles};
|
||||||
Utils::SmallString sourceContent{"void f()\n {}"};
|
Utils::SmallString sourceContent{"void f()\n {}"};
|
||||||
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), {"cc"}};
|
ClangBackEnd::FilePath filePath{TESTDATA_DIR, "query_simplefunction.cpp"};
|
||||||
|
FileContainer source{filePath.clone(),
|
||||||
|
filePathCache.filePathId(filePath),
|
||||||
|
sourceContent.clone(),
|
||||||
|
{"cc"}};
|
||||||
QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath()
|
QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath()
|
||||||
+ "/clangQuery-XXXXXX.cpp"};
|
+ "/clangQuery-XXXXXX.cpp"};
|
||||||
int processingSlotCount = 2;
|
int processingSlotCount = 2;
|
||||||
@@ -126,9 +131,13 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUns
|
|||||||
{
|
{
|
||||||
Utils::SmallString unsavedContent{"void f();"};
|
Utils::SmallString unsavedContent{"void f();"};
|
||||||
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
|
||||||
"#include \"query_simplefunction.h\"",
|
"#include \"query_simplefunction.h\"",
|
||||||
{"cc"}};
|
{"cc"}};
|
||||||
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"}, unsavedContent.clone(), {}};
|
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
|
||||||
|
unsavedContent.clone(),
|
||||||
|
{}};
|
||||||
RequestSourceRangesForQueryMessage message{"functionDecl()", {source.clone()}, {unsaved.clone()}};
|
RequestSourceRangesForQueryMessage message{"functionDecl()", {source.clone()}, {unsaved.clone()}};
|
||||||
|
|
||||||
EXPECT_CALL(mockRefactoringClient,
|
EXPECT_CALL(mockRefactoringClient,
|
||||||
@@ -240,6 +249,8 @@ TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSo
|
|||||||
{
|
{
|
||||||
RequestSourceRangesAndDiagnosticsForQueryMessage message("functionDecl()",
|
RequestSourceRangesAndDiagnosticsForQueryMessage message("functionDecl()",
|
||||||
{FilePath(temporaryFile.fileName()),
|
{FilePath(temporaryFile.fileName()),
|
||||||
|
filePathCache.filePathId(FilePath(
|
||||||
|
temporaryFile.fileName())),
|
||||||
"void f() {}",
|
"void f() {}",
|
||||||
{"cc"}});
|
{"cc"}});
|
||||||
|
|
||||||
@@ -259,6 +270,8 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
|
|||||||
{
|
{
|
||||||
RequestSourceRangesAndDiagnosticsForQueryMessage message("func()",
|
RequestSourceRangesAndDiagnosticsForQueryMessage message("func()",
|
||||||
{FilePath(temporaryFile.fileName()),
|
{FilePath(temporaryFile.fileName()),
|
||||||
|
filePathCache.filePathId(FilePath(
|
||||||
|
temporaryFile.fileName())),
|
||||||
"void f() {}",
|
"void f() {}",
|
||||||
{"cc"}});
|
{"cc"}});
|
||||||
|
|
||||||
@@ -277,6 +290,7 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
|
|||||||
TEST_F(RefactoringServer, UpdateGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
|
TEST_F(RefactoringServer, UpdateGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
|
||||||
{
|
{
|
||||||
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
|
||||||
"void f();",
|
"void f();",
|
||||||
{}}};
|
{}}};
|
||||||
|
|
||||||
@@ -288,6 +302,7 @@ TEST_F(RefactoringServer, UpdateGeneratedFilesSetMemberWhichIsUsedForSymbolIndex
|
|||||||
TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
|
TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
|
||||||
{
|
{
|
||||||
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||||
|
filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
|
||||||
"void f();",
|
"void f();",
|
||||||
{}}};
|
{}}};
|
||||||
refactoringServer.updateGeneratedFiles(Utils::clone(unsaved));
|
refactoringServer.updateGeneratedFiles(Utils::clone(unsaved));
|
||||||
@@ -297,8 +312,12 @@ TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndex
|
|||||||
ASSERT_THAT(generatedFiles.fileContainers(), IsEmpty());
|
ASSERT_THAT(generatedFiles.fileContainers(), IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectParts)
|
TEST_F(RefactoringServer, UpdateProjectPartsCalls)
|
||||||
{
|
{
|
||||||
|
NiceMock<MockFilePathCaching> mockFilePathCaching;
|
||||||
|
ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing,
|
||||||
|
mockFilePathCaching,
|
||||||
|
generatedFiles};
|
||||||
ProjectPartContainers projectParts{
|
ProjectPartContainers projectParts{
|
||||||
{{1,
|
{{1,
|
||||||
{"-I", TESTDATA_DIR},
|
{"-I", TESTDATA_DIR},
|
||||||
@@ -313,8 +332,8 @@ TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectPart
|
|||||||
Utils::LanguageVersion::C11,
|
Utils::LanguageVersion::C11,
|
||||||
Utils::LanguageExtension::All}}};
|
Utils::LanguageExtension::All}}};
|
||||||
|
|
||||||
EXPECT_CALL(mockSymbolIndexing,
|
EXPECT_CALL(mockFilePathCaching, populateIfEmpty());
|
||||||
updateProjectParts(projectParts));
|
EXPECT_CALL(mockSymbolIndexing, updateProjectParts(projectParts));
|
||||||
|
|
||||||
refactoringServer.updateProjectParts({Utils::clone(projectParts), {}});
|
refactoringServer.updateProjectParts({Utils::clone(projectParts), {}});
|
||||||
}
|
}
|
||||||
|
@@ -203,6 +203,7 @@ protected:
|
|||||||
Utils::LanguageVersion::CXX14,
|
Utils::LanguageVersion::CXX14,
|
||||||
Utils::LanguageExtension::None};
|
Utils::LanguageExtension::None};
|
||||||
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||||
|
filePathId(TESTDATA_DIR "/query_simplefunction.h"),
|
||||||
"void f();",
|
"void f();",
|
||||||
{}}};
|
{}}};
|
||||||
SymbolEntries symbolEntries{{1, {"function", "function", SymbolKind::Function}}};
|
SymbolEntries symbolEntries{{1, {"function", "function", SymbolKind::Function}}};
|
||||||
|
@@ -264,8 +264,10 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
|
|||||||
|
|
||||||
TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile))
|
TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile))
|
||||||
{
|
{
|
||||||
FileContainers unsaved{
|
FileContainers unsaved{{{TESTDATA_DIR, "symbolscollector/generated_file.h"},
|
||||||
{{TESTDATA_DIR, "symbolscollector/generated_file.h"}, "void function();", {}}};
|
filePathId({TESTDATA_DIR, "symbolscollector/generated_file.h"}),
|
||||||
|
"void function();",
|
||||||
|
{}}};
|
||||||
collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/unsaved.cpp"), {"cc"});
|
collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/unsaved.cpp"), {"cc"});
|
||||||
collector.setUnsavedFiles(std::move(unsaved));
|
collector.setUnsavedFiles(std::move(unsaved));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user