forked from qt-creator/qt-creator
Clang: Differentiate between user and non user includes for updating
We don't want to recreate a PCH if the include or source is not contained by a PCH. Change-Id: If52fc1aed92054b4165cdc634656147fbe8baa47 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
; /****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
@@ -57,7 +57,7 @@ void set_greedy_intersection_call(
|
|||||||
class WatcherEntry
|
class WatcherEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectPartId id;
|
ProjectChunkId id;
|
||||||
DirectoryPathId directoryPathId;
|
DirectoryPathId directoryPathId;
|
||||||
FilePathId filePathId;
|
FilePathId filePathId;
|
||||||
long long lastModified = -1;
|
long long lastModified = -1;
|
||||||
@@ -140,25 +140,6 @@ public:
|
|||||||
m_notifier = notifier;
|
m_notifier = notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<uint> idsFromIdPaths(const std::vector<IdPaths> &idPaths)
|
|
||||||
{
|
|
||||||
std::vector<uint> ids;
|
|
||||||
ids.reserve(idPaths.size());
|
|
||||||
|
|
||||||
auto extractId = [] (const IdPaths &idPath) {
|
|
||||||
return idPath.id;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::transform(idPaths.begin(),
|
|
||||||
idPaths.end(),
|
|
||||||
std::back_inserter(ids),
|
|
||||||
extractId);
|
|
||||||
|
|
||||||
std::sort(ids.begin(), ids.end());
|
|
||||||
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths)
|
std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths)
|
||||||
{
|
{
|
||||||
auto sumSize = [] (std::size_t size, const IdPaths &idPath) {
|
auto sumSize = [] (std::size_t size, const IdPaths &idPath) {
|
||||||
@@ -168,19 +149,19 @@ public:
|
|||||||
return std::accumulate(idPaths.begin(), idPaths.end(), std::size_t(0), sumSize);
|
return std::accumulate(idPaths.begin(), idPaths.end(), std::size_t(0), sumSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<WatcherEntries, ProjectPartIds> convertIdPathsToWatcherEntriesAndIds(
|
std::pair<WatcherEntries, ProjectChunkIds> convertIdPathsToWatcherEntriesAndIds(
|
||||||
const std::vector<IdPaths> &idPaths)
|
const std::vector<IdPaths> &idPaths)
|
||||||
{
|
{
|
||||||
WatcherEntries entries;
|
WatcherEntries entries;
|
||||||
entries.reserve(sizeOfIdPaths(idPaths));
|
entries.reserve(sizeOfIdPaths(idPaths));
|
||||||
ProjectPartIds ids;
|
ProjectChunkIds ids;
|
||||||
ids.reserve(ids.size());
|
ids.reserve(ids.size());
|
||||||
|
|
||||||
auto outputIterator = std::back_inserter(entries);
|
auto outputIterator = std::back_inserter(entries);
|
||||||
|
|
||||||
for (const IdPaths &idPath : idPaths)
|
for (const IdPaths &idPath : idPaths)
|
||||||
{
|
{
|
||||||
ProjectPartId id = idPath.id;
|
ProjectChunkId id = idPath.id;
|
||||||
|
|
||||||
ids.push_back(id);
|
ids.push_back(id);
|
||||||
|
|
||||||
@@ -214,7 +195,7 @@ public:
|
|||||||
m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
|
m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids)
|
void removeUnusedEntries(const WatcherEntries &entries, const ProjectChunkIds &ids)
|
||||||
{
|
{
|
||||||
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
|
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
|
||||||
|
|
||||||
@@ -294,7 +275,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries,
|
WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries,
|
||||||
const ProjectPartIds &ids) const
|
const ProjectChunkIds &ids) const
|
||||||
{
|
{
|
||||||
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
|
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
|
||||||
|
|
||||||
@@ -420,25 +401,22 @@ public:
|
|||||||
return filePathIds;
|
return filePathIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries)
|
std::vector<IdPaths> idPathsForWatcherEntries(WatcherEntries &&foundEntries)
|
||||||
{
|
{
|
||||||
ProjectPartIds ids;
|
std::sort(foundEntries.begin(), foundEntries.end(), [](WatcherEntry first, WatcherEntry second) {
|
||||||
ids.reserve(foundEntries.size());
|
return std::tie(first.id, first.filePathId) < std::tie(second.id, second.filePathId);
|
||||||
|
});
|
||||||
|
|
||||||
std::transform(foundEntries.begin(),
|
std::vector<IdPaths> idPaths;
|
||||||
foundEntries.end(),
|
idPaths.reserve(foundEntries.size());
|
||||||
std::back_inserter(ids),
|
|
||||||
[&](WatcherEntry entry) { return entry.id; });
|
|
||||||
|
|
||||||
return ids;
|
for (WatcherEntry entry : foundEntries) {
|
||||||
}
|
if (idPaths.empty() || idPaths.back().id != entry.id)
|
||||||
|
idPaths.push_back({entry.id, {}});
|
||||||
|
idPaths.back().filePathIds.push_back(entry.filePathId);
|
||||||
|
}
|
||||||
|
|
||||||
ProjectPartIds uniqueIds(ProjectPartIds &&ids)
|
return idPaths;
|
||||||
{
|
|
||||||
std::sort(ids.begin(), ids.end());
|
|
||||||
ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
|
|
||||||
|
|
||||||
return std::move(ids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addChangedPathForFilePath(DirectoryPathIds &&directoryPathIds)
|
void addChangedPathForFilePath(DirectoryPathIds &&directoryPathIds)
|
||||||
@@ -446,10 +424,12 @@ public:
|
|||||||
if (m_notifier) {
|
if (m_notifier) {
|
||||||
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(directoryPathIds));
|
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(directoryPathIds));
|
||||||
|
|
||||||
ProjectPartIds changedIds = idsForWatcherEntries(foundEntries);
|
FilePathIds watchedFilePathIds = watchedPaths(foundEntries);
|
||||||
|
|
||||||
m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds)));
|
std::vector<IdPaths> changedIdPaths = idPathsForWatcherEntries(std::move(foundEntries));
|
||||||
m_notifier->pathsChanged(watchedPaths(foundEntries));
|
|
||||||
|
m_notifier->pathsChanged(watchedFilePathIds);
|
||||||
|
m_notifier->pathsWithIdsChanged(changedIdPaths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,9 +26,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clangsupport_global.h"
|
#include "clangsupport_global.h"
|
||||||
|
#include "filepathid.h"
|
||||||
#include <filepathid.h>
|
#include "idpaths.h"
|
||||||
#include <projectpartid.h>
|
|
||||||
|
|
||||||
#include <utils/smallstringvector.h>
|
#include <utils/smallstringvector.h>
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ public:
|
|||||||
ClangPathWatcherNotifier(const ClangPathWatcherNotifier &) = delete;
|
ClangPathWatcherNotifier(const ClangPathWatcherNotifier &) = delete;
|
||||||
ClangPathWatcherNotifier &operator=(const ClangPathWatcherNotifier &) = delete;
|
ClangPathWatcherNotifier &operator=(const ClangPathWatcherNotifier &) = delete;
|
||||||
|
|
||||||
virtual void pathsWithIdsChanged(const ProjectPartIds &ids) = 0;
|
virtual void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) = 0;
|
||||||
virtual void pathsChanged(const FilePathIds &filePathIds) = 0;
|
virtual void pathsChanged(const FilePathIds &filePathIds) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -120,6 +120,7 @@ HEADERS += \
|
|||||||
$$PWD/projectpartid.h \
|
$$PWD/projectpartid.h \
|
||||||
$$PWD/projectpartsstorage.h \
|
$$PWD/projectpartsstorage.h \
|
||||||
$$PWD/projectpartsstorageinterface.h \
|
$$PWD/projectpartsstorageinterface.h \
|
||||||
|
$$PWD/projectsourcechunk.h \
|
||||||
$$PWD/requestcompletionsmessage.h \
|
$$PWD/requestcompletionsmessage.h \
|
||||||
$$PWD/echomessage.h \
|
$$PWD/echomessage.h \
|
||||||
$$PWD/endmessage.h \
|
$$PWD/endmessage.h \
|
||||||
|
@@ -25,21 +25,60 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "projectpartid.h"
|
|
||||||
#include "filepathid.h"
|
#include "filepathid.h"
|
||||||
|
#include "projectpartid.h"
|
||||||
|
#include "sourceentry.h"
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class ProjectChunkId
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProjectPartId id;
|
||||||
|
SourceType sourceType;
|
||||||
|
|
||||||
|
friend bool operator==(ProjectChunkId first, ProjectChunkId second)
|
||||||
|
{
|
||||||
|
return first.id == second.id && first.sourceType == second.sourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(ProjectChunkId first, ProjectPartId second)
|
||||||
|
{
|
||||||
|
return first.id == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(ProjectPartId first, ProjectChunkId second)
|
||||||
|
{
|
||||||
|
return first == second.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(ProjectChunkId first, ProjectChunkId second)
|
||||||
|
{
|
||||||
|
return !(first == second);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(ProjectChunkId first, ProjectChunkId second)
|
||||||
|
{
|
||||||
|
return std::tie(first.id, first.sourceType) < std::tie(second.id, second.sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(ProjectChunkId first, ProjectPartId second) { return first.id < second; }
|
||||||
|
|
||||||
|
friend bool operator<(ProjectPartId first, ProjectChunkId second) { return first < second.id; }
|
||||||
|
};
|
||||||
|
|
||||||
class IdPaths
|
class IdPaths
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectPartId id;
|
ProjectChunkId id;
|
||||||
FilePathIds filePathIds;
|
FilePathIds filePathIds;
|
||||||
|
|
||||||
friend bool operator==(const IdPaths &first, const IdPaths &second)
|
friend bool operator==(IdPaths first, IdPaths second)
|
||||||
{
|
{
|
||||||
return first.id == second.id && first.filePathIds == second.filePathIds;
|
return first.id == second.id && first.filePathIds == second.filePathIds;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ProjectChunkIds = std::vector<ProjectChunkId>;
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clangsupport_global.h"
|
#include "clangsupport_global.h"
|
||||||
|
#include "filepathid.h"
|
||||||
#include "projectpartid.h"
|
#include "projectpartid.h"
|
||||||
|
|
||||||
#include <utils/smallstringio.h>
|
#include <utils/smallstringio.h>
|
||||||
@@ -37,6 +38,7 @@ class PrecompiledHeadersUpdatedMessage
|
|||||||
public:
|
public:
|
||||||
PrecompiledHeadersUpdatedMessage() = default;
|
PrecompiledHeadersUpdatedMessage() = default;
|
||||||
PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId)
|
PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId)
|
||||||
|
|
||||||
{
|
{
|
||||||
projectPartIds.push_back(projectPartId);
|
projectPartIds.push_back(projectPartId);
|
||||||
}
|
}
|
||||||
|
@@ -225,7 +225,8 @@ struct Data // because we have a cycle dependency
|
|||||||
PchManagerServer clangPchManagerServer{includeWatcher,
|
PchManagerServer clangPchManagerServer{includeWatcher,
|
||||||
pchTaskGenerator,
|
pchTaskGenerator,
|
||||||
projectParts,
|
projectParts,
|
||||||
generatedFiles};
|
generatedFiles,
|
||||||
|
buildDependencyStorage};
|
||||||
TaskScheduler systemTaskScheduler{pchCreatorManager,
|
TaskScheduler systemTaskScheduler{pchCreatorManager,
|
||||||
pchTaskQueue,
|
pchTaskQueue,
|
||||||
pchCreationProgressCounter,
|
pchCreationProgressCounter,
|
||||||
|
@@ -71,6 +71,11 @@ public:
|
|||||||
return fetchPchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId);
|
return fetchPchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePathIds fetchSources(ProjectPartId projectPartId) const override
|
||||||
|
{
|
||||||
|
return fetchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId);
|
||||||
|
}
|
||||||
|
|
||||||
void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override
|
void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override
|
||||||
{
|
{
|
||||||
WriteStatement &statement = insertOrUpdateFileStatusesStatement;
|
WriteStatement &statement = insertOrUpdateFileStatusesStatement;
|
||||||
@@ -144,6 +149,94 @@ public:
|
|||||||
transaction.commit();
|
transaction.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds,
|
||||||
|
TimeStamp indexingTimeStamp) override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::ImmediateTransaction transaction{database};
|
||||||
|
|
||||||
|
for (FilePathId filePathId : filePathIds) {
|
||||||
|
inserOrUpdateIndexingTimesStampStatement.write(filePathId.filePathId,
|
||||||
|
indexingTimeStamp.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
insertOrUpdateIndexingTimeStamps(filePathIds, indexingTimeStamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) override
|
||||||
|
{
|
||||||
|
for (FileStatus fileStatus : fileStatuses) {
|
||||||
|
inserOrUpdateIndexingTimesStampStatement.write(fileStatus.filePathId.filePathId,
|
||||||
|
fileStatus.lastModified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceTimeStamps fetchIndexingTimeStamps() const override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
|
auto timeStamps = fetchIndexingTimeStampsStatement.template values<SourceTimeStamp, 2>(
|
||||||
|
1024);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return timeStamps;
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
return fetchIndexingTimeStamps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
|
auto timeStamps = fetchIncludedIndexingTimeStampsStatement
|
||||||
|
.template values<SourceTimeStamp, 2>(1024, sourcePathId.filePathId);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return timeStamps;
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
return fetchIncludedIndexingTimeStamps(sourcePathId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
FilePathIds dependentSourceIds;
|
||||||
|
|
||||||
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
|
for (FilePathId sourcePathId : sourcePathIds) {
|
||||||
|
FilePathIds newDependentSourceIds;
|
||||||
|
newDependentSourceIds.reserve(dependentSourceIds.size() + 1024);
|
||||||
|
|
||||||
|
auto newIds = fetchDependentSourceIdsStatement
|
||||||
|
.template values<FilePathId>(1024, sourcePathId.filePathId);
|
||||||
|
|
||||||
|
std::set_union(dependentSourceIds.begin(),
|
||||||
|
dependentSourceIds.end(),
|
||||||
|
newIds.begin(),
|
||||||
|
newIds.end(),
|
||||||
|
std::back_inserter(newDependentSourceIds));
|
||||||
|
|
||||||
|
dependentSourceIds = std::move(newDependentSourceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return dependentSourceIds;
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
return fetchDependentSourceIds(sourcePathIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
|
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
|
||||||
{
|
{
|
||||||
QJsonDocument document;
|
QJsonDocument document;
|
||||||
@@ -255,6 +348,8 @@ public:
|
|||||||
"SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? AND sourceType IN (0, 1, "
|
"SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? AND sourceType IN (0, 1, "
|
||||||
"3, 4) ORDER BY sourceId",
|
"3, 4) ORDER BY sourceId",
|
||||||
database};
|
database};
|
||||||
|
mutable ReadStatement fetchSourcesStatement{
|
||||||
|
"SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? ORDER BY sourceId", database};
|
||||||
mutable ReadStatement fetchSourceDependenciesStatement{
|
mutable ReadStatement fetchSourceDependenciesStatement{
|
||||||
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION "
|
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION "
|
||||||
"SELECT dependencySourceId FROM sourceDependencies, "
|
"SELECT dependencySourceId FROM sourceDependencies, "
|
||||||
@@ -279,5 +374,24 @@ public:
|
|||||||
database};
|
database};
|
||||||
WriteStatement deleteAllProjectPartsFilesWithProjectPartNameStatement{
|
WriteStatement deleteAllProjectPartsFilesWithProjectPartNameStatement{
|
||||||
"DELETE FROM projectPartsFiles WHERE projectPartId = ?", database};
|
"DELETE FROM projectPartsFiles WHERE projectPartId = ?", database};
|
||||||
|
WriteStatement inserOrUpdateIndexingTimesStampStatement{
|
||||||
|
"INSERT INTO fileStatuses(sourceId, indexingTimeStamp) VALUES (?001, ?002) ON "
|
||||||
|
"CONFLICT(sourceId) DO UPDATE SET indexingTimeStamp = ?002",
|
||||||
|
database};
|
||||||
|
mutable ReadStatement fetchIncludedIndexingTimeStampsStatement{
|
||||||
|
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
|
||||||
|
"dependencySourceId FROM sourceDependencies, collectedDependencies WHERE "
|
||||||
|
"sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT DISTINCT sourceId, "
|
||||||
|
"indexingTimeStamp FROM collectedDependencies NATURAL JOIN fileStatuses ORDER BY sourceId",
|
||||||
|
database};
|
||||||
|
mutable ReadStatement fetchIndexingTimeStampsStatement{
|
||||||
|
"SELECT sourceId, indexingTimeStamp FROM fileStatuses", database};
|
||||||
|
mutable ReadStatement fetchDependentSourceIdsStatement{
|
||||||
|
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
|
||||||
|
"sourceDependencies.sourceId FROM sourceDependencies, collectedDependencies WHERE "
|
||||||
|
"sourceDependencies.dependencySourceId == collectedDependencies.sourceId) SELECT sourceId "
|
||||||
|
"FROM collectedDependencies WHERE sourceId NOT IN (SELECT dependencySourceId FROM "
|
||||||
|
"sourceDependencies) ORDER BY sourceId",
|
||||||
|
database};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,12 @@ public:
|
|||||||
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) = 0;
|
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) = 0;
|
||||||
virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp, ProjectPartId projectPartId) = 0;
|
virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp, ProjectPartId projectPartId) = 0;
|
||||||
virtual FilePathIds fetchPchSources(ProjectPartId projectPartId) const = 0;
|
virtual FilePathIds fetchPchSources(ProjectPartId projectPartId) const = 0;
|
||||||
|
virtual FilePathIds fetchSources(ProjectPartId projectPartId) const = 0;
|
||||||
|
virtual void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) = 0;
|
||||||
|
virtual void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) = 0;
|
||||||
|
virtual SourceTimeStamps fetchIndexingTimeStamps() const = 0;
|
||||||
|
virtual SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const = 0;
|
||||||
|
virtual FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~BuildDependenciesStorageInterface() = default;
|
~BuildDependenciesStorageInterface() = default;
|
||||||
|
@@ -45,6 +45,8 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -110,11 +112,28 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas
|
|||||||
return builder.commandLine;
|
return builder.commandLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePathIds PchCreator::existingSources(FilePathIds sources) const
|
||||||
|
{
|
||||||
|
FilePathIds existingSources;
|
||||||
|
existingSources.reserve(sources.size());
|
||||||
|
std::set_difference(sources.begin(),
|
||||||
|
sources.end(),
|
||||||
|
m_generatedFilePathIds.begin(),
|
||||||
|
m_generatedFilePathIds.end(),
|
||||||
|
std::back_inserter(existingSources));
|
||||||
|
|
||||||
|
return existingSources;
|
||||||
|
}
|
||||||
|
|
||||||
void PchCreator::generatePch(PchTask &&pchTask)
|
void PchCreator::generatePch(PchTask &&pchTask)
|
||||||
{
|
{
|
||||||
m_projectPartPch.projectPartId = pchTask.projectPartId();
|
m_projectPartPch.projectPartId = pchTask.projectPartId();
|
||||||
m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch();
|
m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch();
|
||||||
m_sources = std::move(pchTask.sources);
|
m_watchedSystemIncludes = std::move(pchTask.watchedSystemIncludes);
|
||||||
|
m_watchedProjectIncludes = std::move(pchTask.watchedProjectIncludes);
|
||||||
|
m_watchedUserIncludes = std::move(pchTask.watchedUserIncludes);
|
||||||
|
m_watchedSources = std::move(pchTask.watchedUserSources);
|
||||||
|
|
||||||
if (pchTask.includes.empty())
|
if (pchTask.includes.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -166,23 +185,26 @@ void PchCreator::clear()
|
|||||||
{
|
{
|
||||||
m_clangTool = ClangTool{};
|
m_clangTool = ClangTool{};
|
||||||
m_projectPartPch = {};
|
m_projectPartPch = {};
|
||||||
m_sources.clear();
|
m_watchedSystemIncludes.clear();
|
||||||
|
m_watchedProjectIncludes.clear();
|
||||||
|
m_watchedUserIncludes.clear();
|
||||||
|
m_watchedSources.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchCreator::doInMainThreadAfterFinished()
|
void PchCreator::doInMainThreadAfterFinished()
|
||||||
{
|
{
|
||||||
if (m_projectPartPch.projectPartId.isValid()) {
|
if (m_projectPartPch.projectPartId.isValid()) {
|
||||||
FilePathIds existingSources;
|
|
||||||
existingSources.reserve(m_sources.size());
|
|
||||||
std::set_difference(m_sources.begin(),
|
|
||||||
m_sources.end(),
|
|
||||||
m_generatedFilePathIds.begin(),
|
|
||||||
m_generatedFilePathIds.end(),
|
|
||||||
std::back_inserter(existingSources));
|
|
||||||
m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified,
|
m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified,
|
||||||
m_projectPartPch.projectPartId);
|
m_projectPartPch.projectPartId);
|
||||||
m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}});
|
m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::Source},
|
||||||
m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch.projectPartId});
|
existingSources(m_watchedSources)}});
|
||||||
|
m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::UserInclude},
|
||||||
|
existingSources(m_watchedUserIncludes)}});
|
||||||
|
m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::ProjectInclude},
|
||||||
|
existingSources(m_watchedProjectIncludes)}});
|
||||||
|
m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::SystemInclude},
|
||||||
|
existingSources(m_watchedSystemIncludes)}});
|
||||||
|
m_pchManagerClient.precompiledHeadersUpdated(m_projectPartPch.projectPartId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -80,19 +80,24 @@ public:
|
|||||||
static Utils::SmallStringVector generateClangCompilerArguments(const PchTask &pchTask,
|
static Utils::SmallStringVector generateClangCompilerArguments(const PchTask &pchTask,
|
||||||
FilePathView pchPath);
|
FilePathView pchPath);
|
||||||
|
|
||||||
const ClangTool &clangTool() const
|
const ClangTool &clangTool() const { return m_clangTool; }
|
||||||
{
|
|
||||||
return m_clangTool;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FilePathIds &sources() const { return m_sources; }
|
FilePathIds existingSources(FilePathIds sources) const;
|
||||||
|
|
||||||
|
const FilePathIds &watchedSystemIncludes() const { return m_watchedSystemIncludes; }
|
||||||
|
const FilePathIds &watchedProjectIncludes() const { return m_watchedProjectIncludes; }
|
||||||
|
const FilePathIds &watchedUserIncludes() const { return m_watchedUserIncludes; }
|
||||||
|
const FilePathIds &watchedSources() const { return m_watchedSources; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
|
mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
|
||||||
ClangTool m_clangTool;
|
ClangTool m_clangTool;
|
||||||
ProjectPartPch m_projectPartPch;
|
ProjectPartPch m_projectPartPch;
|
||||||
FilePathCaching m_filePathCache;
|
FilePathCaching m_filePathCache;
|
||||||
FilePathIds m_sources;
|
FilePathIds m_watchedSystemIncludes;
|
||||||
|
FilePathIds m_watchedProjectIncludes;
|
||||||
|
FilePathIds m_watchedUserIncludes;
|
||||||
|
FilePathIds m_watchedSources;
|
||||||
FilePathIds m_generatedFilePathIds;
|
FilePathIds m_generatedFilePathIds;
|
||||||
Environment &m_environment;
|
Environment &m_environment;
|
||||||
PchManagerClientInterface &m_pchManagerClient;
|
PchManagerClientInterface &m_pchManagerClient;
|
||||||
|
@@ -25,10 +25,11 @@
|
|||||||
|
|
||||||
#include "pchmanagerserver.h"
|
#include "pchmanagerserver.h"
|
||||||
|
|
||||||
|
#include <builddependenciesstorage.h>
|
||||||
#include <pchmanagerclientinterface.h>
|
#include <pchmanagerclientinterface.h>
|
||||||
|
#include <pchtaskgeneratorinterface.h>
|
||||||
#include <precompiledheadersupdatedmessage.h>
|
#include <precompiledheadersupdatedmessage.h>
|
||||||
#include <progressmessage.h>
|
#include <progressmessage.h>
|
||||||
#include <pchtaskgeneratorinterface.h>
|
|
||||||
#include <removegeneratedfilesmessage.h>
|
#include <removegeneratedfilesmessage.h>
|
||||||
#include <removeprojectpartsmessage.h>
|
#include <removeprojectpartsmessage.h>
|
||||||
#include <updategeneratedfilesmessage.h>
|
#include <updategeneratedfilesmessage.h>
|
||||||
@@ -39,16 +40,20 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
||||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||||
ProjectPartsManagerInterface &projectParts,
|
ProjectPartsManagerInterface &projectParts,
|
||||||
GeneratedFilesInterface &generatedFiles)
|
GeneratedFilesInterface &generatedFiles,
|
||||||
|
BuildDependenciesStorageInterface &buildDependenciesStorage)
|
||||||
: 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_fileSystemWatcher.setNotifier(this);
|
m_fileSystemWatcher.setNotifier(this);
|
||||||
}
|
}
|
||||||
@@ -130,18 +135,74 @@ void PchManagerServer::removeGeneratedFiles(RemoveGeneratedFilesMessage &&messag
|
|||||||
m_generatedFiles.remove(message.takeGeneratedFiles());
|
m_generatedFiles.remove(message.takeGeneratedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchManagerServer::pathsWithIdsChanged(const ProjectPartIds &ids)
|
namespace {
|
||||||
|
struct FilterResults
|
||||||
{
|
{
|
||||||
ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(ids);
|
ProjectPartIds systemIds;
|
||||||
|
ProjectPartIds projectIds;
|
||||||
|
ProjectPartIds userIds;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<ProjectPartIds, ProjectPartIds> pchProjectPartIds(const std::vector<IdPaths> &idPaths)
|
||||||
|
{
|
||||||
|
ProjectPartIds changedProjectPartIds;
|
||||||
|
changedProjectPartIds.reserve(idPaths.size());
|
||||||
|
|
||||||
|
ProjectPartIds changedPchProjectPartIds;
|
||||||
|
changedPchProjectPartIds.reserve(idPaths.size());
|
||||||
|
|
||||||
|
for (const IdPaths &idPath : idPaths) {
|
||||||
|
switch (idPath.id.sourceType) {
|
||||||
|
case SourceType::TopSystemInclude:
|
||||||
|
case SourceType::SystemInclude:
|
||||||
|
case SourceType::TopProjectInclude:
|
||||||
|
case SourceType::ProjectInclude:
|
||||||
|
changedPchProjectPartIds.push_back(idPath.id.id);
|
||||||
|
break;
|
||||||
|
case SourceType::UserInclude:
|
||||||
|
case SourceType::Source:
|
||||||
|
changedProjectPartIds.push_back(idPath.id.id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changedPchProjectPartIds.erase(std::unique(changedPchProjectPartIds.begin(),
|
||||||
|
changedPchProjectPartIds.end()),
|
||||||
|
changedPchProjectPartIds.end());
|
||||||
|
changedPchProjectPartIds.erase(std::unique(changedPchProjectPartIds.begin(),
|
||||||
|
changedPchProjectPartIds.end()),
|
||||||
|
changedPchProjectPartIds.end());
|
||||||
|
|
||||||
|
ProjectPartIds changedUserProjectPartIds;
|
||||||
|
changedProjectPartIds.reserve(changedProjectPartIds.size());
|
||||||
|
|
||||||
|
std::set_difference(changedProjectPartIds.begin(),
|
||||||
|
changedProjectPartIds.end(),
|
||||||
|
changedPchProjectPartIds.begin(),
|
||||||
|
changedPchProjectPartIds.end(),
|
||||||
|
std::back_inserter(changedUserProjectPartIds));
|
||||||
|
|
||||||
|
return {changedPchProjectPartIds, changedUserProjectPartIds};
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void PchManagerServer::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths)
|
||||||
|
{
|
||||||
|
auto changedProjectPartIds = pchProjectPartIds(idPaths);
|
||||||
|
|
||||||
|
ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(changedProjectPartIds.first);
|
||||||
|
|
||||||
for (ArgumentsEntry &entry : entries) {
|
for (ArgumentsEntry &entry : entries) {
|
||||||
m_pchTaskGenerator.addProjectParts(m_projectPartsManager.projects(entry.ids),
|
m_pchTaskGenerator.addProjectParts(m_projectPartsManager.projects(entry.ids),
|
||||||
std::move(entry.arguments));
|
std::move(entry.arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client()->precompiledHeadersUpdated(std::move(changedProjectPartIds.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/)
|
void PchManagerServer::pathsChanged(const FilePathIds &filePathIds)
|
||||||
{
|
{
|
||||||
|
m_buildDependenciesStorage.insertOrUpdateIndexingTimeStamps(filePathIds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchManagerServer::setPchCreationProgress(int progress, int total)
|
void PchManagerServer::setPchCreationProgress(int progress, int total)
|
||||||
|
@@ -39,6 +39,7 @@ namespace ClangBackEnd {
|
|||||||
|
|
||||||
class SourceRangesAndDiagnosticsForQueryMessage;
|
class SourceRangesAndDiagnosticsForQueryMessage;
|
||||||
class PchTaskGeneratorInterface;
|
class PchTaskGeneratorInterface;
|
||||||
|
class BuildDependenciesStorageInterface;
|
||||||
|
|
||||||
class PchManagerServer : public PchManagerServerInterface,
|
class PchManagerServer : public PchManagerServerInterface,
|
||||||
public ClangPathWatcherNotifier,
|
public ClangPathWatcherNotifier,
|
||||||
@@ -49,7 +50,8 @@ public:
|
|||||||
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
||||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||||
ProjectPartsManagerInterface &projectParts,
|
ProjectPartsManagerInterface &projectParts,
|
||||||
GeneratedFilesInterface &generatedFiles);
|
GeneratedFilesInterface &generatedFiles,
|
||||||
|
BuildDependenciesStorageInterface &buildDependenciesStorage);
|
||||||
|
|
||||||
void end() override;
|
void end() override;
|
||||||
void updateProjectParts(UpdateProjectPartsMessage &&message) override;
|
void updateProjectParts(UpdateProjectPartsMessage &&message) override;
|
||||||
@@ -57,7 +59,7 @@ public:
|
|||||||
void updateGeneratedFiles(UpdateGeneratedFilesMessage &&message) override;
|
void updateGeneratedFiles(UpdateGeneratedFilesMessage &&message) override;
|
||||||
void removeGeneratedFiles(RemoveGeneratedFilesMessage &&message) override;
|
void removeGeneratedFiles(RemoveGeneratedFilesMessage &&message) override;
|
||||||
|
|
||||||
void pathsWithIdsChanged(const ProjectPartIds &ids) override;
|
void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override;
|
||||||
void pathsChanged(const FilePathIds &filePathIds) override;
|
void pathsChanged(const FilePathIds &filePathIds) override;
|
||||||
|
|
||||||
void setPchCreationProgress(int progress, int total);
|
void setPchCreationProgress(int progress, int total);
|
||||||
@@ -68,6 +70,7 @@ private:
|
|||||||
PchTaskGeneratorInterface &m_pchTaskGenerator;
|
PchTaskGeneratorInterface &m_pchTaskGenerator;
|
||||||
ProjectPartsManagerInterface &m_projectPartsManager;
|
ProjectPartsManagerInterface &m_projectPartsManager;
|
||||||
GeneratedFilesInterface &m_generatedFiles;
|
GeneratedFilesInterface &m_generatedFiles;
|
||||||
|
BuildDependenciesStorageInterface &m_buildDependenciesStorage;
|
||||||
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
|
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -42,7 +42,10 @@ class PchTask
|
|||||||
public:
|
public:
|
||||||
PchTask(ProjectPartId projectPartId,
|
PchTask(ProjectPartId projectPartId,
|
||||||
FilePathIds &&includes,
|
FilePathIds &&includes,
|
||||||
FilePathIds &&sources,
|
FilePathIds &&watchedSystemIncludes,
|
||||||
|
FilePathIds &&watchedProjectIncludes,
|
||||||
|
FilePathIds &&watchedUserIncludes,
|
||||||
|
FilePathIds &&watchedUserSources,
|
||||||
CompilerMacros &&compilerMacros,
|
CompilerMacros &&compilerMacros,
|
||||||
Utils::SmallStringVector &&usedMacros, // TODO remove
|
Utils::SmallStringVector &&usedMacros, // TODO remove
|
||||||
Utils::SmallStringVector toolChainArguments,
|
Utils::SmallStringVector toolChainArguments,
|
||||||
@@ -53,7 +56,10 @@ public:
|
|||||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
||||||
: projectPartIds({projectPartId})
|
: projectPartIds({projectPartId})
|
||||||
, includes(includes)
|
, includes(includes)
|
||||||
, sources(sources)
|
, watchedSystemIncludes(watchedSystemIncludes)
|
||||||
|
, watchedProjectIncludes(watchedProjectIncludes)
|
||||||
|
, watchedUserIncludes(watchedUserIncludes)
|
||||||
|
, watchedUserSources(watchedUserSources)
|
||||||
, compilerMacros(compilerMacros)
|
, compilerMacros(compilerMacros)
|
||||||
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
||||||
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
||||||
@@ -65,7 +71,10 @@ public:
|
|||||||
|
|
||||||
PchTask(ProjectPartIds &&projectPartIds,
|
PchTask(ProjectPartIds &&projectPartIds,
|
||||||
FilePathIds &&includes,
|
FilePathIds &&includes,
|
||||||
FilePathIds &&sources,
|
FilePathIds &&watchedSystemIncludes,
|
||||||
|
FilePathIds &&watchedProjectIncludes,
|
||||||
|
FilePathIds &&watchedUserIncludes,
|
||||||
|
FilePathIds &&watchedUserSources,
|
||||||
CompilerMacros &&compilerMacros,
|
CompilerMacros &&compilerMacros,
|
||||||
Utils::SmallStringVector &&usedMacros, // TODO remove
|
Utils::SmallStringVector &&usedMacros, // TODO remove
|
||||||
Utils::SmallStringVector toolChainArguments,
|
Utils::SmallStringVector toolChainArguments,
|
||||||
@@ -76,7 +85,10 @@ public:
|
|||||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
||||||
: projectPartIds(std::move(projectPartIds))
|
: projectPartIds(std::move(projectPartIds))
|
||||||
, includes(includes)
|
, includes(includes)
|
||||||
, sources(sources)
|
, watchedSystemIncludes(watchedSystemIncludes)
|
||||||
|
, watchedProjectIncludes(watchedProjectIncludes)
|
||||||
|
, watchedUserIncludes(watchedUserIncludes)
|
||||||
|
, watchedUserSources(watchedUserSources)
|
||||||
, compilerMacros(compilerMacros)
|
, compilerMacros(compilerMacros)
|
||||||
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
||||||
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
||||||
@@ -90,6 +102,10 @@ public:
|
|||||||
{
|
{
|
||||||
return first.systemPchPath == second.systemPchPath
|
return first.systemPchPath == second.systemPchPath
|
||||||
&& first.projectPartIds == second.projectPartIds && first.includes == second.includes
|
&& first.projectPartIds == second.projectPartIds && first.includes == second.includes
|
||||||
|
&& first.watchedSystemIncludes == second.watchedSystemIncludes
|
||||||
|
&& first.watchedProjectIncludes == second.watchedProjectIncludes
|
||||||
|
&& first.watchedUserIncludes == second.watchedUserIncludes
|
||||||
|
&& first.watchedUserSources == second.watchedUserSources
|
||||||
&& first.compilerMacros == second.compilerMacros
|
&& first.compilerMacros == second.compilerMacros
|
||||||
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
||||||
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
|
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
|
||||||
@@ -105,7 +121,10 @@ public:
|
|||||||
FilePath systemPchPath;
|
FilePath systemPchPath;
|
||||||
ProjectPartIds projectPartIds;
|
ProjectPartIds projectPartIds;
|
||||||
FilePathIds includes;
|
FilePathIds includes;
|
||||||
FilePathIds sources;
|
FilePathIds watchedSystemIncludes;
|
||||||
|
FilePathIds watchedProjectIncludes;
|
||||||
|
FilePathIds watchedUserIncludes;
|
||||||
|
FilePathIds watchedUserSources;
|
||||||
CompilerMacros compilerMacros;
|
CompilerMacros compilerMacros;
|
||||||
IncludeSearchPaths systemIncludeSearchPaths;
|
IncludeSearchPaths systemIncludeSearchPaths;
|
||||||
IncludeSearchPaths projectIncludeSearchPaths;
|
IncludeSearchPaths projectIncludeSearchPaths;
|
||||||
|
@@ -52,6 +52,9 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
|
|||||||
pchTaskSets.emplace_back(PchTask{projectPart.projectPartId,
|
pchTaskSets.emplace_back(PchTask{projectPart.projectPartId,
|
||||||
std::move(filter.topSystemIncludes),
|
std::move(filter.topSystemIncludes),
|
||||||
{},
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
std::move(filter.systemCompilerMacros),
|
std::move(filter.systemCompilerMacros),
|
||||||
std::move(filter.systemUsedMacros),
|
std::move(filter.systemUsedMacros),
|
||||||
projectPart.toolChainArguments,
|
projectPart.toolChainArguments,
|
||||||
@@ -62,6 +65,9 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
|
|||||||
projectPart.languageExtension},
|
projectPart.languageExtension},
|
||||||
PchTask{projectPart.projectPartId,
|
PchTask{projectPart.projectPartId,
|
||||||
std::move(filter.topProjectIncludes),
|
std::move(filter.topProjectIncludes),
|
||||||
|
std::move(filter.systemIncludes),
|
||||||
|
std::move(filter.projectIncludes),
|
||||||
|
std::move(filter.userIncludes),
|
||||||
std::move(filter.sources),
|
std::move(filter.sources),
|
||||||
std::move(filter.projectCompilerMacros),
|
std::move(filter.projectCompilerMacros),
|
||||||
std::move(filter.projectUsedMacros),
|
std::move(filter.projectUsedMacros),
|
||||||
|
@@ -98,8 +98,8 @@ bool PchTasksMerger::mergePchTasks(PchTask &firstTask, PchTask &secondTask)
|
|||||||
firstTask.projectPartIds = merge(std::move(firstTask.projectPartIds),
|
firstTask.projectPartIds = merge(std::move(firstTask.projectPartIds),
|
||||||
std::move(secondTask.projectPartIds));
|
std::move(secondTask.projectPartIds));
|
||||||
firstTask.includes = merge(std::move(firstTask.includes), std::move(secondTask.includes));
|
firstTask.includes = merge(std::move(firstTask.includes), std::move(secondTask.includes));
|
||||||
firstTask.sources = merge(std::move(firstTask.sources),
|
firstTask.watchedSystemIncludes = merge(std::move(firstTask.watchedSystemIncludes),
|
||||||
std::move(secondTask.sources));
|
std::move(secondTask.watchedSystemIncludes));
|
||||||
firstTask.compilerMacros = std::move(macros);
|
firstTask.compilerMacros = std::move(macros);
|
||||||
firstTask.systemIncludeSearchPaths = mergeIncludeSearchPaths(
|
firstTask.systemIncludeSearchPaths = mergeIncludeSearchPaths(
|
||||||
std::move(firstTask.systemIncludeSearchPaths),
|
std::move(firstTask.systemIncludeSearchPaths),
|
||||||
|
@@ -99,6 +99,7 @@ public:
|
|||||||
projectIncludes.reserve(sources.size());
|
projectIncludes.reserve(sources.size());
|
||||||
topSystemIncludes.reserve(sources.size() / 10);
|
topSystemIncludes.reserve(sources.size() / 10);
|
||||||
topProjectIncludes.reserve(sources.size() / 10);
|
topProjectIncludes.reserve(sources.size() / 10);
|
||||||
|
userIncludes.reserve(sources.size());
|
||||||
this->sources.reserve(sources.size());
|
this->sources.reserve(sources.size());
|
||||||
|
|
||||||
for (SourceEntry source : sources)
|
for (SourceEntry source : sources)
|
||||||
@@ -128,23 +129,22 @@ private:
|
|||||||
case SourceType::TopSystemInclude:
|
case SourceType::TopSystemInclude:
|
||||||
topSystemIncludes.emplace_back(source.sourceId);
|
topSystemIncludes.emplace_back(source.sourceId);
|
||||||
systemIncludes.emplace_back(source.sourceId);
|
systemIncludes.emplace_back(source.sourceId);
|
||||||
sources.emplace_back(source.sourceId);
|
|
||||||
break;
|
break;
|
||||||
case SourceType::SystemInclude:
|
case SourceType::SystemInclude:
|
||||||
systemIncludes.emplace_back(source.sourceId);
|
systemIncludes.emplace_back(source.sourceId);
|
||||||
sources.emplace_back(source.sourceId);
|
|
||||||
break;
|
break;
|
||||||
case SourceType::TopProjectInclude:
|
case SourceType::TopProjectInclude:
|
||||||
topProjectIncludes.emplace_back(source.sourceId);
|
topProjectIncludes.emplace_back(source.sourceId);
|
||||||
projectIncludes.emplace_back(source.sourceId);
|
projectIncludes.emplace_back(source.sourceId);
|
||||||
sources.emplace_back(source.sourceId);
|
|
||||||
break;
|
break;
|
||||||
case SourceType::ProjectInclude:
|
case SourceType::ProjectInclude:
|
||||||
projectIncludes.emplace_back(source.sourceId);
|
projectIncludes.emplace_back(source.sourceId);
|
||||||
sources.emplace_back(source.sourceId);
|
|
||||||
break;
|
break;
|
||||||
case SourceType::UserInclude:
|
case SourceType::UserInclude:
|
||||||
|
userIncludes.emplace_back(source.sourceId);
|
||||||
|
break;
|
||||||
case SourceType::Source:
|
case SourceType::Source:
|
||||||
|
sources.emplace_back(source.sourceId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +215,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
FilePathIds sources;
|
FilePathIds sources;
|
||||||
|
FilePathIds userIncludes;
|
||||||
FilePathIds projectIncludes;
|
FilePathIds projectIncludes;
|
||||||
FilePathIds systemIncludes;
|
FilePathIds systemIncludes;
|
||||||
FilePathIds topProjectIncludes;
|
FilePathIds topProjectIncludes;
|
||||||
|
@@ -98,7 +98,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
|||||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
||||||
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
||||||
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
||||||
SourceTimeStamps dependentTimeStamps = m_symbolStorage.fetchIncludedIndexingTimeStamps(
|
SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps(
|
||||||
sourcePathId);
|
sourcePathId);
|
||||||
|
|
||||||
if (!m_modifiedTimeChecker.isUpToDate(dependentTimeStamps)) {
|
if (!m_modifiedTimeChecker.isUpToDate(dependentTimeStamps)) {
|
||||||
@@ -122,7 +122,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
|||||||
|
|
||||||
auto store = [&] {
|
auto store = [&] {
|
||||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||||
m_symbolStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
|
m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps(
|
||||||
|
symbolsCollector.fileStatuses());
|
||||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||||
symbolsCollector.sourceLocations());
|
symbolsCollector.sourceLocations());
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
@@ -144,28 +145,17 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pathWatcher.updateIdPaths(
|
m_pathWatcher.updateIdPaths({{{projectPartId, SourceType::Source},
|
||||||
{{projectPartId, m_buildDependencyStorage.fetchPchSources(projectPartId)}});
|
m_buildDependencyStorage.fetchPchSources(projectPartId)}});
|
||||||
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
|
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
|
||||||
m_symbolIndexerTaskQueue.processEntries();
|
m_symbolIndexerTaskQueue.processEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolIndexer::pathsWithIdsChanged(const ProjectPartIds &) {}
|
void SymbolIndexer::pathsWithIdsChanged(const std::vector<IdPaths> &) {}
|
||||||
|
|
||||||
void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
|
void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
|
||||||
{
|
{
|
||||||
m_modifiedTimeChecker.pathsChanged(filePathIds);
|
m_modifiedTimeChecker.pathsChanged(filePathIds);
|
||||||
|
|
||||||
FilePathIds dependentSourcePathIds = m_symbolStorage.fetchDependentSourceIds(filePathIds);
|
|
||||||
|
|
||||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
|
||||||
symbolIndexerTask.reserve(dependentSourcePathIds.size());
|
|
||||||
|
|
||||||
for (FilePathId dependentSourcePathId : dependentSourcePathIds)
|
|
||||||
updateChangedPath(dependentSourcePathId, symbolIndexerTask);
|
|
||||||
|
|
||||||
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
|
|
||||||
m_symbolIndexerTaskQueue.processEntries();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||||
@@ -182,7 +172,8 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
|||||||
|
|
||||||
ProjectPartId projectPartId = optionalArtefact->projectPartId;
|
ProjectPartId projectPartId = optionalArtefact->projectPartId;
|
||||||
|
|
||||||
SourceTimeStamps dependentTimeStamps = m_symbolStorage.fetchIncludedIndexingTimeStamps(filePathId);
|
SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps(
|
||||||
|
filePathId);
|
||||||
|
|
||||||
auto indexing = [optionalArtefact = std::move(optionalArtefact),
|
auto indexing = [optionalArtefact = std::move(optionalArtefact),
|
||||||
filePathId,
|
filePathId,
|
||||||
@@ -207,7 +198,7 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
|||||||
|
|
||||||
auto store = [&] {
|
auto store = [&] {
|
||||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||||
m_symbolStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
|
m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
|
||||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||||
symbolsCollector.sourceLocations());
|
symbolsCollector.sourceLocations());
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
@@ -60,7 +60,7 @@ public:
|
|||||||
void updateProjectParts(ProjectPartContainers &&projectParts);
|
void updateProjectParts(ProjectPartContainers &&projectParts);
|
||||||
void updateProjectPart(ProjectPartContainer &&projectPart);
|
void updateProjectPart(ProjectPartContainer &&projectPart);
|
||||||
|
|
||||||
void pathsWithIdsChanged(const ProjectPartIds &ids) override;
|
void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override;
|
||||||
void pathsChanged(const FilePathIds &filePathIds) override;
|
void pathsChanged(const FilePathIds &filePathIds) override;
|
||||||
void updateChangedPath(FilePathId filePath,
|
void updateChangedPath(FilePathId filePath,
|
||||||
std::vector<SymbolIndexerTask> &symbolIndexerTask);
|
std::vector<SymbolIndexerTask> &symbolIndexerTask);
|
||||||
@@ -75,6 +75,9 @@ public:
|
|||||||
FilePathIds updatableFilePathIds(const ProjectPartContainer &projectPart,
|
FilePathIds updatableFilePathIds(const ProjectPartContainer &projectPart,
|
||||||
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
|
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FilePathIds filterProjectPartSources(const FilePathIds &filePathIds) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
|
SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
|
||||||
SymbolStorageInterface &m_symbolStorage;
|
SymbolStorageInterface &m_symbolStorage;
|
||||||
|
@@ -70,93 +70,6 @@ public:
|
|||||||
deleteNewLocationsTable();
|
deleteNewLocationsTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) override
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Sqlite::ImmediateTransaction transaction{database};
|
|
||||||
|
|
||||||
for (FilePathId filePathId : filePathIds) {
|
|
||||||
inserOrUpdateIndexingTimesStampStatement.write(filePathId.filePathId,
|
|
||||||
indexingTimeStamp.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
} catch (const Sqlite::StatementIsBusy &) {
|
|
||||||
insertOrUpdateIndexingTimeStamps(filePathIds, indexingTimeStamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) override
|
|
||||||
{
|
|
||||||
for (FileStatus fileStatus : fileStatuses) {
|
|
||||||
inserOrUpdateIndexingTimesStampStatement.write(fileStatus.filePathId.filePathId,
|
|
||||||
fileStatus.lastModified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceTimeStamps fetchIndexingTimeStamps() const override
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Sqlite::DeferredTransaction transaction{database};
|
|
||||||
|
|
||||||
auto timeStamps = fetchIndexingTimeStampsStatement.template values<SourceTimeStamp, 2>(
|
|
||||||
1024);
|
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
return timeStamps;
|
|
||||||
} catch (const Sqlite::StatementIsBusy &) {
|
|
||||||
return fetchIndexingTimeStamps();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const override
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Sqlite::DeferredTransaction transaction{database};
|
|
||||||
|
|
||||||
auto timeStamps = fetchIncludedIndexingTimeStampsStatement
|
|
||||||
.template values<SourceTimeStamp, 2>(1024, sourcePathId.filePathId);
|
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
return timeStamps;
|
|
||||||
} catch (const Sqlite::StatementIsBusy &) {
|
|
||||||
return fetchIncludedIndexingTimeStamps(sourcePathId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const override
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
FilePathIds dependentSourceIds;
|
|
||||||
|
|
||||||
Sqlite::DeferredTransaction transaction{database};
|
|
||||||
|
|
||||||
for (FilePathId sourcePathId : sourcePathIds) {
|
|
||||||
FilePathIds newDependentSourceIds;
|
|
||||||
newDependentSourceIds.reserve(dependentSourceIds.size() + 1024);
|
|
||||||
|
|
||||||
auto newIds = fetchDependentSourceIdsStatement
|
|
||||||
.template values<FilePathId>(1024, sourcePathId.filePathId);
|
|
||||||
|
|
||||||
std::set_union(dependentSourceIds.begin(),
|
|
||||||
dependentSourceIds.end(),
|
|
||||||
newIds.begin(),
|
|
||||||
newIds.end(),
|
|
||||||
std::back_inserter(newDependentSourceIds));
|
|
||||||
|
|
||||||
dependentSourceIds = std::move(newDependentSourceIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
return dependentSourceIds;
|
|
||||||
} catch (const Sqlite::StatementIsBusy &) {
|
|
||||||
return fetchDependentSourceIds(sourcePathIds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries)
|
void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries)
|
||||||
{
|
{
|
||||||
WriteStatement &statement = insertSymbolsToNewSymbolsStatement;
|
WriteStatement &statement = insertSymbolsToNewSymbolsStatement;
|
||||||
@@ -278,25 +191,6 @@ public:
|
|||||||
database};
|
database};
|
||||||
WriteStatement deleteNewSymbolsTableStatement{"DELETE FROM newSymbols", database};
|
WriteStatement deleteNewSymbolsTableStatement{"DELETE FROM newSymbols", database};
|
||||||
WriteStatement deleteNewLocationsTableStatement{"DELETE FROM newLocations", database};
|
WriteStatement deleteNewLocationsTableStatement{"DELETE FROM newLocations", database};
|
||||||
WriteStatement inserOrUpdateIndexingTimesStampStatement{
|
|
||||||
"INSERT INTO fileStatuses(sourceId, indexingTimeStamp) VALUES (?001, ?002) ON "
|
|
||||||
"CONFLICT(sourceId) DO UPDATE SET indexingTimeStamp = ?002",
|
|
||||||
database};
|
|
||||||
mutable ReadStatement fetchIncludedIndexingTimeStampsStatement{
|
|
||||||
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
|
|
||||||
"dependencySourceId FROM sourceDependencies, collectedDependencies WHERE "
|
|
||||||
"sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT DISTINCT sourceId, "
|
|
||||||
"indexingTimeStamp FROM collectedDependencies NATURAL JOIN fileStatuses ORDER BY sourceId",
|
|
||||||
database};
|
|
||||||
mutable ReadStatement fetchIndexingTimeStampsStatement{
|
|
||||||
"SELECT sourceId, indexingTimeStamp FROM fileStatuses", database};
|
|
||||||
mutable ReadStatement fetchDependentSourceIdsStatement{
|
|
||||||
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
|
|
||||||
"sourceDependencies.sourceId FROM sourceDependencies, collectedDependencies WHERE "
|
|
||||||
"sourceDependencies.dependencySourceId == collectedDependencies.sourceId) SELECT sourceId "
|
|
||||||
"FROM collectedDependencies WHERE sourceId NOT IN (SELECT dependencySourceId FROM "
|
|
||||||
"sourceDependencies) ORDER BY sourceId",
|
|
||||||
database};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -48,11 +48,6 @@ public:
|
|||||||
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||||
const SourceLocationEntries &sourceLocations)
|
const SourceLocationEntries &sourceLocations)
|
||||||
= 0;
|
= 0;
|
||||||
virtual void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) = 0;
|
|
||||||
virtual void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) = 0;
|
|
||||||
virtual SourceTimeStamps fetchIndexingTimeStamps() const = 0;
|
|
||||||
virtual SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const = 0;
|
|
||||||
virtual FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SymbolStorageInterface() = default;
|
~SymbolStorageInterface() = default;
|
||||||
|
@@ -28,8 +28,11 @@
|
|||||||
#include "mockfilepathcaching.h"
|
#include "mockfilepathcaching.h"
|
||||||
#include "mocksqlitedatabase.h"
|
#include "mocksqlitedatabase.h"
|
||||||
|
|
||||||
#include <sqlitedatabase.h>
|
|
||||||
#include <builddependenciesstorage.h>
|
#include <builddependenciesstorage.h>
|
||||||
|
#include <refactoringdatabaseinitializer.h>
|
||||||
|
#include <sqlitedatabase.h>
|
||||||
|
#include <sqlitereadstatement.h>
|
||||||
|
#include <sqlitewritestatement.h>
|
||||||
|
|
||||||
#include <utils/optional.h>
|
#include <utils/optional.h>
|
||||||
|
|
||||||
@@ -70,7 +73,12 @@ protected:
|
|||||||
MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement;
|
MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement;
|
||||||
MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement
|
MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement
|
||||||
= storage.deleteAllProjectPartsFilesWithProjectPartNameStatement;
|
= storage.deleteAllProjectPartsFilesWithProjectPartNameStatement;
|
||||||
MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchPchSourcesStatement;
|
MockSqliteReadStatement &fetchPchSourcesStatement = storage.fetchPchSourcesStatement;
|
||||||
|
MockSqliteReadStatement &fetchSourcesStatement = storage.fetchSourcesStatement;
|
||||||
|
MockSqliteWriteStatement &inserOrUpdateIndexingTimesStampStatement = storage.inserOrUpdateIndexingTimesStampStatement;
|
||||||
|
MockSqliteReadStatement &fetchIndexingTimeStampsStatement = storage.fetchIndexingTimeStampsStatement;
|
||||||
|
MockSqliteReadStatement &fetchIncludedIndexingTimeStampsStatement = storage.fetchIncludedIndexingTimeStampsStatement;
|
||||||
|
MockSqliteReadStatement &fetchDependentSourceIdsStatement = storage.fetchDependentSourceIdsStatement;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(BuildDependenciesStorage, ConvertStringsToJson)
|
TEST_F(BuildDependenciesStorage, ConvertStringsToJson)
|
||||||
@@ -233,13 +241,163 @@ TEST_F(BuildDependenciesStorage, FetchUsedMacros)
|
|||||||
ASSERT_THAT(usedMacros, result);
|
ASSERT_THAT(usedMacros, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuildDependenciesStorage, FetchSources)
|
TEST_F(BuildDependenciesStorage, FetchPchSources)
|
||||||
{
|
{
|
||||||
ClangBackEnd::FilePathIds result{3, 5, 7};
|
ClangBackEnd::FilePathIds result{3, 5, 7};
|
||||||
EXPECT_CALL(fetchProjectPartsFilesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result));
|
EXPECT_CALL(fetchPchSourcesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result));
|
||||||
|
|
||||||
auto sources = storage.fetchPchSources(22);
|
auto sources = storage.fetchPchSources(22);
|
||||||
|
|
||||||
ASSERT_THAT(sources, result);
|
ASSERT_THAT(sources, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, FetchSources)
|
||||||
|
{
|
||||||
|
ClangBackEnd::FilePathIds result{3, 5, 7};
|
||||||
|
EXPECT_CALL(fetchSourcesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result));
|
||||||
|
|
||||||
|
auto sources = storage.fetchSources(22);
|
||||||
|
|
||||||
|
ASSERT_THAT(sources, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, FetchIndexingTimeStampsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024))
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockDatabase, rollback());
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.fetchIndexingTimeStamps();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, InsertIndexingTimeStamp)
|
||||||
|
{
|
||||||
|
ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}};
|
||||||
|
|
||||||
|
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
|
||||||
|
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37)));
|
||||||
|
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps(fileStatuses);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, InsertIndexingTimeStampsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockDatabase, immediateBegin());
|
||||||
|
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
|
||||||
|
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34)));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, FetchIncludedIndexingTimeStampsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement,
|
||||||
|
valuesReturnSourceTimeStamps(1024, TypedEq<int>(1)))
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockDatabase, rollback());
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement,
|
||||||
|
valuesReturnSourceTimeStamps(1024, TypedEq<int>(1)));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.fetchIncludedIndexingTimeStamps(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorage, FetchDependentSourceIdsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3)));
|
||||||
|
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2)))
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockDatabase, rollback());
|
||||||
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3)));
|
||||||
|
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2)));
|
||||||
|
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(7)));
|
||||||
|
EXPECT_CALL(mockDatabase, commit());
|
||||||
|
|
||||||
|
storage.fetchDependentSourceIds({3, 2, 7});
|
||||||
|
}
|
||||||
|
|
||||||
|
class BuildDependenciesStorageSlow : public testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
||||||
|
ClangBackEnd::BuildDependenciesStorage<> storage{database};
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, InsertIndexingTimeStamps)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
||||||
|
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 34}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamps)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
||||||
|
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({1}, 37);
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
||||||
|
ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, InsertIndexingTimeStamp)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}});
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
||||||
|
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamp)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}});
|
||||||
|
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}});
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
||||||
|
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, FetchIncludedIndexingTimeStamps)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5}, 34);
|
||||||
|
storage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {3, 4}, {5, 3}});
|
||||||
|
|
||||||
|
auto timeStamps = storage.fetchIncludedIndexingTimeStamps(1);
|
||||||
|
|
||||||
|
ASSERT_THAT(timeStamps,
|
||||||
|
ElementsAre(SourceTimeStamp{1, 34},
|
||||||
|
SourceTimeStamp{2, 34},
|
||||||
|
SourceTimeStamp{3, 34},
|
||||||
|
SourceTimeStamp{4, 34}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuildDependenciesStorageSlow, FetchDependentSourceIds)
|
||||||
|
{
|
||||||
|
storage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {4, 2}, {5, 6}, {7, 6}});
|
||||||
|
|
||||||
|
auto sourceIds = storage.fetchDependentSourceIds({3, 2, 7});
|
||||||
|
|
||||||
|
ASSERT_THAT(sourceIds, ElementsAre(FilePathId{1}, FilePathId{4}, FilePathId{7}));
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -48,8 +48,11 @@ using ClangBackEnd::FilePath;
|
|||||||
using ClangBackEnd::FilePathId;
|
using ClangBackEnd::FilePathId;
|
||||||
using ClangBackEnd::FilePathIds;
|
using ClangBackEnd::FilePathIds;
|
||||||
using ClangBackEnd::FilePathView;
|
using ClangBackEnd::FilePathView;
|
||||||
|
using ClangBackEnd::IdPaths;
|
||||||
|
using ClangBackEnd::ProjectChunkId;
|
||||||
using ClangBackEnd::ProjectPartId;
|
using ClangBackEnd::ProjectPartId;
|
||||||
using ClangBackEnd::ProjectPartIds;
|
using ClangBackEnd::ProjectPartIds;
|
||||||
|
using ClangBackEnd::SourceType;
|
||||||
using ClangBackEnd::WatcherEntries;
|
using ClangBackEnd::WatcherEntries;
|
||||||
using ClangBackEnd::WatcherEntry;
|
using ClangBackEnd::WatcherEntry;
|
||||||
|
|
||||||
@@ -111,9 +114,9 @@ protected:
|
|||||||
NiceMock<MockFileSystem> mockFileSystem;
|
NiceMock<MockFileSystem> mockFileSystem;
|
||||||
Watcher watcher{mockFilePathCache, mockFileSystem, ¬ifier};
|
Watcher watcher{mockFilePathCache, mockFileSystem, ¬ifier};
|
||||||
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
|
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
|
||||||
ProjectPartId id1{2};
|
ProjectChunkId id1{2, SourceType::ProjectInclude};
|
||||||
ProjectPartId id2{3};
|
ProjectChunkId id2{2, SourceType::Source};
|
||||||
ProjectPartId id3{4};
|
ProjectChunkId id3{4, SourceType::SystemInclude};
|
||||||
FilePathView path1{"/path/path1"};
|
FilePathView path1{"/path/path1"};
|
||||||
FilePathView path2{"/path/path2"};
|
FilePathView path2{"/path/path2"};
|
||||||
FilePathView path3{"/path2/path1"};
|
FilePathView path3{"/path2/path1"};
|
||||||
@@ -128,14 +131,15 @@ protected:
|
|||||||
Utils::PathString directoryPathString2 = directoryPath2;
|
Utils::PathString directoryPathString2 = directoryPath2;
|
||||||
FilePathIds pathIds = {1, 2, 3, 4, 5};
|
FilePathIds pathIds = {1, 2, 3, 4, 5};
|
||||||
ClangBackEnd::DirectoryPathIds directoryPaths = {1, 2, 3};
|
ClangBackEnd::DirectoryPathIds directoryPaths = {1, 2, 3};
|
||||||
ClangBackEnd::ProjectPartIds ids{id1, id2, id3};
|
ClangBackEnd::ProjectChunkIds ids{id1, id2, id3};
|
||||||
WatcherEntry watcherEntry1{ids[0], directoryPaths[0], pathIds[0]};
|
WatcherEntry watcherEntry1{id1, directoryPaths[0], pathIds[0]};
|
||||||
WatcherEntry watcherEntry2{ids[1], directoryPaths[0], pathIds[0]};
|
WatcherEntry watcherEntry2{id2, directoryPaths[0], pathIds[0]};
|
||||||
WatcherEntry watcherEntry3{ids[0], directoryPaths[0], pathIds[1]};
|
WatcherEntry watcherEntry3{id1, directoryPaths[0], pathIds[1]};
|
||||||
WatcherEntry watcherEntry4{ids[1], directoryPaths[0], pathIds[1]};
|
WatcherEntry watcherEntry4{id2, directoryPaths[0], pathIds[1]};
|
||||||
WatcherEntry watcherEntry5{ids[2], directoryPaths[0], pathIds[1]};
|
WatcherEntry watcherEntry5{id3, directoryPaths[0], pathIds[1]};
|
||||||
WatcherEntry watcherEntry6{ids[0], directoryPaths[1], pathIds[2]};
|
WatcherEntry watcherEntry6{id1, directoryPaths[1], pathIds[2]};
|
||||||
WatcherEntry watcherEntry7{ids[1], directoryPaths[1], pathIds[3]};
|
WatcherEntry watcherEntry7{id2, directoryPaths[1], pathIds[3]};
|
||||||
|
WatcherEntry watcherEntry8{id3, directoryPaths[1], pathIds[3]};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, AddIdPaths)
|
TEST_F(ClangPathWatcher, AddIdPaths)
|
||||||
@@ -260,12 +264,13 @@ TEST_F(ClangPathWatcher, DontAddNewEntriesWithDifferentIdAndSamePaths)
|
|||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemoveEntriesWithId)
|
TEST_F(ClangPathWatcher, RemoveEntriesWithId)
|
||||||
{
|
{
|
||||||
watcher.updateIdPaths(
|
watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}},
|
||||||
{{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[1]}}});
|
{id2, {pathIds[0], pathIds[1]}},
|
||||||
|
{id3, {pathIds[1], pathIds[3]}}});
|
||||||
|
|
||||||
watcher.removeIds({id1});
|
watcher.removeIds({2});
|
||||||
|
|
||||||
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry2, watcherEntry4, watcherEntry5));
|
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry5, watcherEntry8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemoveNoPathsForEmptyIds)
|
TEST_F(ClangPathWatcher, RemoveNoPathsForEmptyIds)
|
||||||
@@ -284,28 +289,28 @@ TEST_F(ClangPathWatcher, RemoveNoPathsForOneId)
|
|||||||
EXPECT_CALL(mockQFileSytemWatcher, removePaths(_))
|
EXPECT_CALL(mockQFileSytemWatcher, removePaths(_))
|
||||||
.Times(0);
|
.Times(0);
|
||||||
|
|
||||||
watcher.removeIds({id3});
|
watcher.removeIds({id3.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemovePathForOneId)
|
TEST_F(ClangPathWatcher, RemovePathForOneId)
|
||||||
{
|
{
|
||||||
watcher.updateIdPaths(
|
watcher.updateIdPaths(
|
||||||
{{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
|
{{id1, {pathIds[0], pathIds[1]}}, {id3, {pathIds[0], pathIds[1], pathIds[3]}}});
|
||||||
|
|
||||||
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath2)));
|
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath2)));
|
||||||
|
|
||||||
watcher.removeIds({id2});
|
watcher.removeIds({id3.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemoveNoPathSecondTime)
|
TEST_F(ClangPathWatcher, RemoveNoPathSecondTime)
|
||||||
{
|
{
|
||||||
watcher.updateIdPaths(
|
watcher.updateIdPaths(
|
||||||
{{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
|
{{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
|
||||||
watcher.removeIds({id2});
|
watcher.removeIds({id2.id});
|
||||||
|
|
||||||
EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)).Times(0);
|
EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)).Times(0);
|
||||||
|
|
||||||
watcher.removeIds({id2});
|
watcher.removeIds({id2.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
|
TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
|
||||||
@@ -315,7 +320,7 @@ TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
|
|||||||
|
|
||||||
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath, directoryPath2)));
|
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath, directoryPath2)));
|
||||||
|
|
||||||
watcher.removeIds({id1, id2, id3});
|
watcher.removeIds({id1.id, id2.id, id3.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
|
TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
|
||||||
@@ -325,7 +330,7 @@ TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
|
|||||||
|
|
||||||
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath)));
|
EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath)));
|
||||||
|
|
||||||
watcher.removeIds({id1, id2});
|
watcher.removeIds({id1.id, id2.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ClangPathWatcher, NotAnymoreWatchedEntriesWithId)
|
TEST_F(ClangPathWatcher, NotAnymoreWatchedEntriesWithId)
|
||||||
@@ -349,13 +354,14 @@ TEST_F(ClangPathWatcher, RemoveUnusedEntries)
|
|||||||
TEST_F(ClangPathWatcher, TwoNotifyFileChanges)
|
TEST_F(ClangPathWatcher, TwoNotifyFileChanges)
|
||||||
{
|
{
|
||||||
watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2]}},
|
watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2]}},
|
||||||
{id2, {pathIds[0], pathIds[1], pathIds[3]}},
|
{id2, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}},
|
||||||
{id3, {pathIds[4]}}});
|
{id3, {pathIds[4]}}});
|
||||||
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2));
|
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2));
|
||||||
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[1]))).WillByDefault(Return(2));
|
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[1]))).WillByDefault(Return(2));
|
||||||
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[3]))).WillByDefault(Return(2));
|
ON_CALL(mockFileSystem, lastModified(Eq(pathIds[3]))).WillByDefault(Return(2));
|
||||||
|
|
||||||
EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id1, id2)));
|
EXPECT_CALL(notifier,
|
||||||
|
pathsWithIdsChanged(ElementsAre(IdPaths{id1, {1, 2}}, IdPaths{id2, {1, 2, 4}})));
|
||||||
|
|
||||||
mockQFileSytemWatcher.directoryChanged(directoryPath);
|
mockQFileSytemWatcher.directoryChanged(directoryPath);
|
||||||
mockQFileSytemWatcher.directoryChanged(directoryPath2);
|
mockQFileSytemWatcher.directoryChanged(directoryPath2);
|
||||||
|
@@ -52,8 +52,8 @@ public:
|
|||||||
CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; }
|
CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClangBackEnd::PchTask emptyProjectInfo{0, {}, {}, {}, {}, {}, {}, {}};
|
ClangBackEnd::PchTask emptyProjectInfo{0, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
|
||||||
ClangBackEnd::PchTask cppProjectInfo{1, {}, {}, {}, {}, {}, {}, {}};
|
ClangBackEnd::PchTask cppProjectInfo{1, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@@ -359,9 +359,8 @@ std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry)
|
|||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry)
|
std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry)
|
||||||
{
|
{
|
||||||
out << "("
|
out << "(" << entry.directoryPathId << ", " << entry.filePathId << ", " << entry.id << ", "
|
||||||
<< entry.id << ", "
|
<< entry.lastModified << ", "
|
||||||
<< entry.filePathId
|
|
||||||
<< ")";
|
<< ")";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -1290,6 +1289,17 @@ std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths)
|
|||||||
{
|
{
|
||||||
return out << "(" << pchPaths.projectPchPath << ", " << pchPaths.systemPchPath << ")";
|
return out << "(" << pchPaths.projectPchPath << ", " << pchPaths.systemPchPath << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ProjectChunkId &chunk)
|
||||||
|
{
|
||||||
|
return out << "(" << chunk.id << ", " << typeToString(chunk.sourceType) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const DirectoryPathId &id)
|
||||||
|
{
|
||||||
|
return out << id.directoryPathId;
|
||||||
|
}
|
||||||
|
|
||||||
void PrintTo(const FilePath &filePath, ::std::ostream *os)
|
void PrintTo(const FilePath &filePath, ::std::ostream *os)
|
||||||
{
|
{
|
||||||
*os << filePath;
|
*os << filePath;
|
||||||
|
@@ -200,6 +200,8 @@ struct ArgumentsEntry;
|
|||||||
class ProjectPartContainer;
|
class ProjectPartContainer;
|
||||||
class ProjectPartId;
|
class ProjectPartId;
|
||||||
class PchPaths;
|
class PchPaths;
|
||||||
|
class ProjectChunkId;
|
||||||
|
class DirectoryPathId;
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
|
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
|
||||||
std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
|
std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
|
||||||
@@ -293,6 +295,8 @@ std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry);
|
|||||||
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
|
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
|
||||||
std::ostream &operator<<(std::ostream &out, const ProjectPartId &projectPathId);
|
std::ostream &operator<<(std::ostream &out, const ProjectPartId &projectPathId);
|
||||||
std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths);
|
std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths);
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ProjectChunkId &chunk);
|
||||||
|
std::ostream &operator<<(std::ostream &out, const DirectoryPathId &id);
|
||||||
|
|
||||||
void PrintTo(const FilePath &filePath, ::std::ostream *os);
|
void PrintTo(const FilePath &filePath, ::std::ostream *os);
|
||||||
void PrintTo(const FilePathView &filePathView, ::std::ostream *os);
|
void PrintTo(const FilePathView &filePathView, ::std::ostream *os);
|
||||||
|
@@ -53,5 +53,16 @@ public:
|
|||||||
void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId));
|
void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId));
|
||||||
MOCK_CONST_METHOD1(fetchPchSources,
|
MOCK_CONST_METHOD1(fetchPchSources,
|
||||||
ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId));
|
ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId));
|
||||||
|
MOCK_CONST_METHOD1(fetchSources,
|
||||||
|
ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId));
|
||||||
|
MOCK_METHOD2(insertOrUpdateIndexingTimeStamps,
|
||||||
|
void(const ClangBackEnd::FilePathIds &filePathIds,
|
||||||
|
ClangBackEnd::TimeStamp indexingTimeStamp));
|
||||||
|
MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &));
|
||||||
|
MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps());
|
||||||
|
MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps,
|
||||||
|
ClangBackEnd::SourceTimeStamps(ClangBackEnd::FilePathId sourcePathId));
|
||||||
|
MOCK_CONST_METHOD1(fetchDependentSourceIds,
|
||||||
|
ClangBackEnd::FilePathIds(const ClangBackEnd::FilePathIds &sourcePathIds));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
class MockClangPathWatcherNotifier : public ClangBackEnd::ClangPathWatcherNotifier
|
class MockClangPathWatcherNotifier : public ClangBackEnd::ClangPathWatcherNotifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD1(pathsWithIdsChanged, void(const ClangBackEnd::ProjectPartIds &ids));
|
MOCK_METHOD1(pathsWithIdsChanged, void(const std::vector<ClangBackEnd::IdPaths> &idPaths));
|
||||||
|
|
||||||
MOCK_METHOD1(pathsChanged,
|
MOCK_METHOD1(pathsChanged,
|
||||||
void (const ClangBackEnd::FilePathIds &filePathIds));
|
void (const ClangBackEnd::FilePathIds &filePathIds));
|
||||||
|
@@ -37,11 +37,4 @@ public:
|
|||||||
MOCK_METHOD2(addSymbolsAndSourceLocations,
|
MOCK_METHOD2(addSymbolsAndSourceLocations,
|
||||||
void(const ClangBackEnd::SymbolEntries &symbolEentries,
|
void(const ClangBackEnd::SymbolEntries &symbolEentries,
|
||||||
const ClangBackEnd::SourceLocationEntries &sourceLocations));
|
const ClangBackEnd::SourceLocationEntries &sourceLocations));
|
||||||
MOCK_METHOD2(insertOrUpdateIndexingTimeStamps,
|
|
||||||
void(const FilePathIds &filePathIds, ClangBackEnd::TimeStamp indexingTimeStamp));
|
|
||||||
MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &));
|
|
||||||
MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps());
|
|
||||||
MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps,
|
|
||||||
ClangBackEnd::SourceTimeStamps(ClangBackEnd::FilePathId sourcePathId));
|
|
||||||
MOCK_CONST_METHOD1(fetchDependentSourceIds, FilePathIds(const FilePathIds &sourcePathIds));
|
|
||||||
};
|
};
|
||||||
|
@@ -34,12 +34,13 @@
|
|||||||
#include "mockpchmanagerclient.h"
|
#include "mockpchmanagerclient.h"
|
||||||
#include "testenvironment.h"
|
#include "testenvironment.h"
|
||||||
|
|
||||||
#include <refactoringdatabaseinitializer.h>
|
|
||||||
#include <filepathcaching.h>
|
#include <filepathcaching.h>
|
||||||
#include <generatedfiles.h>
|
#include <generatedfiles.h>
|
||||||
#include <pchcreator.h>
|
#include <pchcreator.h>
|
||||||
#include <precompiledheadersupdatedmessage.h>
|
#include <precompiledheadersupdatedmessage.h>
|
||||||
#include <progressmessage.h>
|
#include <progressmessage.h>
|
||||||
|
#include <refactoringdatabaseinitializer.h>
|
||||||
|
#include <updateprojectpartsmessage.h>
|
||||||
|
|
||||||
#include <sqlitedatabase.h>
|
#include <sqlitedatabase.h>
|
||||||
|
|
||||||
@@ -55,12 +56,14 @@ using ClangBackEnd::GeneratedFiles;
|
|||||||
using ClangBackEnd::IdPaths;
|
using ClangBackEnd::IdPaths;
|
||||||
using ClangBackEnd::IncludeSearchPathType;
|
using ClangBackEnd::IncludeSearchPathType;
|
||||||
using ClangBackEnd::PchTask;
|
using ClangBackEnd::PchTask;
|
||||||
|
using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
|
||||||
|
using ClangBackEnd::ProjectChunkId;
|
||||||
|
using ClangBackEnd::ProjectPartContainer;
|
||||||
using ClangBackEnd::ProjectPartPch;
|
using ClangBackEnd::ProjectPartPch;
|
||||||
using ClangBackEnd::SourceEntries;
|
using ClangBackEnd::SourceEntries;
|
||||||
using ClangBackEnd::SourceEntry;
|
using ClangBackEnd::SourceEntry;
|
||||||
using ClangBackEnd::SourceType;
|
using ClangBackEnd::SourceType;
|
||||||
using ClangBackEnd::V2::FileContainer;
|
using ClangBackEnd::V2::FileContainer;
|
||||||
using ClangBackEnd::ProjectPartContainer;
|
|
||||||
|
|
||||||
using Utils::PathString;
|
using Utils::PathString;
|
||||||
using Utils::SmallString;
|
using Utils::SmallString;
|
||||||
@@ -91,6 +94,13 @@ protected:
|
|||||||
return creator.filePathCache().filePathId(path);
|
return creator.filePathCache().filePathId(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePathIds sorted(FilePathIds &&filePathIds)
|
||||||
|
{
|
||||||
|
std::sort(filePathIds.begin(), filePathIds.end());
|
||||||
|
|
||||||
|
return std::move(filePathIds);
|
||||||
|
}
|
||||||
|
|
||||||
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};
|
||||||
@@ -111,14 +121,19 @@ protected:
|
|||||||
mockBuildDependenciesStorage};
|
mockBuildDependenciesStorage};
|
||||||
PchTask pchTask1{
|
PchTask pchTask1{
|
||||||
1,
|
1,
|
||||||
{id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
sorted({id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")},
|
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")}),
|
||||||
{id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
sorted({id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
id(TESTDATA_DIR "/builddependencycollector/system/system2.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
|
id(generatedFilePath)}),
|
||||||
id(generatedFilePath),
|
sorted({id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||||
id(main2Path)},
|
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
|
||||||
|
id(generatedFilePath)}),
|
||||||
|
sorted({id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||||
|
id(generatedFilePath)}),
|
||||||
|
sorted({id(main2Path), id(generatedFilePath)}),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
@@ -213,15 +228,34 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess)
|
|||||||
{
|
{
|
||||||
creator.generatePch(std::move(pchTask1));
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(id(main2Path)))))));
|
||||||
|
|
||||||
EXPECT_CALL(mockClangPathWatcher,
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
updateIdPaths(ElementsAre(AllOf(
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
Field(&ClangBackEnd::IdPaths::id, 1),
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
|
||||||
Field(&ClangBackEnd::IdPaths::filePathIds,
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
UnorderedElementsAre(
|
UnorderedElementsAre(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
|
EXPECT_CALL(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp")))))));
|
mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
|
||||||
|
|
||||||
creator.doInMainThreadAfterFinished();
|
creator.doInMainThreadAfterFinished();
|
||||||
}
|
}
|
||||||
@@ -232,15 +266,34 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterFail)
|
|||||||
pchTask1.projectIncludeSearchPaths = {};
|
pchTask1.projectIncludeSearchPaths = {};
|
||||||
creator.generatePch(std::move(pchTask1));
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(id(main2Path)))))));
|
||||||
|
|
||||||
EXPECT_CALL(mockClangPathWatcher,
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
updateIdPaths(ElementsAre(AllOf(
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
Field(&ClangBackEnd::IdPaths::id, 1),
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
|
||||||
Field(&ClangBackEnd::IdPaths::filePathIds,
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
UnorderedElementsAre(
|
UnorderedElementsAre(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
|
EXPECT_CALL(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp")))))));
|
mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
|
||||||
|
|
||||||
creator.doInMainThreadAfterFinished();
|
creator.doInMainThreadAfterFinished();
|
||||||
}
|
}
|
||||||
@@ -282,15 +335,40 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
|
|||||||
ASSERT_FALSE(creator.projectPartPch().isValid());
|
ASSERT_FALSE(creator.projectPartPch().isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchCreatorVerySlowTest, SourcesCleared)
|
TEST_F(PchCreatorVerySlowTest, WatchedSystemIncludesCleared)
|
||||||
{
|
{
|
||||||
creator.generatePch(std::move(pchTask1));
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
creator.clear();
|
creator.clear();
|
||||||
|
|
||||||
ASSERT_THAT(creator.sources(), IsEmpty());
|
ASSERT_THAT(creator.watchedSystemIncludes(), IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PchCreatorVerySlowTest, WatchedProjectIncludesCleared)
|
||||||
|
{
|
||||||
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
|
creator.clear();
|
||||||
|
|
||||||
|
ASSERT_THAT(creator.watchedProjectIncludes(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchCreatorVerySlowTest, WatchedUserIncludesCleared)
|
||||||
|
{
|
||||||
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
|
creator.clear();
|
||||||
|
|
||||||
|
ASSERT_THAT(creator.watchedUserIncludes(), IsEmpty());
|
||||||
|
}
|
||||||
|
TEST_F(PchCreatorVerySlowTest, WatchedSourcesCleared)
|
||||||
|
{
|
||||||
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
|
creator.clear();
|
||||||
|
|
||||||
|
ASSERT_THAT(creator.watchedSources(), IsEmpty());
|
||||||
|
}
|
||||||
TEST_F(PchCreatorVerySlowTest, ClangToolCleared)
|
TEST_F(PchCreatorVerySlowTest, ClangToolCleared)
|
||||||
{
|
{
|
||||||
creator.generatePch(std::move(pchTask1));
|
creator.generatePch(std::move(pchTask1));
|
||||||
@@ -306,6 +384,9 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask
|
|||||||
0,
|
0,
|
||||||
{id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")},
|
{id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")},
|
||||||
{},
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
{{"DEFINE", "1", 1}},
|
{{"DEFINE", "1", 1}},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
@@ -336,20 +417,37 @@ TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls)
|
|||||||
{
|
{
|
||||||
pchTask1.includes = {};
|
pchTask1.includes = {};
|
||||||
creator.generatePch(std::move(pchTask1));
|
creator.generatePch(std::move(pchTask1));
|
||||||
|
|
||||||
EXPECT_CALL(mockPchManagerClient,
|
EXPECT_CALL(mockPchManagerClient,
|
||||||
precompiledHeadersUpdated(
|
precompiledHeadersUpdated(
|
||||||
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
|
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
|
||||||
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
|
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(id(main2Path)))))));
|
||||||
EXPECT_CALL(mockClangPathWatcher,
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
updateIdPaths(ElementsAre(AllOf(
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
Field(&ClangBackEnd::IdPaths::id, 1),
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
|
||||||
Field(&ClangBackEnd::IdPaths::filePathIds,
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
UnorderedElementsAre(
|
UnorderedElementsAre(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
|
||||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
|
EXPECT_CALL(
|
||||||
id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp")))))));
|
mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(
|
||||||
|
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
|
||||||
|
EXPECT_CALL(mockClangPathWatcher,
|
||||||
|
updateIdPaths(ElementsAre(AllOf(
|
||||||
|
Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
|
||||||
|
Field(&ClangBackEnd::IdPaths::filePathIds,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
|
||||||
|
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1)));
|
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1)));
|
||||||
|
|
||||||
creator.doInMainThreadAfterFinished();
|
creator.doInMainThreadAfterFinished();
|
||||||
|
@@ -25,11 +25,12 @@
|
|||||||
|
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
|
#include "mockbuilddependenciesstorage.h"
|
||||||
#include "mockclangpathwatcher.h"
|
#include "mockclangpathwatcher.h"
|
||||||
|
#include "mockgeneratedfiles.h"
|
||||||
#include "mockpchmanagerclient.h"
|
#include "mockpchmanagerclient.h"
|
||||||
#include "mockpchtaskgenerator.h"
|
#include "mockpchtaskgenerator.h"
|
||||||
#include "mockprojectpartsmanager.h"
|
#include "mockprojectpartsmanager.h"
|
||||||
#include "mockgeneratedfiles.h"
|
|
||||||
|
|
||||||
#include <filepathcaching.h>
|
#include <filepathcaching.h>
|
||||||
#include <pchmanagerserver.h>
|
#include <pchmanagerserver.h>
|
||||||
@@ -42,12 +43,13 @@
|
|||||||
#include <updateprojectpartsmessage.h>
|
#include <updateprojectpartsmessage.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using Utils::PathString;
|
using ClangBackEnd::FilePathId;
|
||||||
using Utils::SmallString;
|
|
||||||
using ClangBackEnd::V2::FileContainer;
|
|
||||||
using ClangBackEnd::V2::FileContainers;
|
|
||||||
using ClangBackEnd::ProjectPartContainer;
|
using ClangBackEnd::ProjectPartContainer;
|
||||||
using ClangBackEnd::ProjectPartContainers;
|
using ClangBackEnd::ProjectPartContainers;
|
||||||
|
using ClangBackEnd::V2::FileContainer;
|
||||||
|
using ClangBackEnd::V2::FileContainers;
|
||||||
|
using Utils::PathString;
|
||||||
|
using Utils::SmallString;
|
||||||
using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts;
|
using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts;
|
||||||
|
|
||||||
class PchManagerServer : public ::testing::Test
|
class PchManagerServer : public ::testing::Test
|
||||||
@@ -71,21 +73,27 @@ protected:
|
|||||||
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
||||||
NiceMock<MockProjectPartsManager> mockProjectPartsManager;
|
NiceMock<MockProjectPartsManager> mockProjectPartsManager;
|
||||||
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
|
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
|
||||||
|
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
|
||||||
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};
|
||||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
||||||
mockPchTaskGenerator,
|
mockPchTaskGenerator,
|
||||||
mockProjectPartsManager,
|
mockProjectPartsManager,
|
||||||
mockGeneratedFiles};
|
mockGeneratedFiles,
|
||||||
|
mockBuildDependenciesStorage};
|
||||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||||
ClangBackEnd::ProjectPartId projectPartId1{1};
|
ClangBackEnd::ProjectPartId projectPartId1{1};
|
||||||
ClangBackEnd::ProjectPartId projectPartId2{2};
|
ClangBackEnd::ProjectPartId projectPartId2{2};
|
||||||
|
ClangBackEnd::ProjectPartId projectPartId3{3};
|
||||||
|
ClangBackEnd::ProjectPartId projectPartId4{4};
|
||||||
|
ClangBackEnd::ProjectPartId projectPartId5{5};
|
||||||
|
ClangBackEnd::ProjectPartId projectPartId6{6};
|
||||||
PathString main1Path = TESTDATA_DIR "/BuildDependencyCollector_main3.cpp";
|
PathString main1Path = TESTDATA_DIR "/BuildDependencyCollector_main3.cpp";
|
||||||
PathString main2Path = TESTDATA_DIR "/BuildDependencyCollector_main2.cpp";
|
PathString main2Path = TESTDATA_DIR "/BuildDependencyCollector_main2.cpp";
|
||||||
PathString header1Path = TESTDATA_DIR "/BuildDependencyCollector_header1.h";
|
PathString header1Path = TESTDATA_DIR "/BuildDependencyCollector_header1.h";
|
||||||
PathString header2Path = TESTDATA_DIR "/BuildDependencyCollector_header2.h";
|
PathString header2Path = TESTDATA_DIR "/BuildDependencyCollector_header2.h";
|
||||||
ClangBackEnd::IdPaths idPath{projectPartId1, {1, 2}};
|
ClangBackEnd::IdPaths idPath{{projectPartId1, ClangBackEnd::SourceType::Source}, {1, 2}};
|
||||||
ProjectPartContainer projectPart1{
|
ProjectPartContainer projectPart1{
|
||||||
projectPartId1,
|
projectPartId1,
|
||||||
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||||
@@ -108,6 +116,50 @@ protected:
|
|||||||
Utils::Language::C,
|
Utils::Language::C,
|
||||||
Utils::LanguageVersion::C11,
|
Utils::LanguageVersion::C11,
|
||||||
Utils::LanguageExtension::All};
|
Utils::LanguageExtension::All};
|
||||||
|
ProjectPartContainer projectPart3{
|
||||||
|
projectPartId3,
|
||||||
|
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||||
|
{{"DEFINE", "1", 1}},
|
||||||
|
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
|
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
|
{id(header1Path)},
|
||||||
|
{id(main1Path)},
|
||||||
|
Utils::Language::C,
|
||||||
|
Utils::LanguageVersion::C11,
|
||||||
|
Utils::LanguageExtension::All};
|
||||||
|
ProjectPartContainer projectPart4{
|
||||||
|
projectPartId4,
|
||||||
|
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||||
|
{{"DEFINE", "1", 1}},
|
||||||
|
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
|
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
|
{id(header2Path)},
|
||||||
|
{id(main2Path)},
|
||||||
|
Utils::Language::C,
|
||||||
|
Utils::LanguageVersion::C11,
|
||||||
|
Utils::LanguageExtension::All};
|
||||||
|
ProjectPartContainer projectPart5{
|
||||||
|
projectPartId5,
|
||||||
|
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||||
|
{{"DEFINE", "1", 1}},
|
||||||
|
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
|
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
|
{id(header1Path)},
|
||||||
|
{id(main1Path)},
|
||||||
|
Utils::Language::C,
|
||||||
|
Utils::LanguageVersion::C11,
|
||||||
|
Utils::LanguageExtension::All};
|
||||||
|
ProjectPartContainer projectPart6{
|
||||||
|
projectPartId6,
|
||||||
|
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||||
|
{{"DEFINE", "1", 1}},
|
||||||
|
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||||
|
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||||
|
{id(header2Path)},
|
||||||
|
{id(main2Path)},
|
||||||
|
Utils::Language::C,
|
||||||
|
Utils::LanguageVersion::C11,
|
||||||
|
Utils::LanguageExtension::All};
|
||||||
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
|
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
|
||||||
std::vector<ProjectPartContainer> projectParts1{projectPart1};
|
std::vector<ProjectPartContainer> projectParts1{projectPart1};
|
||||||
std::vector<ProjectPartContainer> projectParts2{projectPart2};
|
std::vector<ProjectPartContainer> projectParts2{projectPart2};
|
||||||
@@ -169,19 +221,68 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
|
|||||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
|
||||||
mockPchTaskGenerator,
|
mockPchTaskGenerator,
|
||||||
mockProjectPartsManager,
|
mockProjectPartsManager,
|
||||||
mockGeneratedFiles};
|
mockGeneratedFiles,
|
||||||
|
mockBuildDependenciesStorage};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
|
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
|
||||||
{
|
{
|
||||||
server.updateProjectParts(
|
server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{
|
||||||
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
|
{projectPart1, projectPart2, projectPart3, projectPart4, projectPart5, projectPart6},
|
||||||
|
{"toolChainArgument"}});
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsManager, projects(ElementsAre(projectPart1.projectPartId)))
|
EXPECT_CALL(mockProjectPartsManager,
|
||||||
.WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}}));
|
projects(ElementsAre(projectPart1.projectPartId,
|
||||||
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
|
projectPart2.projectPartId,
|
||||||
|
projectPart4.projectPartId,
|
||||||
|
projectPart5.projectPartId)))
|
||||||
|
.WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{
|
||||||
|
{projectPart1, projectPart2, projectPart4, projectPart5}}));
|
||||||
|
EXPECT_CALL(mockPchTaskGenerator,
|
||||||
|
addProjectParts(ElementsAre(projectPart1, projectPart2, projectPart4, projectPart5),
|
||||||
|
ElementsAre("toolChainArgument")));
|
||||||
|
|
||||||
server.pathsWithIdsChanged({projectPartId1});
|
server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::TopProjectInclude}, {}},
|
||||||
|
{{projectPartId2, ClangBackEnd::SourceType::TopSystemInclude}, {}},
|
||||||
|
{{projectPartId3, ClangBackEnd::SourceType::UserInclude}, {}},
|
||||||
|
{{projectPartId4, ClangBackEnd::SourceType::ProjectInclude}, {}},
|
||||||
|
{{projectPartId5, ClangBackEnd::SourceType::SystemInclude}, {}},
|
||||||
|
{{projectPartId6, ClangBackEnd::SourceType::Source}, {}}});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchManagerServer, DontUpdateProjectPartQueueByPathIdsIfItUserFile)
|
||||||
|
{
|
||||||
|
server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{{projectPart1, projectPart2},
|
||||||
|
{"toolChainArgument"}});
|
||||||
|
|
||||||
|
EXPECT_CALL(mockProjectPartsManager, projects(_)).Times(0);
|
||||||
|
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
|
||||||
|
|
||||||
|
server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::UserInclude}, {}},
|
||||||
|
{{projectPartId2, ClangBackEnd::SourceType::Source}, {}}});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchManagerServer, ShortcutPrecompiledHeaderGenerationForUserIncludesAndSources)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockPchManagerClient,
|
||||||
|
precompiledHeadersUpdated(
|
||||||
|
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
|
||||||
|
UnorderedElementsAre(projectPartId3, projectPartId6))));
|
||||||
|
|
||||||
|
server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::TopProjectInclude}, {}},
|
||||||
|
{{projectPartId2, ClangBackEnd::SourceType::TopSystemInclude}, {}},
|
||||||
|
{{projectPartId3, ClangBackEnd::SourceType::UserInclude}, {}},
|
||||||
|
{{projectPartId4, ClangBackEnd::SourceType::ProjectInclude}, {}},
|
||||||
|
{{projectPartId5, ClangBackEnd::SourceType::SystemInclude}, {}},
|
||||||
|
{{projectPartId6, ClangBackEnd::SourceType::Source}, {}}});
|
||||||
|
}
|
||||||
|
TEST_F(PchManagerServer, ResetTimeStampForChangedFilesInDatabase)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockBuildDependenciesStorage,
|
||||||
|
insertOrUpdateIndexingTimeStamps(ElementsAre(FilePathId{1}, FilePathId{3}, FilePathId{5}),
|
||||||
|
TypedEq<ClangBackEnd::TimeStamp>(0)));
|
||||||
|
|
||||||
|
server.pathsChanged({1, 3, 5});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, SetPchCreationProgress)
|
TEST_F(PchManagerServer, SetPchCreationProgress)
|
||||||
@@ -214,7 +315,7 @@ TEST_F(PchManagerServer, RemoveToolChainsArguments)
|
|||||||
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
|
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
|
||||||
server.removeProjectParts(removeProjectPartsMessage.clone());
|
server.removeProjectParts(removeProjectPartsMessage.clone());
|
||||||
|
|
||||||
server.pathsWithIdsChanged({projectPart1.projectPartId});
|
server.pathsWithIdsChanged({{{projectPart1.projectPartId, ClangBackEnd::SourceType::Source}, {}}});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid)
|
TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid)
|
||||||
|
@@ -84,7 +84,8 @@ protected:
|
|||||||
{2, SourceType::UserInclude, 1},
|
{2, SourceType::UserInclude, 1},
|
||||||
{3, SourceType::TopProjectInclude, 1},
|
{3, SourceType::TopProjectInclude, 1},
|
||||||
{4, SourceType::SystemInclude, 1},
|
{4, SourceType::SystemInclude, 1},
|
||||||
{5, SourceType::TopSystemInclude, 1}};
|
{5, SourceType::TopSystemInclude, 1},
|
||||||
|
{6, SourceType::Source, 1}};
|
||||||
UsedMacros usedMacros{{"LIANG", 0},{"YI", 1}, {"ER", 2}, {"SAN", 3}, {"SE", 4}, {"WU", 5}};
|
UsedMacros usedMacros{{"LIANG", 0},{"YI", 1}, {"ER", 2}, {"SAN", 3}, {"SE", 4}, {"WU", 5}};
|
||||||
BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}};
|
BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}};
|
||||||
};
|
};
|
||||||
@@ -100,7 +101,10 @@ TEST_F(PchTaskGenerator, AddProjectParts)
|
|||||||
Field(&PchTaskSet::system,
|
Field(&PchTaskSet::system,
|
||||||
AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})),
|
AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})),
|
||||||
Field(&PchTask::includes, ElementsAre(5)),
|
Field(&PchTask::includes, ElementsAre(5)),
|
||||||
Field(&PchTask::sources, IsEmpty()),
|
Field(&PchTask::watchedSystemIncludes, IsEmpty()),
|
||||||
|
Field(&PchTask::watchedProjectIncludes, IsEmpty()),
|
||||||
|
Field(&PchTask::watchedUserIncludes, IsEmpty()),
|
||||||
|
Field(&PchTask::watchedUserSources, IsEmpty()),
|
||||||
Field(&PchTask::compilerMacros,
|
Field(&PchTask::compilerMacros,
|
||||||
ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})),
|
ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})),
|
||||||
Field(&PchTask::systemIncludeSearchPaths,
|
Field(&PchTask::systemIncludeSearchPaths,
|
||||||
@@ -117,7 +121,10 @@ TEST_F(PchTaskGenerator, AddProjectParts)
|
|||||||
&PchTaskSet::project,
|
&PchTaskSet::project,
|
||||||
AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})),
|
AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})),
|
||||||
Field(&PchTask::includes, ElementsAre(3)),
|
Field(&PchTask::includes, ElementsAre(3)),
|
||||||
Field(&PchTask::sources, ElementsAre(1, 3, 4, 5)),
|
Field(&PchTask::watchedSystemIncludes, ElementsAre(4, 5)),
|
||||||
|
Field(&PchTask::watchedProjectIncludes, ElementsAre(1, 3)),
|
||||||
|
Field(&PchTask::watchedUserIncludes, ElementsAre(2)),
|
||||||
|
Field(&PchTask::watchedUserSources, ElementsAre(6)),
|
||||||
Field(&PchTask::compilerMacros,
|
Field(&PchTask::compilerMacros,
|
||||||
ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
|
ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
|
||||||
Field(&PchTask::systemIncludeSearchPaths,
|
Field(&PchTask::systemIncludeSearchPaths,
|
||||||
|
@@ -67,6 +67,9 @@ protected:
|
|||||||
PchTask systemTask1{1,
|
PchTask systemTask1{1,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
|
{2, 3},
|
||||||
|
{3, 4},
|
||||||
|
{6, 7},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{{"LIANG", 0}, {"YI", 1}},
|
{{"LIANG", 0}, {"YI", 1}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -75,6 +78,9 @@ protected:
|
|||||||
PchTask systemTask2{2,
|
PchTask systemTask2{2,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
|
{2, 3},
|
||||||
|
{3, 4},
|
||||||
|
{6, 7},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{{"LIANG", 0}, {"YI", 1}},
|
{{"LIANG", 0}, {"YI", 1}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -83,6 +89,9 @@ protected:
|
|||||||
PchTask systemTask2b{2,
|
PchTask systemTask2b{2,
|
||||||
{3, 4},
|
{3, 4},
|
||||||
{3, 4},
|
{3, 4},
|
||||||
|
{5, 6},
|
||||||
|
{4, 7},
|
||||||
|
{8, 9},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{{"LIANG", 0}, {"YI", 1}},
|
{{"LIANG", 0}, {"YI", 1}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -91,6 +100,9 @@ protected:
|
|||||||
PchTask systemTask3{3,
|
PchTask systemTask3{3,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
|
{2, 3},
|
||||||
|
{3, 4},
|
||||||
|
{6, 7},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{{"LIANG", 0}, {"YI", 1}},
|
{{"LIANG", 0}, {"YI", 1}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -99,6 +111,9 @@ protected:
|
|||||||
PchTask projectTask1{1,
|
PchTask projectTask1{1,
|
||||||
{11, 12},
|
{11, 12},
|
||||||
{11, 12},
|
{11, 12},
|
||||||
|
{12, 13},
|
||||||
|
{13, 14},
|
||||||
|
{16, 17},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{{"ER", 2}, {"SAN", 3}},
|
{{"ER", 2}, {"SAN", 3}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -107,6 +122,9 @@ protected:
|
|||||||
PchTask projectTask2{2,
|
PchTask projectTask2{2,
|
||||||
{11, 12},
|
{11, 12},
|
||||||
{11, 12},
|
{11, 12},
|
||||||
|
{12, 13},
|
||||||
|
{13, 14},
|
||||||
|
{16, 17},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{{"ER", 2}, {"SAN", 3}},
|
{{"ER", 2}, {"SAN", 3}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -115,6 +133,9 @@ protected:
|
|||||||
PchTask projectTask2b{2,
|
PchTask projectTask2b{2,
|
||||||
{21, 22},
|
{21, 22},
|
||||||
{11, 12},
|
{11, 12},
|
||||||
|
{22, 23},
|
||||||
|
{23, 24},
|
||||||
|
{26, 27},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{{"ER", 2}, {"SAN", 3}},
|
{{"ER", 2}, {"SAN", 3}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -123,6 +144,9 @@ protected:
|
|||||||
PchTask projectTask3{3,
|
PchTask projectTask3{3,
|
||||||
{21, 22},
|
{21, 22},
|
||||||
{21, 22},
|
{21, 22},
|
||||||
|
{22, 23},
|
||||||
|
{23, 24},
|
||||||
|
{26, 27},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{{"ER", 2}, {"SAN", 3}},
|
{{"ER", 2}, {"SAN", 3}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -131,6 +155,9 @@ protected:
|
|||||||
PchTask systemTask4{{1, 3},
|
PchTask systemTask4{{1, 3},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
|
{2, 3},
|
||||||
|
{3, 4},
|
||||||
|
{5, 8},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{{"LIANG", 0}, {"YI", 1}},
|
{{"LIANG", 0}, {"YI", 1}},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
|
@@ -54,7 +54,10 @@ protected:
|
|||||||
ClangBackEnd::PchTasksMerger merger{mockPchTaskQueue};
|
ClangBackEnd::PchTasksMerger merger{mockPchTaskQueue};
|
||||||
PchTask systemTask1{1,
|
PchTask systemTask1{1,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2, 3},
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||||
{"YI", "LIANG"},
|
{"YI", "LIANG"},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -66,6 +69,9 @@ protected:
|
|||||||
PchTask projectTask1{1,
|
PchTask projectTask1{1,
|
||||||
{11, 12},
|
{11, 12},
|
||||||
{11, 12},
|
{11, 12},
|
||||||
|
{21, 22},
|
||||||
|
{31, 32},
|
||||||
|
{41, 42},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{"ER", "SAN"},
|
{"ER", "SAN"},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -75,7 +81,10 @@ protected:
|
|||||||
{"/to/path2", 2, IncludeSearchPathType::User}}};
|
{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||||
PchTask systemTask2{2,
|
PchTask systemTask2{2,
|
||||||
{11, 12},
|
{11, 12},
|
||||||
{11, 12, 13},
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{"ER", "SAN"},
|
{"ER", "SAN"},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -87,6 +96,9 @@ protected:
|
|||||||
PchTask projectTask2{2,
|
PchTask projectTask2{2,
|
||||||
{11, 12},
|
{11, 12},
|
||||||
{11, 12},
|
{11, 12},
|
||||||
|
{21, 22},
|
||||||
|
{31, 32},
|
||||||
|
{41, 42},
|
||||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||||
{"ER", "SAN"},
|
{"ER", "SAN"},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -97,7 +109,10 @@ protected:
|
|||||||
{"/to/path2", 2, IncludeSearchPathType::User}}};
|
{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||||
PchTask systemTask3{3,
|
PchTask systemTask3{3,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
{1, 2},
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
{{"YI", "2", 1}, {"SAN", "3", 3}},
|
{{"YI", "2", 1}, {"SAN", "3", 3}},
|
||||||
{"YI", "LIANG"},
|
{"YI", "LIANG"},
|
||||||
{"--yi"},
|
{"--yi"},
|
||||||
@@ -268,18 +283,25 @@ TEST_F(PchTasksMerger, DontMergeIncludes)
|
|||||||
ASSERT_THAT(systemTask1.includes, ElementsAre(1, 2));
|
ASSERT_THAT(systemTask1.includes, ElementsAre(1, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchTasksMerger, MergeAllIncludes)
|
TEST_F(PchTasksMerger, DontMergeWatchedSystemSources)
|
||||||
{
|
{
|
||||||
Merger::mergePchTasks(systemTask1, systemTask2);
|
Merger::mergePchTasks(systemTask1, systemTask2);
|
||||||
|
|
||||||
ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3, 11, 12, 13));
|
ASSERT_THAT(systemTask1.watchedSystemIncludes, IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchTasksMerger, DontAllMergeIncludes)
|
TEST_F(PchTasksMerger, DontMergeWatchedProjectSources)
|
||||||
{
|
{
|
||||||
Merger::mergePchTasks(systemTask1, systemTask3);
|
Merger::mergePchTasks(systemTask1, systemTask3);
|
||||||
|
|
||||||
ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3));
|
ASSERT_THAT(systemTask1.watchedProjectIncludes, IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTasksMerger, DontMergeWatchedUserSources)
|
||||||
|
{
|
||||||
|
Merger::mergePchTasks(systemTask1, systemTask3);
|
||||||
|
|
||||||
|
ASSERT_THAT(systemTask1.watchedUserSources, IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchTasksMerger, MergeProjectIds)
|
TEST_F(PchTasksMerger, MergeProjectIds)
|
||||||
|
@@ -463,7 +463,6 @@ 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};
|
||||||
Storage storage{database};
|
Storage storage{database};
|
||||||
ClangBackEnd::SymbolStorage<> symbolStorage{database};
|
|
||||||
ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database};
|
ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -505,13 +504,13 @@ TEST_F(ProjectPartsStorageSlow, FetchProjectParts)
|
|||||||
|
|
||||||
TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps)
|
TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps)
|
||||||
{
|
{
|
||||||
symbolStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34);
|
buildDependenciesStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34);
|
||||||
buildDependenciesStorage.insertOrUpdateSourceDependencies(
|
buildDependenciesStorage.insertOrUpdateSourceDependencies(
|
||||||
{{3, 1}, {4, 1}, {1, 2}, {7, 5}, {8, 6}, {6, 5}, {9, 10}});
|
{{3, 1}, {4, 1}, {1, 2}, {7, 5}, {8, 6}, {6, 5}, {9, 10}});
|
||||||
|
|
||||||
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
||||||
|
|
||||||
ASSERT_THAT(symbolStorage.fetchIndexingTimeStamps(),
|
ASSERT_THAT(buildDependenciesStorage.fetchIndexingTimeStamps(),
|
||||||
ElementsAre(SourceTimeStamp{1, 0},
|
ElementsAre(SourceTimeStamp{1, 0},
|
||||||
SourceTimeStamp{2, 0},
|
SourceTimeStamp{2, 0},
|
||||||
SourceTimeStamp{3, 0},
|
SourceTimeStamp{3, 0},
|
||||||
|
@@ -116,11 +116,11 @@ protected:
|
|||||||
.WillByDefault(Return(artefact));
|
.WillByDefault(Return(artefact));
|
||||||
ON_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillByDefault(Return(-1));
|
ON_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillByDefault(Return(-1));
|
||||||
ON_CALL(mockCollector, collectSymbols()).WillByDefault(Return(true));
|
ON_CALL(mockCollector, collectSymbols()).WillByDefault(Return(true));
|
||||||
ON_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds))
|
ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(sourceFileIds))
|
||||||
.WillByDefault(Return(sourceFileIds));
|
.WillByDefault(Return(sourceFileIds));
|
||||||
ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(sourceFileIds[0])))
|
ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(ElementsAre(sourceFileIds[0])))
|
||||||
.WillByDefault(Return(FilePathIds{sourceFileIds[0]}));
|
.WillByDefault(Return(FilePathIds{sourceFileIds[0]}));
|
||||||
ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(main1PathId)))
|
ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(ElementsAre(main1PathId)))
|
||||||
.WillByDefault(Return(FilePathIds{main1PathId}));
|
.WillByDefault(Return(FilePathIds{main1PathId}));
|
||||||
mockCollector.setIsUsed(false);
|
mockCollector.setIsUsed(false);
|
||||||
|
|
||||||
@@ -879,16 +879,16 @@ TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps)
|
|||||||
Utils::LanguageVersion::CXX14,
|
Utils::LanguageVersion::CXX14,
|
||||||
Utils::LanguageExtension::None};
|
Utils::LanguageExtension::None};
|
||||||
|
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId)))
|
EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId)))
|
||||||
.WillOnce(Return(dependentSourceTimeStamps1));
|
.WillOnce(Return(dependentSourceTimeStamps1));
|
||||||
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps1));
|
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps1));
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId)))
|
EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId)))
|
||||||
.WillOnce(Return(dependentSourceTimeStamps2));
|
.WillOnce(Return(dependentSourceTimeStamps2));
|
||||||
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps2));
|
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps2));
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
|
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
|
||||||
EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1));
|
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1));
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses2));
|
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses2));
|
||||||
EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2));
|
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2));
|
||||||
|
|
||||||
indexer.updateProjectParts({projectPart});
|
indexer.updateProjectParts({projectPart});
|
||||||
}
|
}
|
||||||
@@ -917,642 +917,6 @@ TEST_F(SymbolIndexer, DependentSourceAreUpToDate)
|
|||||||
indexer.updateProjectParts({projectPart1});
|
indexer.updateProjectParts({projectPart1});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, SourcesAreWatched)
|
|
||||||
{
|
|
||||||
using ClangBackEnd::IdPaths;
|
|
||||||
InSequence s;
|
|
||||||
FilePathIds sourcePathIds{4, 6, 8};
|
|
||||||
|
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, fetchPchSources(projectPart1.projectPartId))
|
|
||||||
.WillOnce(Return(sourcePathIds));
|
|
||||||
EXPECT_CALL(mockPathWatcher,
|
|
||||||
updateIdPaths(ElementsAre(AllOf(Field(&IdPaths::id, projectPart1.projectPartId),
|
|
||||||
Field(&IdPaths::filePathIds, sourcePathIds)))));
|
|
||||||
|
|
||||||
indexer.updateProjectParts({projectPart1});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, CallSetNotifier)
|
|
||||||
{
|
|
||||||
EXPECT_CALL(mockPathWatcher, setNotifier(_));
|
|
||||||
|
|
||||||
ClangBackEnd::SymbolIndexer indexer{indexerQueue,
|
|
||||||
mockSymbolStorage,
|
|
||||||
mockBuildDependenciesStorage,
|
|
||||||
mockPrecompiledHeaderStorage,
|
|
||||||
mockPathWatcher,
|
|
||||||
filePathCache,
|
|
||||||
fileStatusCache,
|
|
||||||
mockSqliteTransactionBackend,
|
|
||||||
mockProjectPartsStorage,
|
|
||||||
mockModifiedTimeChecker,
|
|
||||||
testEnvironment};
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage)
|
|
||||||
{
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0]));
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[1]));
|
|
||||||
|
|
||||||
indexer.pathsChanged(sourceFileIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathChangedCallsFetchSourcePathIds)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds))
|
|
||||||
.WillOnce(Return(FilePathIds{2, 6, 5}));
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{2}));
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{6}));
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{5}));
|
|
||||||
|
|
||||||
indexer.pathsChanged(sourceFileIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathChangedFetchIncludedIndexingTimeStamps)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
ProjectPartContainer projectPart{1,
|
|
||||||
{"-Wno-pragma-once-outside-header"},
|
|
||||||
{{"BAR", "1", 1}, {"FOO", "1", 2}},
|
|
||||||
Utils::clone(systemIncludeSearchPaths),
|
|
||||||
Utils::clone(projectIncludeSearchPaths),
|
|
||||||
{header1PathId},
|
|
||||||
{main1PathId, main2PathId},
|
|
||||||
Utils::Language::Cxx,
|
|
||||||
Utils::LanguageVersion::CXX14,
|
|
||||||
Utils::LanguageExtension::None};
|
|
||||||
|
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillOnce(Return(FilePathIds{1, 2}));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(1)))
|
|
||||||
.WillOnce(Return(dependentSourceTimeStamps1));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(2)))
|
|
||||||
.WillOnce(Return(dependentSourceTimeStamps2));
|
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses1));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1));
|
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses2));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2));
|
|
||||||
|
|
||||||
indexer.pathsChanged({1, 3});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathChangedFetchesDependentSourceIdsFromStorage)
|
|
||||||
{
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0]));
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[1]));
|
|
||||||
|
|
||||||
indexer.pathsChanged(sourceFileIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(Eq(sourceFileIds[0]),
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols());
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0]))
|
|
||||||
.WillOnce(Return(nullArtefact));
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(_)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector, setFile(_, _)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _)).Times(0);
|
|
||||||
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasNoError)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"}));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/project/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectPch)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"}));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/project/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/system/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectAndSystemPch)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"}));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/project/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/system/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasOnlyError)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"}));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/project/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/system/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsSystemPchPathsAndHasErrorWithProjectPch)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillOnce(Return(ClangBackEnd::PchPaths{{}, "/system/pch"}));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/system/pch"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, PathsChangedCallsGetsNoPchPathsAndHasErrors)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockProjectPartsStorage,
|
|
||||||
fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillOnce(Return(artefact));
|
|
||||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)));
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(sourceFileIds[0],
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"))));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true));
|
|
||||||
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
|
||||||
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader)
|
|
||||||
{
|
|
||||||
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillByDefault(Return(artefact));
|
|
||||||
ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId)))
|
|
||||||
.WillByDefault(Return(pchPaths));
|
|
||||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(Eq(sourceFileIds[0]),
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"),
|
|
||||||
"-Xclang",
|
|
||||||
"-include-pch",
|
|
||||||
"-Xclang",
|
|
||||||
toNativePath("/project/pch"))));
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists)
|
|
||||||
{
|
|
||||||
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0])))
|
|
||||||
.WillByDefault(Return(artefact));
|
|
||||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockCollector,
|
|
||||||
setFile(Eq(sourceFileIds[0]),
|
|
||||||
ElementsAre("clang++",
|
|
||||||
"-w",
|
|
||||||
"-DFOO",
|
|
||||||
"-DNOMINMAX",
|
|
||||||
"-x",
|
|
||||||
"c++",
|
|
||||||
"-std=c++14",
|
|
||||||
"-nostdinc",
|
|
||||||
"-nostdinc++",
|
|
||||||
"-DBAR=1",
|
|
||||||
"-DFOO=1",
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR "/preincludes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/project/includes"),
|
|
||||||
"-I",
|
|
||||||
toNativePath("/other/project/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath(TESTDATA_DIR),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/other/includes"),
|
|
||||||
"-isystem",
|
|
||||||
toNativePath("/includes"))));
|
|
||||||
|
|
||||||
indexer.pathsChanged({sourceFileIds[0]});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, CompilerMacrosAndIncludeSearchPathsAreNotDifferent)
|
TEST_F(SymbolIndexer, CompilerMacrosAndIncludeSearchPathsAreNotDifferent)
|
||||||
{
|
{
|
||||||
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(A<ProjectPartId>()))
|
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(A<ProjectPartId>()))
|
||||||
@@ -1660,7 +1024,8 @@ TEST_F(SymbolIndexer, PathsChangedUpdatesFileStatusCache)
|
|||||||
{
|
{
|
||||||
auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp");
|
auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp");
|
||||||
ON_CALL(mockFileSystem, lastModified(Eq(sourceId))).WillByDefault(Return(65));
|
ON_CALL(mockFileSystem, lastModified(Eq(sourceId))).WillByDefault(Return(65));
|
||||||
ON_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillByDefault(Return(FilePathIds{sourceId}));
|
ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(_))
|
||||||
|
.WillByDefault(Return(FilePathIds{sourceId}));
|
||||||
|
|
||||||
indexer.pathsChanged({sourceId});
|
indexer.pathsChanged({sourceId});
|
||||||
|
|
||||||
|
@@ -69,10 +69,6 @@ protected:
|
|||||||
MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = storage.insertNewLocationsInLocationsStatement;
|
MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = storage.insertNewLocationsInLocationsStatement;
|
||||||
MockSqliteWriteStatement &deleteNewSymbolsTableStatement = storage.deleteNewSymbolsTableStatement;
|
MockSqliteWriteStatement &deleteNewSymbolsTableStatement = storage.deleteNewSymbolsTableStatement;
|
||||||
MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.deleteNewLocationsTableStatement;
|
MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.deleteNewLocationsTableStatement;
|
||||||
MockSqliteWriteStatement &inserOrUpdateIndexingTimesStampStatement = storage.inserOrUpdateIndexingTimesStampStatement;
|
|
||||||
MockSqliteReadStatement &fetchIndexingTimeStampsStatement = storage.fetchIndexingTimeStampsStatement;
|
|
||||||
MockSqliteReadStatement &fetchIncludedIndexingTimeStampsStatement = storage.fetchIncludedIndexingTimeStampsStatement;
|
|
||||||
MockSqliteReadStatement &fetchDependentSourceIdsStatement = storage.fetchDependentSourceIdsStatement;
|
|
||||||
SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}},
|
SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}},
|
||||||
{2, {"function2USR", "function2", SymbolKind::Function}}};
|
{2, {"function2USR", "function2", SymbolKind::Function}}};
|
||||||
SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SourceLocationKind::Declaration},
|
SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SourceLocationKind::Declaration},
|
||||||
@@ -192,145 +188,4 @@ TEST_F(SymbolStorage, AddTablesInConstructor)
|
|||||||
Storage storage{mockDatabase};
|
Storage storage{mockDatabase};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SymbolStorage, FetchIndexingTimeStampsIsBusy)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024))
|
|
||||||
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
||||||
EXPECT_CALL(mockDatabase, rollback());
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024));
|
|
||||||
EXPECT_CALL(mockDatabase, commit());
|
|
||||||
|
|
||||||
storage.fetchIndexingTimeStamps();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorage, InsertIndexingTimeStamp)
|
|
||||||
{
|
|
||||||
ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}};
|
|
||||||
|
|
||||||
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
|
|
||||||
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37)));
|
|
||||||
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps(fileStatuses);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorage, InsertIndexingTimeStampsIsBusy)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
||||||
EXPECT_CALL(mockDatabase, immediateBegin());
|
|
||||||
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
|
|
||||||
EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34)));
|
|
||||||
EXPECT_CALL(mockDatabase, commit());
|
|
||||||
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorage, FetchIncludedIndexingTimeStampsIsBusy)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement,
|
|
||||||
valuesReturnSourceTimeStamps(1024, TypedEq<int>(1)))
|
|
||||||
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
||||||
EXPECT_CALL(mockDatabase, rollback());
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement,
|
|
||||||
valuesReturnSourceTimeStamps(1024, TypedEq<int>(1)));
|
|
||||||
EXPECT_CALL(mockDatabase, commit());
|
|
||||||
|
|
||||||
storage.fetchIncludedIndexingTimeStamps(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorage, FetchDependentSourceIdsIsBusy)
|
|
||||||
{
|
|
||||||
InSequence s;
|
|
||||||
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3)));
|
|
||||||
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2)))
|
|
||||||
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
||||||
EXPECT_CALL(mockDatabase, rollback());
|
|
||||||
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
||||||
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3)));
|
|
||||||
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2)));
|
|
||||||
EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(7)));
|
|
||||||
EXPECT_CALL(mockDatabase, commit());
|
|
||||||
|
|
||||||
storage.fetchDependentSourceIds({3, 2, 7});
|
|
||||||
}
|
|
||||||
|
|
||||||
class SymbolStorageSlow : public testing::Test
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
|
||||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
|
||||||
ClangBackEnd::SymbolStorage<> storage{database};
|
|
||||||
ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database};
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, InsertIndexingTimeStamps)
|
|
||||||
{
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
|
||||||
|
|
||||||
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
|
||||||
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 34}));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamps)
|
|
||||||
{
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
|
|
||||||
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({1}, 37);
|
|
||||||
|
|
||||||
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
|
||||||
ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34}));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, InsertIndexingTimeStamp)
|
|
||||||
{
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}});
|
|
||||||
|
|
||||||
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
|
||||||
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamp)
|
|
||||||
{
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}});
|
|
||||||
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}});
|
|
||||||
|
|
||||||
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
|
|
||||||
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, FetchIncludedIndexingTimeStamps)
|
|
||||||
{
|
|
||||||
storage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5}, 34);
|
|
||||||
buildDependenciesStorage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {3, 4}, {5, 3}});
|
|
||||||
|
|
||||||
auto timeStamps = storage.fetchIncludedIndexingTimeStamps(1);
|
|
||||||
|
|
||||||
ASSERT_THAT(timeStamps,
|
|
||||||
ElementsAre(SourceTimeStamp{1, 34},
|
|
||||||
SourceTimeStamp{2, 34},
|
|
||||||
SourceTimeStamp{3, 34},
|
|
||||||
SourceTimeStamp{4, 34}));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(SymbolStorageSlow, FetchDependentSourceIds)
|
|
||||||
{
|
|
||||||
buildDependenciesStorage.insertOrUpdateSourceDependencies(
|
|
||||||
{{1, 2}, {1, 3}, {2, 3}, {4, 2}, {5, 6}, {7, 6}});
|
|
||||||
|
|
||||||
auto sourceIds = storage.fetchDependentSourceIds({3, 2, 7});
|
|
||||||
|
|
||||||
ASSERT_THAT(sourceIds, ElementsAre(FilePathId{1}, FilePathId{4}, FilePathId{7}));
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -97,8 +97,14 @@ TEST_F(UsedMacroFilter, Sources)
|
|||||||
{
|
{
|
||||||
ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
|
ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
|
||||||
|
|
||||||
ASSERT_THAT(filter.sources,
|
ASSERT_THAT(filter.sources, ElementsAre(FilePathId{6}));
|
||||||
ElementsAre(FilePathId{2}, FilePathId{3}, FilePathId{4}, FilePathId{5}));
|
}
|
||||||
|
|
||||||
|
TEST_F(UsedMacroFilter, UserIncludes)
|
||||||
|
{
|
||||||
|
ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
|
||||||
|
|
||||||
|
ASSERT_THAT(filter.userIncludes, ElementsAre(FilePathId{1}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UsedMacroFilter, SystemUsedMacros)
|
TEST_F(UsedMacroFilter, SystemUsedMacros)
|
||||||
|
Reference in New Issue
Block a user