diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h index a6f8d4633e52613a53a074e8c613febeb5a8f682..804be33541f19ea0d5ee683e5f14574367bdfbb9 100644 --- a/src/libs/clangsupport/stringcache.h +++ b/src/libs/clangsupport/stringcache.h @@ -25,6 +25,8 @@ #pragma once +#include "stringcachefwd.h" + #include #include @@ -52,11 +54,11 @@ public: void unlock() {} }; -template +template class StringCacheEntry { public: - StringCacheEntry(StringType &&string, uint id) + StringCacheEntry(StringType &&string, IndexType id) : string(std::move(string)), id(id) {} @@ -77,22 +79,27 @@ public: } StringType string; - uint id; + IndexType id; }; -template -using StringCacheEntries = std::vector>; +template +using StringCacheEntries = std::vector>; + +using FileCacheCacheEntry = StringCacheEntry; +using FileCacheCacheEntries = std::vector; template + typename IndexType, + typename Mutex> class StringCache { - using const_iterator = typename StringCacheEntries::const_iterator; + using CacheEnties = StringCacheEntries; + using const_iterator = typename CacheEnties::const_iterator; class Found { public: - typename StringCacheEntries::const_iterator iterator; + typename CacheEnties::const_iterator iterator; bool wasFound; }; @@ -103,14 +110,14 @@ public: m_indices.reserve(1024); } - void populate(StringCacheEntries &&entries) + void populate(CacheEnties &&entries) { uncheckedPopulate(std::move(entries)); checkEntries(); } - void uncheckedPopulate(StringCacheEntries &&entries) + void uncheckedPopulate(CacheEnties &&entries) { std::sort(entries.begin(), entries.end()); @@ -123,7 +130,7 @@ public: } - uint stringId(Utils::SmallStringView stringView) + IndexType stringId(Utils::SmallStringView stringView) { std::lock_guard lock(m_mutex); @@ -136,11 +143,11 @@ public: } template - std::vector stringIds(const Container &strings) + std::vector stringIds(const Container &strings) { std::lock_guard lock(m_mutex); - std::vector ids; + std::vector ids; ids.reserve(strings.size()); std::transform(strings.begin(), @@ -151,19 +158,19 @@ public: return ids; } - std::vector stringIds(std::initializer_list strings) + std::vector stringIds(std::initializer_list strings) { return stringIds>(strings); } - Utils::SmallStringView string(uint id) const + Utils::SmallStringView string(IndexType id) const { std::lock_guard lock(m_mutex); return m_strings.at(m_indices.at(id)).string; } - std::vector strings(const std::vector &ids) const + std::vector strings(const std::vector &ids) const { std::lock_guard lock(m_mutex); @@ -173,7 +180,7 @@ public: std::transform(ids.begin(), ids.end(), std::back_inserter(strings), - [&] (uint id) { return m_strings.at(m_indices.at(id)).string; }); + [&] (IndexType id) { return m_strings.at(m_indices.at(id)).string; }); return strings; } @@ -191,24 +198,24 @@ private: return {range.first, range.first != range.second}; } - void incrementLargerOrEqualIndicesByOne(uint newIndex) + void incrementLargerOrEqualIndicesByOne(IndexType newIndex) { std::transform(m_indices.begin(), m_indices.end(), m_indices.begin(), - [&] (uint index) { + [&] (IndexType index) { return index >= newIndex ? ++index : index; }); } - uint insertString(const_iterator beforeIterator, + IndexType insertString(const_iterator beforeIterator, Utils::SmallStringView stringView) { - auto id = uint(m_indices.size()); + auto id = IndexType(m_indices.size()); auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id); - auto newIndex = uint(std::distance(m_strings.begin(), inserted)); + auto newIndex = IndexType(std::distance(m_strings.begin(), inserted)); incrementLargerOrEqualIndicesByOne(newIndex); @@ -226,12 +233,13 @@ private: } private: - StringCacheEntries m_strings; - std::vector m_indices; + CacheEnties m_strings; + std::vector m_indices; mutable Mutex m_mutex; }; -template -using FilePathCache = StringCache; +template +using FilePathCache = StringCache; +using FilePathIndices = std::vector; } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/stringcachefwd.h b/src/libs/clangsupport/stringcachefwd.h index 35b8534254e5aa18cb1f7141e65a1a30acb23884..4a12bfee691df1426184c02ae9430af8e210e717 100644 --- a/src/libs/clangsupport/stringcachefwd.h +++ b/src/libs/clangsupport/stringcachefwd.h @@ -29,14 +29,17 @@ namespace ClangBackEnd { +using FilePathIndex = long long int; + class NonLockingMutex; template class StringCache; template -using FilePathCache = StringCache; +using FilePathCache = StringCache; } // namespace ClangBackEnd diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitestatement.h index 09c75c16d974055e0f38a820fc8b23f7d74f79e4..d9bd87a2ee4f170006e17b142f0b3bb94b5d10c1 100644 --- a/src/libs/sqlite/sqlitestatement.h +++ b/src/libs/sqlite/sqlitestatement.h @@ -83,27 +83,27 @@ protected: { } - template - void bindValues(Values... values) + template + void bindValues(ValueType... values) { bindValuesByIndex(1, values...); } - template - void write(Values... values) + template + void write(ValueType... values) { bindValuesByIndex(1, values...); execute(); } - template - void bindNameValues(Values... values) + template + void bindNameValues(ValueType... values) { bindValuesByName(values...); } - template - void writeNamed(Values... values) + template + void writeNamed(ValueType... values) { bindValuesByName(values...); execute(); @@ -117,45 +117,45 @@ protected: void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames); const Utils::SmallStringVector &bindingColumnNames() const; - template - std::vector> tupleValues(std::size_t reserveSize) + template + std::vector> tupleValues(std::size_t reserveSize) { - using Container = std::vector>; + using Container = std::vector>; Container resultValues; resultValues.reserve(reserveSize); while (next()) - emplaceTupleValues(resultValues); + emplaceTupleValues(resultValues); reset(); return resultValues; } - template - std::vector> tupleValues(std::size_t reserveSize, const QueryType&... queryValues) + template + std::vector> tupleValues(std::size_t reserveSize, const QueryTypes&... queryValues) { - using Container = std::vector>; + using Container = std::vector>; Container resultValues; resultValues.reserve(reserveSize); bindValues(queryValues...); while (next()) - emplaceTupleValues(resultValues); + emplaceTupleValues(resultValues); reset(); return resultValues; } - template - std::vector> tupleValues(std::size_t reserveSize, - const std::vector> &queryTuples) + template + std::vector> tupleValues(std::size_t reserveSize, + const std::vector> &queryTuples) { - using Container = std::vector>; + using Container = std::vector>; Container resultValues; resultValues.reserve(reserveSize); @@ -163,7 +163,7 @@ protected: bindTupleValues(queryTuple); while (next()) - emplaceTupleValues(resultValues); + emplaceTupleValues(resultValues); reset(); } @@ -171,12 +171,12 @@ protected: return resultValues; } - template - std::vector> tupleValues(std::size_t reserveSize, + std::vector> tupleValues(std::size_t reserveSize, const std::vector &queryValues) { - using Container = std::vector>; + using Container = std::vector>; Container resultValues; resultValues.reserve(reserveSize); @@ -184,7 +184,7 @@ protected: bindValues(queryValue); while (next()) - emplaceTupleValues(resultValues); + emplaceTupleValues(resultValues); reset(); } @@ -193,7 +193,7 @@ protected: } template + typename... ResultEntryTypes> std::vector structValues(std::size_t reserveSize) { using Container = std::vector; @@ -201,7 +201,7 @@ protected: resultValues.reserve(reserveSize); while (next()) - pushBackStructValues(resultValues); + pushBackStructValues(resultValues); reset(); @@ -209,9 +209,9 @@ protected: } template - std::vector structValues(std::size_t reserveSize, const QueryType&... queryValues) + typename... ResultEntryTypes, + typename... QueryTypes> + std::vector structValues(std::size_t reserveSize, const QueryTypes&... queryValues) { using Container = std::vector; Container resultValues; @@ -220,7 +220,7 @@ protected: bindValues(queryValues...); while (next()) - pushBackStructValues(resultValues); + pushBackStructValues(resultValues); reset(); @@ -228,7 +228,7 @@ protected: } template std::vector structValues(std::size_t reserveSize, const std::vector &queryValues) @@ -241,7 +241,7 @@ protected: bindValues(queryValue); while (next()) - pushBackStructValues(resultValues); + pushBackStructValues(resultValues); reset(); } @@ -250,10 +250,10 @@ protected: } template + typename... ResultEntryTypes, + typename... QueryElementTypes> std::vector structValues(std::size_t reserveSize, - const std::vector> &queryTuples) + const std::vector> &queryTuples) { using Container = std::vector; Container resultValues; @@ -263,7 +263,7 @@ protected: bindTupleValues(queryTuple); while (next()) - pushBackStructValues(resultValues); + pushBackStructValues(resultValues); reset(); } @@ -272,7 +272,7 @@ protected: } template + typename... ElementTypes> std::vector values(std::size_t reserveSize) { std::vector resultValues; @@ -327,8 +327,8 @@ protected: } template - std::vector values(std::size_t reserveSize, const QueryType&... queryValues) + typename... QueryTypes> + std::vector values(std::size_t reserveSize, const QueryTypes&... queryValues) { std::vector resultValues; resultValues.reserve(reserveSize); @@ -379,74 +379,74 @@ protected: SqliteDatabaseBackend &databaseBackend); private: - template - void emplaceTupleValues(Container &container, std::integer_sequence) + template + void emplaceTupleValues(ContainerType &container, std::integer_sequence) { - container.emplace_back(value(Index)...); + container.emplace_back(value(ColumnIndices)...); } - template - void emplaceTupleValues(Container &container) + template + void emplaceTupleValues(ContainerType &container) { - emplaceTupleValues(container, std::make_integer_sequence{}); + emplaceTupleValues(container, std::make_integer_sequence{}); } - template - void pushBackStructValues(Container &container, std::integer_sequence) + template + void pushBackStructValues(ContainerType &container, std::integer_sequence) { - using ResultType = typename Container::value_type; - container.push_back(ResultType{value(Index)...}); + using ResultType = typename ContainerType::value_type; + container.push_back(ResultType{value(ColumnIndices)...}); } - template - void pushBackStructValues(Container &container) + template + void pushBackStructValues(ContainerType &container) { - pushBackStructValues(container, std::make_integer_sequence{}); + pushBackStructValues(container, std::make_integer_sequence{}); } - template - void bindValuesByIndex(int index, Type value) + template + void bindValuesByIndex(int index, ValueType value) { bind(index, value); } - template - void bindValuesByIndex(int index, Type value, Value... values) + template + void bindValuesByIndex(int index, ValueType value, ValueTypes... values) { bind(index, value); bindValuesByIndex(index + 1, values...); } - template - void bindValuesByName(Utils::SmallStringView name, Type value) + template + void bindValuesByName(Utils::SmallStringView name, ValueType value) { bind(bindingIndexForName(name), value); } - template - void bindValuesByName(Utils::SmallStringView name, Type value, Values... values) + template + void bindValuesByName(Utils::SmallStringView name, ValueType value, ValueTypes... values) { bind(bindingIndexForName(name), value); bindValuesByName(values...); } - template - void bindTupleValuesElement(const TupleType &tuple, std::index_sequence) + template + void bindTupleValuesElement(const TupleType &tuple, std::index_sequence) { - bindValues(std::get(tuple)...); + bindValues(std::get(tuple)...); } template ::value>> + typename ColumnIndices = std::make_index_sequence::value>> void bindTupleValues(const TupleType &element) { - bindTupleValuesElement(element, Indices()); + bindTupleValuesElement(element, ColumnIndices()); } private: diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h index 194616b2b44ed113f527110606b08568a81ad3dd..3798cb6e4e87211de97421d388c517af8f4bc7c5 100644 --- a/src/libs/utils/smallstringview.h +++ b/src/libs/utils/smallstringview.h @@ -140,6 +140,8 @@ public: return m_pointer[0] == characterToSearch; } + + private: const char *m_pointer; size_type m_size; diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index a8eb4ce09a15458941bd406630f26066cfdca731..5622179272b496f790b770db2c03e760fafa2688 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -50,7 +50,7 @@ using ClangBackEnd::PchGenerator; using ClangBackEnd::PchManagerClientProxy; using ClangBackEnd::PchManagerServer; using ClangBackEnd::ProjectParts; -using ClangBackEnd::StringCache; +using ClangBackEnd::FilePathCache; class ApplicationEnvironment : public ClangBackEnd::Environment { @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) const QString connection = processArguments(application); - StringCache filePathCache; + FilePathCache<> filePathCache; ClangPathWatcher includeWatcher(filePathCache); ApplicationEnvironment environment; PchGenerator pchGenerator(environment); diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h index a02d09f3f7f9358fd2ff19c2f858113675ee3392..10dbbb1247107fb02315be0e1c8ad60dc38270bc 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h +++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h @@ -37,8 +37,8 @@ namespace ClangBackEnd { class WatcherEntry { public: - uint id; - uint path; + FilePathIndex id; + FilePathIndex path; friend bool operator==(const WatcherEntry &first, const WatcherEntry &second) { @@ -50,12 +50,12 @@ public: return std::tie(first.path, first.id) < std::tie(second.path, second.id); } - friend bool operator<(const WatcherEntry &entry, uint path) + friend bool operator<(const WatcherEntry &entry, FilePathIndex path) { return entry.path < path; } - friend bool operator<(uint path, const WatcherEntry &entry) + friend bool operator<(FilePathIndex path, const WatcherEntry &entry) { return path < entry.path; } @@ -63,12 +63,14 @@ public: using WatcherEntries = std::vector; +using IdCache = StringCache; + template class ClangPathWatcher : public ClangPathWatcherInterface { public: - ClangPathWatcher(StringCache &pathCache, + ClangPathWatcher(FilePathCache<> &pathCache, ClangPathWatcherNotifier *notifier=nullptr) : m_pathCache(pathCache), m_notifier(notifier) @@ -130,9 +132,9 @@ unittest_public: return ids; } - std::vector convertToIdNumbers(const Utils::SmallStringVector &ids) + std::vector convertToIdNumbers(const Utils::SmallStringVector &ids) { - std::vector idNumbers = m_idCache.stringIds(ids); + std::vector idNumbers = m_idCache.stringIds(ids); std::sort(idNumbers.begin(), idNumbers.end()); @@ -149,19 +151,19 @@ unittest_public: } - std::pair> + std::pair> convertIdPathsToWatcherEntriesAndIds(const std::vector &idPaths) { WatcherEntries entries; entries.reserve(sizeOfIdPaths(idPaths)); - std::vector ids; + std::vector ids; ids.reserve(ids.size()); auto outputIterator = std::back_inserter(entries); for (const IdPaths &idPath : idPaths) { - uint id = m_idCache.stringId(idPath.id); + FilePathIndex id = m_idCache.stringId(idPath.id); ids.push_back(id); @@ -190,7 +192,7 @@ unittest_public: } void removeUnusedEntries(const WatcherEntries &entries, - const std::vector &ids) + const std::vector &ids) { auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids); @@ -272,7 +274,7 @@ unittest_public: WatcherEntries notAnymoreWatchedEntriesWithIds( const WatcherEntries &newEntries, - const std::vector &ids) const + const std::vector &ids) const { auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less()); @@ -328,7 +330,7 @@ unittest_public: return m_watchedEntries; } - WatcherEntries removeIdsFromWatchedEntries(const std::vector &ids) + WatcherEntries removeIdsFromWatchedEntries(const std::vector &ids) { auto keep = [&] (const WatcherEntry &entry) { @@ -368,7 +370,7 @@ unittest_public: WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths) { - std::vector pathIds = m_pathCache.stringIds(filePaths); + std::vector pathIds = m_pathCache.stringIds(filePaths); WatcherEntries foundEntries; @@ -414,22 +416,22 @@ unittest_public: } } - StringCache &pathCache() + FilePathCache<> &pathCache() { return m_pathCache; } - StringCache &idCache() + IdCache &idCache() { return m_idCache; } private: - StringCache m_idCache; + IdCache m_idCache; WatcherEntries m_watchedEntries; ChangedFilePathCompressor m_changedFilePathCompressor; FileSystemWatcher m_fileSystemWatcher; - StringCache &m_pathCache; + FilePathCache<> &m_pathCache; ClangPathWatcherNotifier *m_notifier; }; diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h index 5b8b8ad5e6b9b2c7fa9cfc31e99e1f5ed3aa9b14..339d491848db095a481cd5a79fdc8037dd7c6212 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h @@ -38,10 +38,10 @@ namespace ClangBackEnd { class CollectIncludesAction final : public clang::PreprocessOnlyAction { public: - CollectIncludesAction(std::vector &includeIds, - StringCache &filePathCache, - std::vector &excludedIncludeUID, - std::vector &alreadyIncludedFileUIDs) + CollectIncludesAction(FilePathIndices &includeIds, + FilePathCache<> &filePathCache, + FilePathIndices &excludedIncludeUID, + FilePathIndices &alreadyIncludedFileUIDs) : m_includeIds(includeIds), m_filePathCache(filePathCache), m_excludedIncludeUID(excludedIncludeUID), @@ -78,10 +78,10 @@ public: } private: - std::vector &m_includeIds; - StringCache &m_filePathCache; - std::vector &m_excludedIncludeUID; - std::vector &m_alreadyIncludedFileUIDs; + FilePathIndices &m_includeIds; + FilePathCache<> &m_filePathCache; + FilePathIndices &m_excludedIncludeUID; + FilePathIndices &m_alreadyIncludedFileUIDs; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h index ba86822fce35ddeed8f1c422f59e89f6523b3050..a57d72adfcb96018be9022a0bd224be4e2e00e78 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h @@ -47,10 +47,10 @@ class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks { public: CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch, - std::vector &includeIds, - StringCache &filePathCache, - const std::vector &excludedIncludeUID, - std::vector &alreadyIncludedFileUIDs) + std::vector &includeIds, + FilePathCache<> &filePathCache, + const std::vector &excludedIncludeUID, + std::vector &alreadyIncludedFileUIDs) : m_headerSearch(headerSearch), m_includeIds(includeIds), m_filePathCache(filePathCache), @@ -78,7 +78,7 @@ public: m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); Utils::PathString filePath = filePathFromFile(file); if (!filePath.isEmpty()) { - uint includeId = m_filePathCache.stringId(filePath); + FilePathIndex includeId = m_filePathCache.stringId(filePath); m_includeIds.emplace_back(includeId); } } @@ -132,7 +132,7 @@ public: uid); } - std::pair::iterator> isNotAlreadyIncluded(uint uid) const + std::pair::iterator> isNotAlreadyIncluded(FilePathIndex uid) const { auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(), m_alreadyIncludedFileUIDs.end(), @@ -174,10 +174,10 @@ public: private: clang::HeaderSearch &m_headerSearch; - std::vector &m_includeIds; - StringCache &m_filePathCache; - const std::vector &m_excludedIncludeUID; - std::vector &m_alreadyIncludedFileUIDs; + std::vector &m_includeIds; + FilePathCache<> &m_filePathCache; + const std::vector &m_excludedIncludeUID; + std::vector &m_alreadyIncludedFileUIDs; bool m_skipInclude = false; }; diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h index 87e92c1df3eae3aa752b41541be6a752071f9cc3..42b8a62cea712da8fe695c81c17324c30c20935e 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h @@ -36,8 +36,8 @@ namespace ClangBackEnd { class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory { public: - CollectIncludesToolAction(std::vector &includeIds, - StringCache &filePathCache, + CollectIncludesToolAction(std::vector &includeIds, + FilePathCache<> &filePathCache, const Utils::PathStringVector &excludedIncludes) : m_includeIds(includeIds), m_filePathCache(filePathCache), @@ -72,9 +72,9 @@ public: m_alreadyIncludedFileUIDs); } - std::vector generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const + std::vector generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const { - std::vector fileUIDs; + std::vector fileUIDs; fileUIDs.reserve(m_excludedIncludes.size()); for (const Utils::PathString &filePath : m_excludedIncludes) { @@ -90,10 +90,10 @@ public: } private: - std::vector m_alreadyIncludedFileUIDs; - std::vector m_excludedIncludeUIDs; - std::vector &m_includeIds; - StringCache &m_filePathCache; + std::vector m_alreadyIncludedFileUIDs; + std::vector m_excludedIncludeUIDs; + std::vector &m_includeIds; + FilePathCache<> &m_filePathCache; const Utils::PathStringVector &m_excludedIncludes; }; diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.h b/src/tools/clangpchmanagerbackend/source/idpaths.h index f6f312f05fd49e9bf3a934be3e321da872341862..a407e24530ff91c4f122f8d103a8a864db19ba30 100644 --- a/src/tools/clangpchmanagerbackend/source/idpaths.h +++ b/src/tools/clangpchmanagerbackend/source/idpaths.h @@ -29,13 +29,15 @@ #include +#include + namespace ClangBackEnd { class IdPaths { public: Utils::SmallString id; - std::vector paths; + std::vector paths; friend bool operator==(const IdPaths &first, const IdPaths &second) { diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp index b380fa2b8b6148e3feb6c16ebba8d1c29a42b566..421123b3a7c970e96ee8db30d02318665f6efa12 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp +++ b/src/tools/clangpchmanagerbackend/source/includecollector.cpp @@ -33,7 +33,7 @@ namespace ClangBackEnd { -IncludeCollector::IncludeCollector(StringCache &filePathCache) +IncludeCollector::IncludeCollector(FilePathCache<> &filePathCache) : m_filePathCache(filePathCache) { } @@ -69,7 +69,7 @@ void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedInc #endif } -std::vector IncludeCollector::takeIncludeIds() +std::vector IncludeCollector::takeIncludeIds() { std::sort(m_includeIds.begin(), m_includeIds.end()); diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/includecollector.h index ba485ea33d75cac64cf5765fff4d0095f49b7db4..73f9b948afa7e93a6aa2b08e4602cd1493147a5f 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.h +++ b/src/tools/clangpchmanagerbackend/source/includecollector.h @@ -34,19 +34,19 @@ namespace ClangBackEnd { class IncludeCollector : public ClangTool { public: - IncludeCollector(StringCache &filePathCache); + IncludeCollector(FilePathCache<> &filePathCache); void collectIncludes(); void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes); - std::vector takeIncludeIds(); + std::vector takeIncludeIds(); private: Utils::PathStringVector m_excludedIncludes; - std::vector m_includeIds; + std::vector m_includeIds; Utils::SmallStringVector m_directories; - StringCache &m_filePathCache; + FilePathCache<> &m_filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 4c685dc34e12549a4d22e1fc4e3dabe5fe1ac394..d8551d77677d7bc2425051158b473844f3ab996e 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -37,7 +37,7 @@ namespace ClangBackEnd { -PchCreator::PchCreator(Environment &environment, StringCache &filePathCache) +PchCreator::PchCreator(Environment &environment, FilePathCache<> &filePathCache) : m_environment(environment), m_filePathCache(filePathCache) { @@ -45,7 +45,7 @@ PchCreator::PchCreator(Environment &environment, StringCache PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts, Environment &environment, - StringCache &filePathCache, + FilePathCache<> &filePathCache, PchGeneratorInterface *pchGenerator, V2::FileContainers &&generatedFiles) : m_projectParts(std::move(projectsParts)), @@ -239,7 +239,7 @@ Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() cons return compilerArguments; } -std::vector PchCreator::generateGlobalPchIncludeIds() const +std::vector PchCreator::generateGlobalPchIncludeIds() const { IncludeCollector collector(m_filePathCache); @@ -267,7 +267,7 @@ std::size_t contentSize(const std::vector &includes) } Utils::SmallString PchCreator::generatePchIncludeFileContent( - const std::vector &includeIds) const + const std::vector &includeIds) const { Utils::SmallString fileContent; const std::size_t lineTemplateSize = 12; @@ -461,7 +461,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaderAndSourcePaths( return includeAndSources; } -std::vector PchCreator::generateProjectPartPchIncludes( +std::vector PchCreator::generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const { Utils::SmallString jointedFileContent = generateProjectPartHeaderAndSourcesContent(projectPart); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 1b418ad3db2c306947dd34b98a7b3f9460e98605..5548ec7acd2f0f6b3706b1cc3e4532bd7cd70213 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -48,10 +48,10 @@ class PchCreator final : public PchCreatorInterface { public: PchCreator(Environment &environment, - StringCache &filePathCache); + FilePathCache<> &filePathCache); PchCreator(V2::ProjectPartContainers &&projectsParts, Environment &environment, - StringCache &filePathCache, + FilePathCache<> &filePathCache, PchGeneratorInterface *pchGenerator, V2::FileContainers &&generatedFiles); @@ -70,9 +70,9 @@ unittest_public: Utils::SmallStringVector generateGlobalPchCompilerArguments() const; Utils::SmallStringVector generateGlobalClangCompilerArguments() const; - std::vector generateGlobalPchIncludeIds() const; + std::vector generateGlobalPchIncludeIds() const; - Utils::SmallString generatePchIncludeFileContent(const std::vector &includeIds) const; + Utils::SmallString generatePchIncludeFileContent(const std::vector &includeIds) const; Utils::SmallString generateGlobalPchHeaderFileContent() const; std::unique_ptr generateGlobalPchHeaderFile(); void generatePch(Utils::SmallStringVector &&commandLineArguments, @@ -97,7 +97,7 @@ unittest_public: const V2::ProjectPartContainer &projectPart); static Utils::PathStringVector generateProjectPartHeaderAndSourcePaths( const V2::ProjectPartContainer &projectPart); - std::vector generateProjectPartPchIncludes( + std::vector generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPathPchHeaderFilePath( const V2::ProjectPartContainer &projectPart) const; @@ -127,7 +127,7 @@ private: std::vector m_projectPartPchs; std::vector m_projectsIncludeIds; Environment &m_environment; - StringCache &m_filePathCache; + FilePathCache<> &m_filePathCache; PchGeneratorInterface *m_pchGenerator = nullptr; }; diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp index f22458c8b3ddabcce744ecf30a4144871e5305d6..03261ae164c3309ce768e861441fb19aafbba936 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp @@ -36,7 +36,7 @@ namespace ClangBackEnd { -PchManagerServer::PchManagerServer(StringCache &filePathCache, +PchManagerServer::PchManagerServer(FilePathCache<> &filePathCache, ClangPathWatcherInterface &fileSystemWatcher, PchCreatorInterface &pchCreator, ProjectPartsInterface &projectParts) diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h index b9df33f8b9f532d0bed796e33ffb5dc6a8cbede4..7be9c7596698b3e6f3a43156ec21e39c8ace9ef7 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h @@ -46,7 +46,7 @@ class PchManagerServer : public PchManagerServerInterface, { public: - PchManagerServer(StringCache &filePathCache, + PchManagerServer(FilePathCache<> &filePathCache, ClangPathWatcherInterface &fileSystemWatcher, PchCreatorInterface &pchCreator, ProjectPartsInterface &projectParts); @@ -60,7 +60,7 @@ public: void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override; private: - StringCache &m_filePathCache; + FilePathCache<> &m_filePathCache; ClangPathWatcherInterface &m_fileSystemWatcher; PchCreatorInterface &m_pchCreator; ProjectPartsInterface &m_projectParts; diff --git a/src/tools/clangrefactoringbackend/source/clangquery.cpp b/src/tools/clangrefactoringbackend/source/clangquery.cpp index b625e9e197f88f2d96828e4bc2a2a332c37a45f6..620a7ebaab078b93e10b85a57c51c28ad96cd44d 100644 --- a/src/tools/clangrefactoringbackend/source/clangquery.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquery.cpp @@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder::MatchCallback { } }; -ClangQuery::ClangQuery(StringCache &filePathCache, +ClangQuery::ClangQuery(FilePathCache &filePathCache, Utils::SmallString &&query) : query(std::move(query)), filePathCache(filePathCache) diff --git a/src/tools/clangrefactoringbackend/source/clangquery.h b/src/tools/clangrefactoringbackend/source/clangquery.h index faa5821ca3b6e3b552cc8cacacce178cae2996ff..7d99766008d5d1f100b3c6e9c76c40774f138db3 100644 --- a/src/tools/clangrefactoringbackend/source/clangquery.h +++ b/src/tools/clangrefactoringbackend/source/clangquery.h @@ -51,7 +51,7 @@ namespace ClangBackEnd { class ClangQuery : public ClangTool { public: - ClangQuery(StringCache &filePathCache, Utils::SmallString &&query={}); + ClangQuery(FilePathCache &filePathCache, Utils::SmallString &&query={}); void setQuery(Utils::SmallString &&query); @@ -69,7 +69,7 @@ private: SourceRangesContainer sourceRangesContainer; Utils::SmallString query; std::vector diagnosticContainers_; - StringCache &filePathCache; + FilePathCache &filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp index 32c8e8694e2dc93a7dcf85eb8d249e454718b47a..692065a9e79f931b4c59720992596caabe6e6fb7 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp @@ -29,7 +29,7 @@ namespace ClangBackEnd { -ClangQueryGatherer::ClangQueryGatherer(StringCache *filePathCache, +ClangQueryGatherer::ClangQueryGatherer(FilePathCache *filePathCache, std::vector &&sources, std::vector &&unsaved, Utils::SmallString &&query) @@ -43,7 +43,7 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache *filePathCache, + FilePathCache *filePathCache, V2::FileContainer &&source, const std::vector &unsaved, Utils::SmallString &&query) diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h index 7d93560eecf448d25547807e8b54d396d32a72c4..c1fd6341fabf3ecdae4cbba90214cd4be960c9c0 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h @@ -41,13 +41,13 @@ public: using Future = std::future; ClangQueryGatherer() = default; - ClangQueryGatherer(StringCache *filePathCache, + ClangQueryGatherer(FilePathCache *filePathCache, std::vector &&sources, std::vector &&unsaved, Utils::SmallString &&query); static SourceRangesForQueryMessage createSourceRangesForSource( - StringCache *filePathCache, + FilePathCache *filePathCache, V2::FileContainer &&source, const std::vector &unsaved, Utils::SmallString &&query); @@ -69,7 +69,7 @@ protected: std::vector finishedFutures(); private: - StringCache *m_filePathCache = nullptr; + FilePathCache *m_filePathCache = nullptr; SourceRangeFilter m_sourceRangeFilter; std::vector m_sources; std::vector m_unsaved; diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index d8e81a9044f429859c532aeb12d7e584bdf1bd79..a342ff8478ba132d6a7f37441f1f80316b04d363 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -12,7 +12,9 @@ HEADERS += \ $$PWD/collectsymbolsastvisitor.h \ $$PWD/sourcelocationentry.h \ $$PWD/symbolscollectorinterface.h \ - $$PWD/symbolstorageinterface.h + $$PWD/symbolstorageinterface.h \ + $$PWD/symbolstorage.h \ + $$PWD/storagesqlitestatementfactory.h !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ @@ -52,4 +54,5 @@ SOURCES += \ $$PWD/collectsymbolsaction.cpp \ $$PWD/collectmacrossourcefilecallbacks.cpp \ $$PWD/symbolentry.cpp \ - $$PWD/sourcelocationentry.cpp + $$PWD/sourcelocationentry.cpp \ + $$PWD/symbolstorage.cpp diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h index 11fd41900fd64fd81a1e0425762e7739d200ef74..73fe3c5b13866dbba86bbb3ced7e9607ce9b6542 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h @@ -60,7 +60,7 @@ public: bool VisitNamedDecl(const clang::NamedDecl *declaration) { - auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding(); + SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl()); auto sourceLocation = declaration->getLocation(); auto found = m_symbolEntries.find(globalId); @@ -81,7 +81,7 @@ public: bool VisitDeclRefExpr(const clang::DeclRefExpr *expression) { auto declaration = expression->getFoundDecl(); - auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding(); + SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl()); auto sourceLocation = expression->getLocation(); m_sourceLocationEntries.emplace_back(globalId, @@ -92,7 +92,7 @@ public: return true; } - uint filePathId(clang::SourceLocation sourceLocation) + FilePathIndex filePathId(clang::SourceLocation sourceLocation) { auto filePath = m_sourceManager.getFilename(sourceLocation); @@ -114,6 +114,11 @@ public: return usr; } + static SymbolIndex toSymbolIndex(const void *pointer) + { + return SymbolIndex(reinterpret_cast(pointer)); + } + private: SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h index d988ea5b8060f0492d991219b9c0757d4cbc2721..33eaee2a0a4c49c97e81499be0e83f777d8c64c3 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.h +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h @@ -75,7 +75,7 @@ private: Utils::SmallString &&query); private: - StringCache m_filePathCache; + FilePathCache m_filePathCache; ClangQueryGatherer m_gatherer; QTimer m_pollTimer; }; diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationentry.h b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h index 20f506c8b1ff506c9209ab80d5cccca53da45382..dbe701238839c74dcdf9994f16842206e749bbf7 100644 --- a/src/tools/clangrefactoringbackend/source/sourcelocationentry.h +++ b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h @@ -25,6 +25,8 @@ #pragma once +#include + #include #include #include @@ -51,11 +53,13 @@ public: uint column = 0; }; +using SymbolIndex = long long; + class SourceLocationEntry { public: - SourceLocationEntry(uint symbolId, - uint fileId, + SourceLocationEntry(SymbolIndex symbolId, + FilePathIndex fileId, LineColumn lineColumn, SymbolType symbolType) : symbolId(symbolId), @@ -65,8 +69,8 @@ public: symbolType(symbolType) {} - uint symbolId = 0; - uint fileId = std::numeric_limits::max(); + SymbolIndex symbolId = 0; + FilePathIndex fileId = std::numeric_limits::max(); uint line = 0; uint column = 0; SymbolType symbolType; diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp index e83f6a3c3839d69b2dcee6bcfb8137a6cd9ec404..6d9d4982273fa0e6555309b13ce15c590738754b 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp +++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp @@ -54,7 +54,7 @@ namespace ClangBackEnd { SourceRangeExtractor::SourceRangeExtractor( const clang::SourceManager &sourceManager, const clang::LangOptions &languageOptions, - ClangBackEnd::StringCache &filePathCache, + ClangBackEnd::FilePathCache &filePathCache, SourceRangesContainer &sourceRangesContainer) : sourceManager(sourceManager), languageOptions(languageOptions), @@ -145,7 +145,7 @@ void SourceRangeExtractor::insertSourceRange(uint fileId, std::move(lineSnippet)); } -uint SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const +FilePathIndex SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const { auto found = m_fileIdMapping.find(fileId.getHashValue()); if (found != m_fileIdMapping.end()) { diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h index 7a07e5c3f87c7ae92fab5f5c8294fc370b3127de..306464297472b332c68b6120e2433139542d5cca 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h +++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h @@ -59,7 +59,7 @@ class SourceRangeExtractor public: SourceRangeExtractor(const clang::SourceManager &sourceManager, const clang::LangOptions &languageOptions, - ClangBackEnd::StringCache &filePathCache, + ClangBackEnd::FilePathCache &filePathCache, SourceRangesContainer &sourceRangesContainer); void addSourceRange(const clang::SourceRange &sourceRange); @@ -82,13 +82,13 @@ private: uint endOffset, Utils::SmallString &&lineSnippet); - uint findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const; + FilePathIndex findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const; private: mutable std::unordered_map m_fileIdMapping; const clang::SourceManager &sourceManager; const clang::LangOptions &languageOptions; - ClangBackEnd::StringCache &filePathCache; + ClangBackEnd::FilePathCache &filePathCache; SourceRangesContainer &sourceRangesContainer; }; diff --git a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h new file mode 100644 index 0000000000000000000000000000000000000000..22bd7cf5f5c85844a2814e0b2a9b7ad8605fb296 --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include +#include + +namespace ClangBackEnd { + +template +class StorageSqliteStatementFactory +{ +public: + using DatabaseType = Database; + using ReadStatementType = ReadStatement; + using WriteStatementType = WriteStatement; + + StorageSqliteStatementFactory(Database &database) + : database(database) + { + } + + Sqlite::SqliteTable createSymbolsTable() + { + Sqlite::SqliteTable table; + table.setUseIfNotExists(true); + table.setName("symbols"); + table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey); + table.addColumn("usr", Sqlite::ColumnType::Text); + table.addColumn("symbolName", Sqlite::ColumnType::Text); + + Sqlite::SqliteImmediateTransaction transaction(database); + table.initialize(database); + transaction.commit(); + + return table; + } + + Sqlite::SqliteTable createLocationsTable() + { + Sqlite::SqliteTable table; + table.setUseIfNotExists(true); + table.setName("locations"); + table.addColumn("symbolId", Sqlite::ColumnType::Integer); + table.addColumn("line", Sqlite::ColumnType::Integer); + table.addColumn("column", Sqlite::ColumnType::Integer); + table.addColumn("sourceId", Sqlite::ColumnType::Integer); + + Sqlite::SqliteImmediateTransaction transaction(database); + table.initialize(database); + transaction.commit(); + + return table; + } + + Sqlite::SqliteTable createSourcesTable() + { + Sqlite::SqliteTable table; + table.setUseIfNotExists(true); + table.setName("sources"); + table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey); + table.addColumn("sourcePath", Sqlite::ColumnType::Text); + + Sqlite::SqliteImmediateTransaction transaction(database); + table.initialize(database); + transaction.commit(); + + return table; + } + + Sqlite::SqliteTable createNewSymbolsTable() const + { + Sqlite::SqliteTable table; + table.setName("newSymbols"); + table.setUseTemporaryTable(true); + table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey); + table.addColumn("symbolId", Sqlite::ColumnType::Integer); + table.addColumn("usr", Sqlite::ColumnType::Text); + table.addColumn("symbolName", Sqlite::ColumnType::Text); + + Sqlite::SqliteImmediateTransaction transaction(database); + table.initialize(database); + transaction.commit(); + + return table; + } + + Sqlite::SqliteTable createNewLocationsTable() const + { + Sqlite::SqliteTable table; + table.setName("newLocations"); + table.setUseTemporaryTable(true); + table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer); + table.addColumn("symbolId", Sqlite::ColumnType::Integer); + table.addColumn("line", Sqlite::ColumnType::Integer); + table.addColumn("column", Sqlite::ColumnType::Integer); + table.addColumn("sourceId", Sqlite::ColumnType::Integer); + + Sqlite::SqliteImmediateTransaction transaction(database); + table.initialize(database); + transaction.commit(); + + return table; + } + +public: + Database &database; + Sqlite::SqliteTable symbolsTable{createSymbolsTable()}; + Sqlite::SqliteTable locationsTable{createLocationsTable()}; + Sqlite::SqliteTable sourcesTable{createSourcesTable()}; + Sqlite::SqliteTable newSymbolsTablet{createNewSymbolsTable()}; + Sqlite::SqliteTable newLocationsTable{createNewLocationsTable()}; + WriteStatement insertSymbolsToNewSymbolsStatement{ + "INSERT INTO newSymbols(temporarySymbolId, usr, symbolName) VALUES(?,?,?)", + database}; + WriteStatement insertLocationsToNewLocationsStatement{ + "INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)", + database}; +// WriteStatement syncNewLocationsToLocationsStatement{ +// "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations", +// database}; + ReadStatement selectNewSourceIdsStatement{ + "SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)", + database}; + WriteStatement addNewSymbolsToSymbolsStatement{ + "INSERT INTO symbols(usr, symbolname) " + "SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS " + "(SELECT usr FROM symbols WHERE usr == newsymbols.usr)", + database}; + WriteStatement insertSourcesStatement{ + "INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)", + database}; + WriteStatement syncNewSymbolsFromSymbolsStatement{ + "UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)", + database}; + WriteStatement syncSymbolsIntoNewLocationsStatement{ + "UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)", + database}; + WriteStatement deleteAllLocationsFromUpdatedFilesStatement{ + "DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)", + database}; + WriteStatement insertNewLocationsInLocationsStatement{ + "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations", + database}; + WriteStatement deleteNewSymbolsTableStatement{ + "DELETE FROM newSymbols", + database}; + WriteStatement deleteNewLocationsTableStatement{ + "DELETE FROM newLocations", + database}; +}; + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolentry.h b/src/tools/clangrefactoringbackend/source/symbolentry.h index 1b97d2f22bb82fb8ec330040761fb8cef35d0d64..432367e3c4ba8dce527eaa45a885f3478a3b357f 100644 --- a/src/tools/clangrefactoringbackend/source/symbolentry.h +++ b/src/tools/clangrefactoringbackend/source/symbolentry.h @@ -25,6 +25,8 @@ #pragma once +#include + #include #include @@ -36,6 +38,8 @@ namespace ClangBackEnd { +using SymbolIndex = long long; + class SymbolEntry { public: @@ -60,7 +64,7 @@ public: } }; -using SymbolEntries = std::unordered_map; +using SymbolEntries = std::unordered_map; std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry); diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.cpp b/src/tools/clangrefactoringbackend/source/symbolstorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..793f06f882b5a8c130cc55c68e96729fffbd0562 --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.cpp @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "symbolstorage.h" + +namespace ClangBackEnd { + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h new file mode 100644 index 0000000000000000000000000000000000000000..12163b0f25cce4e61155d60202f36126c02add46 --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "symbolstorageinterface.h" + +#include +#include + +namespace ClangBackEnd { + +template +class SymbolStorage : public SymbolStorageInterface +{ + using Transaction = Sqlite::SqliteImmediateTransaction; + using ReadStatement = typename StatementFactory::ReadStatementType; + using WriteStatement = typename StatementFactory::WriteStatementType; + using Database = typename StatementFactory::DatabaseType; + +public: + SymbolStorage(StatementFactory &statementFactory, + FilePathCache<> &filePathCache) + : m_statementFactory(statementFactory), + m_filePathCache(filePathCache) + { + } + + void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries, + const SourceLocationEntries &sourceLocations) override + { + Transaction transaction{m_statementFactory.database}; + + fillTemporarySymbolsTable(symbolEntries); + fillTemporaryLocationsTable(sourceLocations); + addNewSymbolsToSymbols(); + syncNewSymbolsFromSymbols(); + syncSymbolsIntoNewLocations(); + insertNewSources(); + deleteAllLocationsFromUpdatedFiles(); + insertNewLocationsInLocations(); + deleteNewSymbolsTable(); + deleteNewLocationsTable(); + + transaction.commit(); + } + + void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries) + { + WriteStatement &statement = m_statementFactory.insertSymbolsToNewSymbolsStatement; + + for (const auto &symbolEntry : symbolEntries) { + statement.write(symbolEntry.first, + symbolEntry.second.usr, + symbolEntry.second.symbolName); + } + } + + void fillTemporaryLocationsTable(const SourceLocationEntries &sourceLocations) + { + WriteStatement &statement = m_statementFactory.insertLocationsToNewLocationsStatement; + + for (const auto &locationsEntry : sourceLocations) { + statement.write(locationsEntry.symbolId, + locationsEntry.line, + locationsEntry.column, + locationsEntry.fileId); + } + } + + void addNewSymbolsToSymbols() + { + m_statementFactory.addNewSymbolsToSymbolsStatement.execute(); + } + + void syncNewSymbolsFromSymbols() + { + m_statementFactory.syncNewSymbolsFromSymbolsStatement.execute(); + } + + void syncSymbolsIntoNewLocations() + { + m_statementFactory.syncSymbolsIntoNewLocationsStatement.execute(); + } + + void deleteAllLocationsFromUpdatedFiles() + { + m_statementFactory.deleteAllLocationsFromUpdatedFilesStatement.execute(); + } + + void insertNewLocationsInLocations() + { + m_statementFactory.insertNewLocationsInLocationsStatement.execute(); + } + + FilePathIndices selectNewSourceIds() const + { + ReadStatement &statement = m_statementFactory.selectNewSourceIdsStatement; + + return statement.template values(16); + } + + void insertNewSources() + { + WriteStatement &statement = m_statementFactory.insertSourcesStatement; + + FilePathIndices newSourceIds = selectNewSourceIds(); + + for (FilePathIndex sourceId : newSourceIds) + statement.write(sourceId, m_filePathCache.string(sourceId)); + } + + void deleteNewSymbolsTable() + { + m_statementFactory.deleteNewSymbolsTableStatement.execute(); + } + + void deleteNewLocationsTable() + { + m_statementFactory.deleteNewLocationsTableStatement.execute(); + } + + SourceLocationEntries sourceLocations() const + { + return SourceLocationEntries(); + } + +private: + StatementFactory &m_statementFactory; + FilePathCache<> &m_filePathCache; +}; + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h index cea0ec8d7a456afa544af899a76e3aad83ddd695..05d449748c26bfee341cd813d57aad9379f3d5df 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h @@ -33,7 +33,7 @@ namespace ClangBackEnd { class SymbolStorageInterface { public: - virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEentries, + virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries, const SourceLocationEntries &sourceLocations) = 0; }; diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp index ebe57c3a3d8774994f45703b16580367145ea122..4bbadca3a3c49c2fbdfeb7ee8fb804e199f2b15d 100644 --- a/tests/unit/unittest/clangpathwatcher-test.cpp +++ b/tests/unit/unittest/clangpathwatcher-test.cpp @@ -42,11 +42,12 @@ using testing::NiceMock; using Watcher = ClangBackEnd::ClangPathWatcher, FakeTimer>; using ClangBackEnd::WatcherEntry; +using ClangBackEnd::FilePathIndices; class ClangPathWatcher : public testing::Test { protected: - ClangBackEnd::StringCache pathCache; + ClangBackEnd::FilePathCache<> pathCache; NiceMock notifier; Watcher watcher{pathCache, ¬ifier}; NiceMock &mockQFileSytemWatcher = watcher.fileSystemWatcher(); @@ -55,8 +56,8 @@ protected: Utils::SmallString id3{"id3"}; Utils::PathString path1{"/path/path1"}; Utils::PathString path2{"/path/path2"}; - std::vector paths = watcher.pathCache().stringIds({path1, path2}); - std::vector ids = watcher.idCache().stringIds({id1, id2, id3}); + FilePathIndices paths{watcher.pathCache().stringIds({path1, path2})}; + FilePathIndices ids{watcher.idCache().stringIds({id1, id2, id3})}; WatcherEntry watcherEntry1{ids[0], paths[0]}; WatcherEntry watcherEntry2{ids[1], paths[0]}; WatcherEntry watcherEntry3{ids[0], paths[1]}; diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp index 3b1a196e94dbad06b92e5370b2bee79f7a8ed994..792c234570a2bfb0e8db92b3ade80dc6ac654b89 100644 --- a/tests/unit/unittest/clangquery-test.cpp +++ b/tests/unit/unittest/clangquery-test.cpp @@ -33,7 +33,7 @@ #include using ClangBackEnd::ClangQuery; -using ClangBackEnd::StringCache; +using ClangBackEnd::FilePathCache; using testing::AllOf; using testing::Contains; @@ -48,7 +48,7 @@ protected: void SetUp() override; protected: - StringCache filePathCache; + FilePathCache filePathCache; ::ClangQuery simpleFunctionQuery{filePathCache}; ::ClangQuery simpleClassQuery{filePathCache}; }; diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp index 47719f031dec9f82304d5dfc91dcfb8873f102a6..a9a191383c11e09d1ae52b113364bbfec9167f24 100644 --- a/tests/unit/unittest/clangquerygatherer-test.cpp +++ b/tests/unit/unittest/clangquerygatherer-test.cpp @@ -75,7 +75,7 @@ protected: void SetUp() override; protected: - ClangBackEnd::StringCache filePathCache; + ClangBackEnd::FilePathCache filePathCache; Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"}; FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp index d2c0d06b7106aecc0a5784207923477e9e0f31d5..ad405e55d7d9f193d76e039cded5afecaa9c3cbf 100644 --- a/tests/unit/unittest/includecollector-test.cpp +++ b/tests/unit/unittest/includecollector-test.cpp @@ -43,7 +43,7 @@ protected: uint id(const Utils::SmallString &path); protected: - ClangBackEnd::StringCache filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; ClangBackEnd::IncludeCollector collector{filePathCache}; ClangBackEnd::IncludeCollector emptyCollector{filePathCache}; Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.h", diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h new file mode 100644 index 0000000000000000000000000000000000000000..55c06cb81e448ca424a4dc338b799adc6b081ee8 --- /dev/null +++ b/tests/unit/unittest/mocksqlitedatabase.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include + +#include + +class MockSqliteDatabase +{ +public: + MOCK_METHOD1(execute, + void (Utils::SmallStringView sqlStatement)); + +}; + diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1813b52c70b8f9c120358878c8487a44e4b3be4 --- /dev/null +++ b/tests/unit/unittest/mocksqlitereadstatement.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "mocksqlitereadstatement.h" + +template +std::vector values(std::size_t, QueryType...) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template +std::vector> values(std::size_t, + Utils::SmallStringView, + uint, + uint) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template class ContainerType, + typename ElementType> +std::vector> tupleValues(std::size_t, + const ContainerType &) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template <> +std::vector MockSqliteReadStatement::values(std::size_t reserveSize) +{ + return valuesReturnStdVectorInt(reserveSize); +} + +template <> +std::vector> +MockSqliteReadStatement::tupleValues( + std::size_t reserveSize, + const Utils::PathString &sourcePath, + const uint &line, + const uint &column) +{ + return valuesReturnStdVectorTupleInt64Int64Int64(reserveSize, sourcePath, line, column); +} + +template <> +std::vector> +MockSqliteReadStatement::tupleValues(std::size_t reserveSize, + const std::vector &sourceIds) +{ + return valuesReturnStdVectorTupleInt64PathString(reserveSize, sourceIds); +} diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h new file mode 100644 index 0000000000000000000000000000000000000000..7e45bd3952777ab03dd9f9b8980b0adb19404f0e --- /dev/null +++ b/tests/unit/unittest/mocksqlitereadstatement.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include "mocksqlitedatabase.h" + +#include + +#include +#include +#include + +using std::int64_t; +using ClangBackEnd::FilePathIndex; + +class MockSqliteReadStatement +{ +public: + MockSqliteReadStatement() = default; + MockSqliteReadStatement(Utils::SmallStringView sqlStatement, MockSqliteDatabase &) + : sqlStatement(sqlStatement) + {} + + MOCK_CONST_METHOD1(valuesReturnStdVectorInt, + std::vector(std::size_t)); + + MOCK_CONST_METHOD4(valuesReturnStdVectorTupleInt64Int64Int64, + std::vector>(std::size_t, Utils::SmallStringView, int64_t, int64_t)); + + MOCK_CONST_METHOD2(valuesReturnStdVectorTupleInt64PathString, + std::vector>(std::size_t, const std::vector &)); + + template + std::vector values(std::size_t, QueryType...); + + template + std::vector> tupleValues(std::size_t reserveSize, const QueryType&... queryValues); + + template class ContainerType, + typename ElementType> + std::vector> tupleValues(std::size_t reserveSize, const ContainerType &queryValues); + + +public: + Utils::SmallString sqlStatement; +}; + +template <> +std::vector MockSqliteReadStatement::values(std::size_t reserveSize); + +template <> +std::vector> +MockSqliteReadStatement::tupleValues( + std::size_t reserveSize, + const Utils::PathString &sourcePath, + const uint &line, + const uint &column); + +template <> +std::vector> +MockSqliteReadStatement::tupleValues(std::size_t reserveSize, + const std::vector &); + + diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h new file mode 100644 index 0000000000000000000000000000000000000000..98ea4e7e249c00ee8d17bae91afee2d92e8d4dcc --- /dev/null +++ b/tests/unit/unittest/mocksqlitewritestatement.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "mocksqlitedatabase.h" + +#include + +class MockSqliteWriteStatement +{ +public: + MockSqliteWriteStatement() = default; + MockSqliteWriteStatement(Utils::SmallStringView sqlStatement, MockSqliteDatabase &) + : sqlStatement(sqlStatement) + {} + + MOCK_METHOD0(execute, + void ()); + + MOCK_METHOD2(bind, + void (int index, Utils::SmallStringView value)); + + MOCK_METHOD2(bindValues, + void (Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD3(write, + void (uint, Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD4(write, + void (uint, uint, uint, uint)); + + MOCK_METHOD2(write, + void (uint, Utils::SmallStringView)); + + Utils::SmallString sqlStatement; +}; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 12cd50b8e5fdeca9f6c2c588adfbc332ee26c18a..f03b0cd25e12206fa4f80330a86dc8bcfe2c84c4 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -68,7 +68,7 @@ protected: uint id(const Utils::PathString &path); protected: - ClangBackEnd::StringCache filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp"; PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp"; PathString header1Path = TESTDATA_DIR "/includecollector_header1.h"; diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 8ac039b16ab515a64c4ac56498e5fc0c1c1161d5..b9b170e3dc88510f491aea5fd67fd36f37748719 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -59,7 +59,7 @@ protected: NiceMock mockPchCreator; NiceMock mockClangPathWatcher; NiceMock mockProjectParts; - ClangBackEnd::StringCache filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts}; NiceMock mockPchManagerClient; SmallString projectPartId1 = "project1"; diff --git a/tests/unit/unittest/sourcerangeextractor-test.cpp b/tests/unit/unittest/sourcerangeextractor-test.cpp index 42f2f0f724662ad62d47ce475bc694fd5528abd1..d20cd9bb93d563310bb523129fbfd06d95d03a1e 100644 --- a/tests/unit/unittest/sourcerangeextractor-test.cpp +++ b/tests/unit/unittest/sourcerangeextractor-test.cpp @@ -54,7 +54,7 @@ protected: TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}}; ClangBackEnd::SourceRangesContainer sourceRangesContainer; const clang::SourceManager &sourceManager{clangTool.sourceManager()}; - ClangBackEnd::StringCache filePathCache; + ClangBackEnd::FilePathCache filePathCache; ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer}; clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()); clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4); diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index b3523bdc77056130b5fda29a20d0cba721f25913..c052367a8bd7132dd8901b04f2ed0be023fa2009 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -340,7 +340,6 @@ TEST_F(SqliteStatement, GetStructValuesWithoutArguments) Output{"poo", "40", 3})); } - TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes) { SqliteReadStatement statement("SELECT name FROM test WHERE number=?", database); diff --git a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98c99d908e22534a2129aa79c4b62e91f1c09bb6 --- /dev/null +++ b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" + +#include "mocksqlitedatabase.h" +#include "mocksqlitereadstatement.h" +#include "mocksqlitewritestatement.h" + +#include + +namespace { + +using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory, + MockSqliteReadStatement, + MockSqliteWriteStatement>; + +using Sqlite::SqliteTable; + +class StorageSqliteStatementFactory : public testing::Test +{ +protected: + NiceMock mockDatabase; + StatementFactory factory{mockDatabase}; +}; + +TEST_F(StorageSqliteStatementFactory, AddSymbolsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createSymbolsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddLocationsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createLocationsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddSourcesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createSourcesTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddNewSymbolsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createNewSymbolsTable(); +} + + +TEST_F(StorageSqliteStatementFactory, AddNewLocationsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createNewLocationsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor) +{ + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))).Times(5); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))).Times(5); + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + + StatementFactory factory{mockDatabase}; +} + +TEST_F(StorageSqliteStatementFactory, InsertNewSymbolsStatement) +{ + ASSERT_THAT(factory.insertSymbolsToNewSymbolsStatement.sqlStatement, + Eq("INSERT INTO newSymbols(temporarySymbolId, usr, symbolName) VALUES(?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertNewLocationsToLocations) +{ + ASSERT_THAT(factory.insertLocationsToNewLocationsStatement.sqlStatement, + Eq("INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement) +{ + ASSERT_THAT(factory.selectNewSourceIdsStatement.sqlStatement, + Eq("SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)")); +} + +TEST_F(StorageSqliteStatementFactory, AddNewSymbolsToSymbolsStatement) +{ + ASSERT_THAT(factory.addNewSymbolsToSymbolsStatement.sqlStatement, + Eq("INSERT INTO symbols(usr, symbolname) SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE usr == newsymbols.usr)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertSourcesStatement) +{ + ASSERT_THAT(factory.insertSourcesStatement.sqlStatement, + Eq("INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncNewSymbolsFromSymbolsStatement) +{ + ASSERT_THAT(factory.syncNewSymbolsFromSymbolsStatement.sqlStatement, + Eq("UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncSymbolsIntoNewLocations) +{ + ASSERT_THAT(factory.syncSymbolsIntoNewLocationsStatement.sqlStatement, + Eq("UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteAllLocationsFromUpdatedFiles) +{ + ASSERT_THAT(factory.deleteAllLocationsFromUpdatedFilesStatement.sqlStatement, + Eq("DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertNewLocationsInLocations) +{ + ASSERT_THAT(factory.insertNewLocationsInLocationsStatement.sqlStatement, + Eq("INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteNewSymbolsTableStatement) +{ + ASSERT_THAT(factory.deleteNewSymbolsTableStatement.sqlStatement, + Eq("DELETE FROM newSymbols")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteNewLocationsTableStatement) +{ + ASSERT_THAT(factory.deleteNewLocationsTableStatement.sqlStatement, + Eq("DELETE FROM newLocations")); +} + +} + diff --git a/tests/unit/unittest/stringcache-test.cpp b/tests/unit/unittest/stringcache-test.cpp index 265555f35c5a193f7ada6c92985844b9742352d6..a4f989ba0230887719068f533c5e6cf5a2cf7d48 100644 --- a/tests/unit/unittest/stringcache-test.cpp +++ b/tests/unit/unittest/stringcache-test.cpp @@ -31,13 +31,16 @@ namespace { -using ClangBackEnd::StringCacheEntries; using ClangBackEnd::StringCacheException; +using uint64 = unsigned long long; + +using CacheEntries = ClangBackEnd::FileCacheCacheEntries; + class StringCache : public testing::Test { protected: - ClangBackEnd::StringCache cache; + ClangBackEnd::FilePathCache<> cache; Utils::PathString filePath1{"/file/pathOne"}; Utils::PathString filePath2{"/file/pathTwo"}; Utils::PathString filePath3{"/file/pathThree"}; @@ -144,7 +147,7 @@ TEST_F(StringCache, IsNotEmpty) TEST_F(StringCache, PopulateWithEmptyVector) { - StringCacheEntries entries; + CacheEntries entries; cache.uncheckedPopulate(std::move(entries)); @@ -153,10 +156,10 @@ TEST_F(StringCache, PopulateWithEmptyVector) TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries) { - StringCacheEntries entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; cache.uncheckedPopulate(std::move(entries)); @@ -165,10 +168,10 @@ TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries) TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries) { - StringCacheEntries entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; cache.uncheckedPopulate(std::move(entries)); auto string = cache.string(2); @@ -178,30 +181,30 @@ TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries) TEST_F(StringCache, EntriesHaveUniqueIds) { - StringCacheEntries entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 2}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 2}}; ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException); } TEST_F(StringCache, IdsAreHigherLowerEntriesSize) { - StringCacheEntries entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 4}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 4}, + {filePath4.clone(), 3}}; ASSERT_THROW(cache.populate(std::move(entries)), std::out_of_range); } TEST_F(StringCache, MultipleEntries) { - StringCacheEntries entries{{filePath1.clone(), 0}, - {filePath1.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath1.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException); } diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 15e15ba5f14d0617b5b80b00db4c051b5bb21ab7..4543c61e446c07598bca52a8aa5d618d297944c5 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -42,6 +42,7 @@ using testing::_; using ClangBackEnd::SourceLocationEntry; using ClangBackEnd::SymbolEntry; using ClangBackEnd::SymbolType; +using ClangBackEnd::SymbolIndex; namespace { @@ -53,7 +54,7 @@ protected: return filePathCache.stringId(string); } - uint symbolIdForSymbolName(const Utils::SmallString &symbolName); + SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName); protected: ClangBackEnd::FilePathCache<> filePathCache; @@ -149,7 +150,7 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation) Field(&SourceLocationEntry::column, 5)))); } -uint SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName) +SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName) { for (const auto &entry : collector.symbols()) { if (entry.second.symbolName == symbolName) diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec30b9289df93306c2c140c5561c37f3bed7f3ae --- /dev/null +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" + +#include "mocksqlitereadstatement.h" +#include "mocksqlitewritestatement.h" + +#include +#include +#include + +#include + +namespace { + +using Utils::PathString; +using ClangBackEnd::FilePathCache; +using ClangBackEnd::SymbolEntries; +using ClangBackEnd::SymbolEntry; +using ClangBackEnd::SourceLocationEntries; +using ClangBackEnd::SourceLocationEntry; +using ClangBackEnd::StorageSqliteStatementFactory; +using ClangBackEnd::SymbolType; +using Sqlite::SqliteDatabase; +using Sqlite::SqliteTable; + +using StatementFactory = StorageSqliteStatementFactory; +using Storage = ClangBackEnd::SymbolStorage; + +class SymbolStorage : public testing::Test +{ +protected: + void SetUp(); + +protected: + FilePathCache<> filePathCache; + NiceMock mockDatabase; + StatementFactory statementFactory{mockDatabase}; + + MockSqliteWriteStatement &insertSymbolsToNewSymbolsStatement = statementFactory.insertSymbolsToNewSymbolsStatement; + MockSqliteWriteStatement &insertLocationsToNewLocationsStatement = statementFactory.insertLocationsToNewLocationsStatement; + MockSqliteWriteStatement &insertSourcesStatement = statementFactory.insertSourcesStatement; + MockSqliteReadStatement &selectNewSourceIdsStatement = statementFactory.selectNewSourceIdsStatement; + MockSqliteWriteStatement &addNewSymbolsToSymbolsStatement = statementFactory.addNewSymbolsToSymbolsStatement; + MockSqliteWriteStatement &syncNewSymbolsFromSymbolsStatement = statementFactory.syncNewSymbolsFromSymbolsStatement; + MockSqliteWriteStatement &syncSymbolsIntoNewLocationsStatement = statementFactory.syncSymbolsIntoNewLocationsStatement; + MockSqliteWriteStatement &deleteAllLocationsFromUpdatedFilesStatement = statementFactory.deleteAllLocationsFromUpdatedFilesStatement; + MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = statementFactory.insertNewLocationsInLocationsStatement; + MockSqliteWriteStatement &deleteNewSymbolsTableStatement = statementFactory.deleteNewSymbolsTableStatement; + MockSqliteWriteStatement &deleteNewLocationsTableStatement = statementFactory.deleteNewLocationsTableStatement; + SymbolEntries symbolEntries{{1, {"functionUSR", "function"}}, + {2, {"function2USR", "function2"}}}; + SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SymbolType::Declaration}, + {2, 4, {7, 11}, SymbolType::Declaration}}; + Storage storage{statementFactory, filePathCache}; +}; + +TEST_F(SymbolStorage, CreateAndFillTemporaryLocationsTable) +{ + InSequence sequence; + + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + + storage.fillTemporaryLocationsTable(sourceLocations); +} + +TEST_F(SymbolStorage, AddNewSymbolsToSymbols) +{ + EXPECT_CALL(addNewSymbolsToSymbolsStatement, execute()); + + storage.addNewSymbolsToSymbols(); +} + +TEST_F(SymbolStorage, SyncNewSymbolsFromSymbols) +{ + EXPECT_CALL(syncNewSymbolsFromSymbolsStatement, execute()); + + storage.syncNewSymbolsFromSymbols(); +} + +TEST_F(SymbolStorage, SyncSymbolsIntoNewLocations) +{ + EXPECT_CALL(syncSymbolsIntoNewLocationsStatement, execute()); + + storage.syncSymbolsIntoNewLocations(); +} + +TEST_F(SymbolStorage, DeleteAllLocationsFromUpdatedFiles) +{ + EXPECT_CALL(deleteAllLocationsFromUpdatedFilesStatement, execute()); + + storage.deleteAllLocationsFromUpdatedFiles(); +} + +TEST_F(SymbolStorage, InsertNewLocationsInLocations) +{ + EXPECT_CALL(insertNewLocationsInLocationsStatement, execute()); + + storage.insertNewLocationsInLocations(); +} + +TEST_F(SymbolStorage, SelectNewSourceIdsCalls) +{ + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + storage.selectNewSourceIds(); +} + +TEST_F(SymbolStorage, SelectNewSourceIds) +{ + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + auto sourceIds = storage.selectNewSourceIds(); + + ASSERT_THAT(sourceIds, ElementsAre(0, 1, 2)); +} + +TEST_F(SymbolStorage, InserNewSources) +{ + InSequence sequence; + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + EXPECT_CALL(insertSourcesStatement, write(0, Eq("/path/to/source1"))); + EXPECT_CALL(insertSourcesStatement, write(1, Eq("/path/to/source2"))); + EXPECT_CALL(insertSourcesStatement, write(2, Eq("/path/to/source3"))); + + storage.insertNewSources(); +} + + +TEST_F(SymbolStorage, DropNewSymbolsTable) +{ + EXPECT_CALL(deleteNewSymbolsTableStatement, execute()); + + storage.deleteNewSymbolsTable(); +} + +TEST_F(SymbolStorage, DropNewLocationsTable) +{ + EXPECT_CALL(deleteNewLocationsTableStatement, execute()); + + storage.deleteNewLocationsTable(); +} + +TEST_F(SymbolStorage, AddSymbolsAndSourceLocationsCallsWrite) +{ + InSequence sequence; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(insertSymbolsToNewSymbolsStatement, write(_, _, _)).Times(2); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + EXPECT_CALL(addNewSymbolsToSymbolsStatement, execute()); + EXPECT_CALL(syncNewSymbolsFromSymbolsStatement, execute()); + EXPECT_CALL(syncSymbolsIntoNewLocationsStatement, execute()); + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + EXPECT_CALL(insertSourcesStatement, write(0, Eq("/path/to/source1"))); + EXPECT_CALL(insertSourcesStatement, write(1, Eq("/path/to/source2"))); + EXPECT_CALL(insertSourcesStatement, write(2, Eq("/path/to/source3"))); + EXPECT_CALL(deleteAllLocationsFromUpdatedFilesStatement, execute()); + EXPECT_CALL(insertNewLocationsInLocationsStatement, execute()); + EXPECT_CALL(deleteNewSymbolsTableStatement, execute()); + EXPECT_CALL(deleteNewLocationsTableStatement, execute()); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + storage.addSymbolsAndSourceLocations(symbolEntries, sourceLocations); +} + +void SymbolStorage::SetUp() +{ + ON_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)) + .WillByDefault(Return(std::vector{0, 1, 2})); + + filePathCache.stringIds({"/path/to/source1", "/path/to/source2", "/path/to/source3"}); +} +} + diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 7c44c4f4ad9cd289095e7a50a66ab0812c98a03e..667aeaa5d707f4facc0c55c52d023f4a215fe123 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -69,7 +69,10 @@ SOURCES += \ symbolindexer-test.cpp \ stringcache-test.cpp \ unittests-main.cpp \ - utf8-test.cpp + utf8-test.cpp \ + symbolstorage-test.cpp \ + storagesqlitestatementfactory-test.cpp \ + mocksqlitereadstatement.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -188,7 +191,11 @@ HEADERS += \ spydummy.h \ testenvironment.h \ mocksymbolscollector.h \ - mocksymbolstorage.h + mocksymbolstorage.h \ + mocksqlitewritestatement.h \ + mocksqlitedatabase.h \ + mocksqlitereadstatement.h \ + google-using-directive.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \