forked from qt-creator/qt-creator
Clang: Add symbol storage
Extend file path cache to 64 bit integer. Change-Id: I5627f13d59a3214f389087038482cbcc8d0eb484 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "stringcachefwd.h"
|
||||||
|
|
||||||
#include <utils/smallstringview.h>
|
#include <utils/smallstringview.h>
|
||||||
#include <utils/smallstringfwd.h>
|
#include <utils/smallstringfwd.h>
|
||||||
|
|
||||||
@@ -52,11 +54,11 @@ public:
|
|||||||
void unlock() {}
|
void unlock() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType, typename IndexType>
|
||||||
class StringCacheEntry
|
class StringCacheEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StringCacheEntry(StringType &&string, uint id)
|
StringCacheEntry(StringType &&string, IndexType id)
|
||||||
: string(std::move(string)),
|
: string(std::move(string)),
|
||||||
id(id)
|
id(id)
|
||||||
{}
|
{}
|
||||||
@@ -77,22 +79,27 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringType string;
|
StringType string;
|
||||||
uint id;
|
IndexType id;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType, typename IndexType>
|
||||||
using StringCacheEntries = std::vector<StringCacheEntry<StringType>>;
|
using StringCacheEntries = std::vector<StringCacheEntry<StringType, IndexType>>;
|
||||||
|
|
||||||
|
using FileCacheCacheEntry = StringCacheEntry<Utils::PathString, FilePathIndex>;
|
||||||
|
using FileCacheCacheEntries = std::vector<FileCacheCacheEntry>;
|
||||||
|
|
||||||
template <typename StringType,
|
template <typename StringType,
|
||||||
typename Mutex = NonLockingMutex>
|
typename IndexType,
|
||||||
|
typename Mutex>
|
||||||
class StringCache
|
class StringCache
|
||||||
{
|
{
|
||||||
using const_iterator = typename StringCacheEntries<StringType>::const_iterator;
|
using CacheEnties = StringCacheEntries<StringType, IndexType>;
|
||||||
|
using const_iterator = typename CacheEnties::const_iterator;
|
||||||
|
|
||||||
class Found
|
class Found
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typename StringCacheEntries<StringType>::const_iterator iterator;
|
typename CacheEnties::const_iterator iterator;
|
||||||
bool wasFound;
|
bool wasFound;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,14 +110,14 @@ public:
|
|||||||
m_indices.reserve(1024);
|
m_indices.reserve(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate(StringCacheEntries<StringType> &&entries)
|
void populate(CacheEnties &&entries)
|
||||||
{
|
{
|
||||||
uncheckedPopulate(std::move(entries));
|
uncheckedPopulate(std::move(entries));
|
||||||
|
|
||||||
checkEntries();
|
checkEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uncheckedPopulate(StringCacheEntries<StringType> &&entries)
|
void uncheckedPopulate(CacheEnties &&entries)
|
||||||
{
|
{
|
||||||
std::sort(entries.begin(), entries.end());
|
std::sort(entries.begin(), entries.end());
|
||||||
|
|
||||||
@@ -123,7 +130,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint stringId(Utils::SmallStringView stringView)
|
IndexType stringId(Utils::SmallStringView stringView)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(m_mutex);
|
std::lock_guard<Mutex> lock(m_mutex);
|
||||||
|
|
||||||
@@ -136,11 +143,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
std::vector<uint> stringIds(const Container &strings)
|
std::vector<IndexType> stringIds(const Container &strings)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(m_mutex);
|
std::lock_guard<Mutex> lock(m_mutex);
|
||||||
|
|
||||||
std::vector<uint> ids;
|
std::vector<IndexType> ids;
|
||||||
ids.reserve(strings.size());
|
ids.reserve(strings.size());
|
||||||
|
|
||||||
std::transform(strings.begin(),
|
std::transform(strings.begin(),
|
||||||
@@ -151,19 +158,19 @@ public:
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> stringIds(std::initializer_list<StringType> strings)
|
std::vector<IndexType> stringIds(std::initializer_list<StringType> strings)
|
||||||
{
|
{
|
||||||
return stringIds<std::initializer_list<StringType>>(strings);
|
return stringIds<std::initializer_list<StringType>>(strings);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::SmallStringView string(uint id) const
|
Utils::SmallStringView string(IndexType id) const
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(m_mutex);
|
std::lock_guard<Mutex> lock(m_mutex);
|
||||||
|
|
||||||
return m_strings.at(m_indices.at(id)).string;
|
return m_strings.at(m_indices.at(id)).string;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<StringType> strings(const std::vector<uint> &ids) const
|
std::vector<StringType> strings(const std::vector<IndexType> &ids) const
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(m_mutex);
|
std::lock_guard<Mutex> lock(m_mutex);
|
||||||
|
|
||||||
@@ -173,7 +180,7 @@ public:
|
|||||||
std::transform(ids.begin(),
|
std::transform(ids.begin(),
|
||||||
ids.end(),
|
ids.end(),
|
||||||
std::back_inserter(strings),
|
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;
|
return strings;
|
||||||
}
|
}
|
||||||
@@ -191,24 +198,24 @@ private:
|
|||||||
return {range.first, range.first != range.second};
|
return {range.first, range.first != range.second};
|
||||||
}
|
}
|
||||||
|
|
||||||
void incrementLargerOrEqualIndicesByOne(uint newIndex)
|
void incrementLargerOrEqualIndicesByOne(IndexType newIndex)
|
||||||
{
|
{
|
||||||
std::transform(m_indices.begin(),
|
std::transform(m_indices.begin(),
|
||||||
m_indices.end(),
|
m_indices.end(),
|
||||||
m_indices.begin(),
|
m_indices.begin(),
|
||||||
[&] (uint index) {
|
[&] (IndexType index) {
|
||||||
return index >= newIndex ? ++index : index;
|
return index >= newIndex ? ++index : index;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
uint insertString(const_iterator beforeIterator,
|
IndexType insertString(const_iterator beforeIterator,
|
||||||
Utils::SmallStringView stringView)
|
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 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);
|
incrementLargerOrEqualIndicesByOne(newIndex);
|
||||||
|
|
||||||
@@ -226,12 +233,13 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCacheEntries<StringType> m_strings;
|
CacheEnties m_strings;
|
||||||
std::vector<uint> m_indices;
|
std::vector<IndexType> m_indices;
|
||||||
mutable Mutex m_mutex;
|
mutable Mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Mutex = NonLockingMutex>
|
template <typename Mutex>
|
||||||
using FilePathCache = StringCache<Utils::PathString, Mutex>;
|
using FilePathCache = StringCache<Utils::PathString, FilePathIndex, Mutex>;
|
||||||
|
using FilePathIndices = std::vector<FilePathIndex>;
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -29,14 +29,17 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
using FilePathIndex = long long int;
|
||||||
|
|
||||||
class NonLockingMutex;
|
class NonLockingMutex;
|
||||||
|
|
||||||
template <typename StringType,
|
template <typename StringType,
|
||||||
|
typename IndexType,
|
||||||
typename Mutex>
|
typename Mutex>
|
||||||
class StringCache;
|
class StringCache;
|
||||||
|
|
||||||
template <typename Mutex = NonLockingMutex>
|
template <typename Mutex = NonLockingMutex>
|
||||||
using FilePathCache = StringCache<Utils::PathString, Mutex>;
|
using FilePathCache = StringCache<Utils::PathString, FilePathIndex, Mutex>;
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
|
|||||||
@@ -83,27 +83,27 @@ protected:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Values>
|
template<typename... ValueType>
|
||||||
void bindValues(Values... values)
|
void bindValues(ValueType... values)
|
||||||
{
|
{
|
||||||
bindValuesByIndex(1, values...);
|
bindValuesByIndex(1, values...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Values>
|
template<typename... ValueType>
|
||||||
void write(Values... values)
|
void write(ValueType... values)
|
||||||
{
|
{
|
||||||
bindValuesByIndex(1, values...);
|
bindValuesByIndex(1, values...);
|
||||||
execute();
|
execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Values>
|
template<typename... ValueType>
|
||||||
void bindNameValues(Values... values)
|
void bindNameValues(ValueType... values)
|
||||||
{
|
{
|
||||||
bindValuesByName(values...);
|
bindValuesByName(values...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Values>
|
template<typename... ValueType>
|
||||||
void writeNamed(Values... values)
|
void writeNamed(ValueType... values)
|
||||||
{
|
{
|
||||||
bindValuesByName(values...);
|
bindValuesByName(values...);
|
||||||
execute();
|
execute();
|
||||||
@@ -117,45 +117,45 @@ protected:
|
|||||||
void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
|
void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
|
||||||
const Utils::SmallStringVector &bindingColumnNames() const;
|
const Utils::SmallStringVector &bindingColumnNames() const;
|
||||||
|
|
||||||
template <typename... ResultType>
|
template <typename... ResultTypes>
|
||||||
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize)
|
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize)
|
||||||
{
|
{
|
||||||
using Container = std::vector<std::tuple<ResultType...>>;
|
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
emplaceTupleValues<Container, ResultType...>(resultValues);
|
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
return resultValues;
|
return resultValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... ResultType,
|
template <typename... ResultTypes,
|
||||||
typename... QueryType>
|
typename... QueryTypes>
|
||||||
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const QueryType&... queryValues)
|
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||||
{
|
{
|
||||||
using Container = std::vector<std::tuple<ResultType...>>;
|
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
|
|
||||||
bindValues(queryValues...);
|
bindValues(queryValues...);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
emplaceTupleValues<Container, ResultType...>(resultValues);
|
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
return resultValues;
|
return resultValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... ResultType,
|
template <typename... ResultTypes,
|
||||||
typename... ElementType>
|
typename... QueryElementTypes>
|
||||||
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize,
|
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||||
const std::vector<std::tuple<ElementType...>> &queryTuples)
|
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||||
{
|
{
|
||||||
using Container = std::vector<std::tuple<ResultType...>>;
|
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ protected:
|
|||||||
bindTupleValues(queryTuple);
|
bindTupleValues(queryTuple);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
emplaceTupleValues<Container, ResultType...>(resultValues);
|
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -171,12 +171,12 @@ protected:
|
|||||||
return resultValues;
|
return resultValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... ResultType,
|
template <typename... ResultTypes,
|
||||||
typename QueryElementType>
|
typename QueryElementType>
|
||||||
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize,
|
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||||
const std::vector<QueryElementType> &queryValues)
|
const std::vector<QueryElementType> &queryValues)
|
||||||
{
|
{
|
||||||
using Container = std::vector<std::tuple<ResultType...>>;
|
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ protected:
|
|||||||
bindValues(queryValue);
|
bindValues(queryValue);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
emplaceTupleValues<Container, ResultType...>(resultValues);
|
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... ResultEntryType>
|
typename... ResultEntryTypes>
|
||||||
std::vector<ResultType> structValues(std::size_t reserveSize)
|
std::vector<ResultType> structValues(std::size_t reserveSize)
|
||||||
{
|
{
|
||||||
using Container = std::vector<ResultType>;
|
using Container = std::vector<ResultType>;
|
||||||
@@ -201,7 +201,7 @@ protected:
|
|||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
pushBackStructValues<Container, ResultEntryType...>(resultValues);
|
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
@@ -209,9 +209,9 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... ResultEntryType,
|
typename... ResultEntryTypes,
|
||||||
typename... QueryType>
|
typename... QueryTypes>
|
||||||
std::vector<ResultType> structValues(std::size_t reserveSize, const QueryType&... queryValues)
|
std::vector<ResultType> structValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||||
{
|
{
|
||||||
using Container = std::vector<ResultType>;
|
using Container = std::vector<ResultType>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
@@ -220,7 +220,7 @@ protected:
|
|||||||
bindValues(queryValues...);
|
bindValues(queryValues...);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
pushBackStructValues<Container, ResultEntryType...>(resultValues);
|
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... ResultEntryType,
|
typename... ResultEntryTypes,
|
||||||
typename QueryElementType>
|
typename QueryElementType>
|
||||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||||
const std::vector<QueryElementType> &queryValues)
|
const std::vector<QueryElementType> &queryValues)
|
||||||
@@ -241,7 +241,7 @@ protected:
|
|||||||
bindValues(queryValue);
|
bindValues(queryValue);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
pushBackStructValues<Container, ResultEntryType...>(resultValues);
|
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -250,10 +250,10 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... ResultEntryType,
|
typename... ResultEntryTypes,
|
||||||
typename... QueryElementType>
|
typename... QueryElementTypes>
|
||||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||||
const std::vector<std::tuple<QueryElementType...>> &queryTuples)
|
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||||
{
|
{
|
||||||
using Container = std::vector<ResultType>;
|
using Container = std::vector<ResultType>;
|
||||||
Container resultValues;
|
Container resultValues;
|
||||||
@@ -263,7 +263,7 @@ protected:
|
|||||||
bindTupleValues(queryTuple);
|
bindTupleValues(queryTuple);
|
||||||
|
|
||||||
while (next())
|
while (next())
|
||||||
pushBackStructValues<Container, ResultEntryType...>(resultValues);
|
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... ElementType>
|
typename... ElementTypes>
|
||||||
std::vector<ResultType> values(std::size_t reserveSize)
|
std::vector<ResultType> values(std::size_t reserveSize)
|
||||||
{
|
{
|
||||||
std::vector<ResultType> resultValues;
|
std::vector<ResultType> resultValues;
|
||||||
@@ -327,8 +327,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ResultType,
|
template <typename ResultType,
|
||||||
typename... QueryType>
|
typename... QueryTypes>
|
||||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryType&... queryValues)
|
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||||
{
|
{
|
||||||
std::vector<ResultType> resultValues;
|
std::vector<ResultType> resultValues;
|
||||||
resultValues.reserve(reserveSize);
|
resultValues.reserve(reserveSize);
|
||||||
@@ -379,74 +379,74 @@ protected:
|
|||||||
SqliteDatabaseBackend &databaseBackend);
|
SqliteDatabaseBackend &databaseBackend);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Container,
|
template <typename ContainerType,
|
||||||
typename... ResultType,
|
typename... ResultTypes,
|
||||||
int... Index>
|
int... ColumnIndices>
|
||||||
void emplaceTupleValues(Container &container, std::integer_sequence<int, Index...>)
|
void emplaceTupleValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||||
{
|
{
|
||||||
container.emplace_back(value<ResultType>(Index)...);
|
container.emplace_back(value<ResultTypes>(ColumnIndices)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container,
|
template <typename ContainerType,
|
||||||
typename... ResultType>
|
typename... ResultTypes>
|
||||||
void emplaceTupleValues(Container &container)
|
void emplaceTupleValues(ContainerType &container)
|
||||||
{
|
{
|
||||||
emplaceTupleValues<Container, ResultType...>(container, std::make_integer_sequence<int, sizeof...(ResultType)>{});
|
emplaceTupleValues<ContainerType, ResultTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultTypes)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container,
|
template <typename ContainerType,
|
||||||
typename... ResultEntryType,
|
typename... ResultEntryTypes,
|
||||||
int... Index>
|
int... ColumnIndices>
|
||||||
void pushBackStructValues(Container &container, std::integer_sequence<int, Index...>)
|
void pushBackStructValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||||
{
|
{
|
||||||
using ResultType = typename Container::value_type;
|
using ResultType = typename ContainerType::value_type;
|
||||||
container.push_back(ResultType{value<ResultEntryType>(Index)...});
|
container.push_back(ResultType{value<ResultEntryTypes>(ColumnIndices)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container,
|
template <typename ContainerType,
|
||||||
typename... ResultEntryType>
|
typename... ResultEntryTypes>
|
||||||
void pushBackStructValues(Container &container)
|
void pushBackStructValues(ContainerType &container)
|
||||||
{
|
{
|
||||||
pushBackStructValues<Container, ResultEntryType...>(container, std::make_integer_sequence<int, sizeof...(ResultEntryType)>{});
|
pushBackStructValues<ContainerType, ResultEntryTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultEntryTypes)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename ValueType>
|
||||||
void bindValuesByIndex(int index, Type value)
|
void bindValuesByIndex(int index, ValueType value)
|
||||||
{
|
{
|
||||||
bind(index, value);
|
bind(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename... Value>
|
template<typename ValueType, typename... ValueTypes>
|
||||||
void bindValuesByIndex(int index, Type value, Value... values)
|
void bindValuesByIndex(int index, ValueType value, ValueTypes... values)
|
||||||
{
|
{
|
||||||
bind(index, value);
|
bind(index, value);
|
||||||
bindValuesByIndex(index + 1, values...);
|
bindValuesByIndex(index + 1, values...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename ValueType>
|
||||||
void bindValuesByName(Utils::SmallStringView name, Type value)
|
void bindValuesByName(Utils::SmallStringView name, ValueType value)
|
||||||
{
|
{
|
||||||
bind(bindingIndexForName(name), value);
|
bind(bindingIndexForName(name), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename... Values>
|
template<typename ValueType, typename... ValueTypes>
|
||||||
void bindValuesByName(Utils::SmallStringView name, Type value, Values... values)
|
void bindValuesByName(Utils::SmallStringView name, ValueType value, ValueTypes... values)
|
||||||
{
|
{
|
||||||
bind(bindingIndexForName(name), value);
|
bind(bindingIndexForName(name), value);
|
||||||
bindValuesByName(values...);
|
bindValuesByName(values...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TupleType, std::size_t... Index>
|
template <typename TupleType, std::size_t... ColumnIndices>
|
||||||
void bindTupleValuesElement(const TupleType &tuple, std::index_sequence<Index...>)
|
void bindTupleValuesElement(const TupleType &tuple, std::index_sequence<ColumnIndices...>)
|
||||||
{
|
{
|
||||||
bindValues(std::get<Index>(tuple)...);
|
bindValues(std::get<ColumnIndices>(tuple)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TupleType,
|
template <typename TupleType,
|
||||||
typename Indices = std::make_index_sequence<std::tuple_size<TupleType>::value>>
|
typename ColumnIndices = std::make_index_sequence<std::tuple_size<TupleType>::value>>
|
||||||
void bindTupleValues(const TupleType &element)
|
void bindTupleValues(const TupleType &element)
|
||||||
{
|
{
|
||||||
bindTupleValuesElement(element, Indices());
|
bindTupleValuesElement(element, ColumnIndices());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ public:
|
|||||||
return m_pointer[0] == characterToSearch;
|
return m_pointer[0] == characterToSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *m_pointer;
|
const char *m_pointer;
|
||||||
size_type m_size;
|
size_type m_size;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ using ClangBackEnd::PchGenerator;
|
|||||||
using ClangBackEnd::PchManagerClientProxy;
|
using ClangBackEnd::PchManagerClientProxy;
|
||||||
using ClangBackEnd::PchManagerServer;
|
using ClangBackEnd::PchManagerServer;
|
||||||
using ClangBackEnd::ProjectParts;
|
using ClangBackEnd::ProjectParts;
|
||||||
using ClangBackEnd::StringCache;
|
using ClangBackEnd::FilePathCache;
|
||||||
|
|
||||||
class ApplicationEnvironment : public ClangBackEnd::Environment
|
class ApplicationEnvironment : public ClangBackEnd::Environment
|
||||||
{
|
{
|
||||||
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const QString connection = processArguments(application);
|
const QString connection = processArguments(application);
|
||||||
|
|
||||||
StringCache<Utils::PathString> filePathCache;
|
FilePathCache<> filePathCache;
|
||||||
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
|
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
|
||||||
ApplicationEnvironment environment;
|
ApplicationEnvironment environment;
|
||||||
PchGenerator<QProcess> pchGenerator(environment);
|
PchGenerator<QProcess> pchGenerator(environment);
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ namespace ClangBackEnd {
|
|||||||
class WatcherEntry
|
class WatcherEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint id;
|
FilePathIndex id;
|
||||||
uint path;
|
FilePathIndex path;
|
||||||
|
|
||||||
friend bool operator==(const WatcherEntry &first, const WatcherEntry &second)
|
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);
|
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;
|
return entry.path < path;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator<(uint path, const WatcherEntry &entry)
|
friend bool operator<(FilePathIndex path, const WatcherEntry &entry)
|
||||||
{
|
{
|
||||||
return path < entry.path;
|
return path < entry.path;
|
||||||
}
|
}
|
||||||
@@ -63,12 +63,14 @@ public:
|
|||||||
|
|
||||||
using WatcherEntries = std::vector<WatcherEntry>;
|
using WatcherEntries = std::vector<WatcherEntry>;
|
||||||
|
|
||||||
|
using IdCache = StringCache<Utils::SmallString, FilePathIndex, NonLockingMutex>;
|
||||||
|
|
||||||
template <typename FileSystemWatcher,
|
template <typename FileSystemWatcher,
|
||||||
typename Timer>
|
typename Timer>
|
||||||
class ClangPathWatcher : public ClangPathWatcherInterface
|
class ClangPathWatcher : public ClangPathWatcherInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClangPathWatcher(StringCache<Utils::PathString> &pathCache,
|
ClangPathWatcher(FilePathCache<> &pathCache,
|
||||||
ClangPathWatcherNotifier *notifier=nullptr)
|
ClangPathWatcherNotifier *notifier=nullptr)
|
||||||
: m_pathCache(pathCache),
|
: m_pathCache(pathCache),
|
||||||
m_notifier(notifier)
|
m_notifier(notifier)
|
||||||
@@ -130,9 +132,9 @@ unittest_public:
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> convertToIdNumbers(const Utils::SmallStringVector &ids)
|
std::vector<FilePathIndex> convertToIdNumbers(const Utils::SmallStringVector &ids)
|
||||||
{
|
{
|
||||||
std::vector<uint> idNumbers = m_idCache.stringIds(ids);
|
std::vector<FilePathIndex> idNumbers = m_idCache.stringIds(ids);
|
||||||
|
|
||||||
std::sort(idNumbers.begin(), idNumbers.end());
|
std::sort(idNumbers.begin(), idNumbers.end());
|
||||||
|
|
||||||
@@ -149,19 +151,19 @@ unittest_public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<WatcherEntries,std::vector<uint>>
|
std::pair<WatcherEntries,std::vector<FilePathIndex>>
|
||||||
convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths)
|
convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths)
|
||||||
{
|
{
|
||||||
WatcherEntries entries;
|
WatcherEntries entries;
|
||||||
entries.reserve(sizeOfIdPaths(idPaths));
|
entries.reserve(sizeOfIdPaths(idPaths));
|
||||||
std::vector<uint> ids;
|
std::vector<FilePathIndex> 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)
|
||||||
{
|
{
|
||||||
uint id = m_idCache.stringId(idPath.id);
|
FilePathIndex id = m_idCache.stringId(idPath.id);
|
||||||
|
|
||||||
ids.push_back(id);
|
ids.push_back(id);
|
||||||
|
|
||||||
@@ -190,7 +192,7 @@ unittest_public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void removeUnusedEntries(const WatcherEntries &entries,
|
void removeUnusedEntries(const WatcherEntries &entries,
|
||||||
const std::vector<uint> &ids)
|
const std::vector<FilePathIndex> &ids)
|
||||||
{
|
{
|
||||||
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
|
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
|
||||||
|
|
||||||
@@ -272,7 +274,7 @@ unittest_public:
|
|||||||
|
|
||||||
WatcherEntries notAnymoreWatchedEntriesWithIds(
|
WatcherEntries notAnymoreWatchedEntriesWithIds(
|
||||||
const WatcherEntries &newEntries,
|
const WatcherEntries &newEntries,
|
||||||
const std::vector<uint> &ids) const
|
const std::vector<FilePathIndex> &ids) const
|
||||||
{
|
{
|
||||||
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
|
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
|
||||||
|
|
||||||
@@ -328,7 +330,7 @@ unittest_public:
|
|||||||
return m_watchedEntries;
|
return m_watchedEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
WatcherEntries removeIdsFromWatchedEntries(const std::vector<uint> &ids)
|
WatcherEntries removeIdsFromWatchedEntries(const std::vector<FilePathIndex> &ids)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto keep = [&] (const WatcherEntry &entry) {
|
auto keep = [&] (const WatcherEntry &entry) {
|
||||||
@@ -368,7 +370,7 @@ unittest_public:
|
|||||||
|
|
||||||
WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths)
|
WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths)
|
||||||
{
|
{
|
||||||
std::vector<uint> pathIds = m_pathCache.stringIds(filePaths);
|
std::vector<FilePathIndex> pathIds = m_pathCache.stringIds(filePaths);
|
||||||
|
|
||||||
WatcherEntries foundEntries;
|
WatcherEntries foundEntries;
|
||||||
|
|
||||||
@@ -414,22 +416,22 @@ unittest_public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringCache<Utils::PathString> &pathCache()
|
FilePathCache<> &pathCache()
|
||||||
{
|
{
|
||||||
return m_pathCache;
|
return m_pathCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringCache<Utils::SmallString> &idCache()
|
IdCache &idCache()
|
||||||
{
|
{
|
||||||
return m_idCache;
|
return m_idCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCache<Utils::SmallString> m_idCache;
|
IdCache m_idCache;
|
||||||
WatcherEntries m_watchedEntries;
|
WatcherEntries m_watchedEntries;
|
||||||
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
|
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
|
||||||
FileSystemWatcher m_fileSystemWatcher;
|
FileSystemWatcher m_fileSystemWatcher;
|
||||||
StringCache<Utils::PathString> &m_pathCache;
|
FilePathCache<> &m_pathCache;
|
||||||
ClangPathWatcherNotifier *m_notifier;
|
ClangPathWatcherNotifier *m_notifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ namespace ClangBackEnd {
|
|||||||
class CollectIncludesAction final : public clang::PreprocessOnlyAction
|
class CollectIncludesAction final : public clang::PreprocessOnlyAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollectIncludesAction(std::vector<uint> &includeIds,
|
CollectIncludesAction(FilePathIndices &includeIds,
|
||||||
StringCache<Utils::PathString> &filePathCache,
|
FilePathCache<> &filePathCache,
|
||||||
std::vector<uint> &excludedIncludeUID,
|
FilePathIndices &excludedIncludeUID,
|
||||||
std::vector<uint> &alreadyIncludedFileUIDs)
|
FilePathIndices &alreadyIncludedFileUIDs)
|
||||||
: m_includeIds(includeIds),
|
: m_includeIds(includeIds),
|
||||||
m_filePathCache(filePathCache),
|
m_filePathCache(filePathCache),
|
||||||
m_excludedIncludeUID(excludedIncludeUID),
|
m_excludedIncludeUID(excludedIncludeUID),
|
||||||
@@ -78,10 +78,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint> &m_includeIds;
|
FilePathIndices &m_includeIds;
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
std::vector<uint> &m_excludedIncludeUID;
|
FilePathIndices &m_excludedIncludeUID;
|
||||||
std::vector<uint> &m_alreadyIncludedFileUIDs;
|
FilePathIndices &m_alreadyIncludedFileUIDs;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
|
CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
|
||||||
std::vector<uint> &includeIds,
|
std::vector<FilePathIndex> &includeIds,
|
||||||
StringCache<Utils::PathString> &filePathCache,
|
FilePathCache<> &filePathCache,
|
||||||
const std::vector<uint> &excludedIncludeUID,
|
const std::vector<FilePathIndex> &excludedIncludeUID,
|
||||||
std::vector<uint> &alreadyIncludedFileUIDs)
|
std::vector<FilePathIndex> &alreadyIncludedFileUIDs)
|
||||||
: m_headerSearch(headerSearch),
|
: m_headerSearch(headerSearch),
|
||||||
m_includeIds(includeIds),
|
m_includeIds(includeIds),
|
||||||
m_filePathCache(filePathCache),
|
m_filePathCache(filePathCache),
|
||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
|
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
|
||||||
Utils::PathString filePath = filePathFromFile(file);
|
Utils::PathString filePath = filePathFromFile(file);
|
||||||
if (!filePath.isEmpty()) {
|
if (!filePath.isEmpty()) {
|
||||||
uint includeId = m_filePathCache.stringId(filePath);
|
FilePathIndex includeId = m_filePathCache.stringId(filePath);
|
||||||
m_includeIds.emplace_back(includeId);
|
m_includeIds.emplace_back(includeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ public:
|
|||||||
uid);
|
uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, std::vector<uint>::iterator> isNotAlreadyIncluded(uint uid) const
|
std::pair<bool, std::vector<FilePathIndex>::iterator> isNotAlreadyIncluded(FilePathIndex uid) const
|
||||||
{
|
{
|
||||||
auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(),
|
auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(),
|
||||||
m_alreadyIncludedFileUIDs.end(),
|
m_alreadyIncludedFileUIDs.end(),
|
||||||
@@ -174,10 +174,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
clang::HeaderSearch &m_headerSearch;
|
clang::HeaderSearch &m_headerSearch;
|
||||||
std::vector<uint> &m_includeIds;
|
std::vector<FilePathIndex> &m_includeIds;
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
const std::vector<uint> &m_excludedIncludeUID;
|
const std::vector<FilePathIndex> &m_excludedIncludeUID;
|
||||||
std::vector<uint> &m_alreadyIncludedFileUIDs;
|
std::vector<FilePathIndex> &m_alreadyIncludedFileUIDs;
|
||||||
bool m_skipInclude = false;
|
bool m_skipInclude = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ namespace ClangBackEnd {
|
|||||||
class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory
|
class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollectIncludesToolAction(std::vector<uint> &includeIds,
|
CollectIncludesToolAction(std::vector<FilePathIndex> &includeIds,
|
||||||
StringCache<Utils::PathString> &filePathCache,
|
FilePathCache<> &filePathCache,
|
||||||
const Utils::PathStringVector &excludedIncludes)
|
const Utils::PathStringVector &excludedIncludes)
|
||||||
: m_includeIds(includeIds),
|
: m_includeIds(includeIds),
|
||||||
m_filePathCache(filePathCache),
|
m_filePathCache(filePathCache),
|
||||||
@@ -72,9 +72,9 @@ public:
|
|||||||
m_alreadyIncludedFileUIDs);
|
m_alreadyIncludedFileUIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
|
std::vector<FilePathIndex> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
|
||||||
{
|
{
|
||||||
std::vector<uint> fileUIDs;
|
std::vector<FilePathIndex> fileUIDs;
|
||||||
fileUIDs.reserve(m_excludedIncludes.size());
|
fileUIDs.reserve(m_excludedIncludes.size());
|
||||||
|
|
||||||
for (const Utils::PathString &filePath : m_excludedIncludes) {
|
for (const Utils::PathString &filePath : m_excludedIncludes) {
|
||||||
@@ -90,10 +90,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint> m_alreadyIncludedFileUIDs;
|
std::vector<FilePathIndex> m_alreadyIncludedFileUIDs;
|
||||||
std::vector<uint> m_excludedIncludeUIDs;
|
std::vector<FilePathIndex> m_excludedIncludeUIDs;
|
||||||
std::vector<uint> &m_includeIds;
|
std::vector<FilePathIndex> &m_includeIds;
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
const Utils::PathStringVector &m_excludedIncludes;
|
const Utils::PathStringVector &m_excludedIncludes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,15 @@
|
|||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#include <stringcachefwd.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
class IdPaths
|
class IdPaths
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Utils::SmallString id;
|
Utils::SmallString id;
|
||||||
std::vector<uint> paths;
|
std::vector<FilePathIndex> paths;
|
||||||
|
|
||||||
friend bool operator==(const IdPaths &first, const IdPaths &second)
|
friend bool operator==(const IdPaths &first, const IdPaths &second)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
IncludeCollector::IncludeCollector(StringCache<Utils::PathString> &filePathCache)
|
IncludeCollector::IncludeCollector(FilePathCache<> &filePathCache)
|
||||||
: m_filePathCache(filePathCache)
|
: m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedInc
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> IncludeCollector::takeIncludeIds()
|
std::vector<FilePathIndex> IncludeCollector::takeIncludeIds()
|
||||||
{
|
{
|
||||||
std::sort(m_includeIds.begin(), m_includeIds.end());
|
std::sort(m_includeIds.begin(), m_includeIds.end());
|
||||||
|
|
||||||
|
|||||||
@@ -34,19 +34,19 @@ namespace ClangBackEnd {
|
|||||||
class IncludeCollector : public ClangTool
|
class IncludeCollector : public ClangTool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IncludeCollector(StringCache<Utils::PathString> &filePathCache);
|
IncludeCollector(FilePathCache<> &filePathCache);
|
||||||
|
|
||||||
void collectIncludes();
|
void collectIncludes();
|
||||||
|
|
||||||
void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes);
|
void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes);
|
||||||
|
|
||||||
std::vector<uint> takeIncludeIds();
|
std::vector<FilePathIndex> takeIncludeIds();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::PathStringVector m_excludedIncludes;
|
Utils::PathStringVector m_excludedIncludes;
|
||||||
std::vector<uint> m_includeIds;
|
std::vector<FilePathIndex> m_includeIds;
|
||||||
Utils::SmallStringVector m_directories;
|
Utils::SmallStringVector m_directories;
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
PchCreator::PchCreator(Environment &environment, StringCache<Utils::PathString> &filePathCache)
|
PchCreator::PchCreator(Environment &environment, FilePathCache<> &filePathCache)
|
||||||
: m_environment(environment),
|
: m_environment(environment),
|
||||||
m_filePathCache(filePathCache)
|
m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ PchCreator::PchCreator(Environment &environment, StringCache<Utils::PathString>
|
|||||||
|
|
||||||
PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
|
PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
|
||||||
Environment &environment,
|
Environment &environment,
|
||||||
StringCache<Utils::PathString> &filePathCache,
|
FilePathCache<> &filePathCache,
|
||||||
PchGeneratorInterface *pchGenerator,
|
PchGeneratorInterface *pchGenerator,
|
||||||
V2::FileContainers &&generatedFiles)
|
V2::FileContainers &&generatedFiles)
|
||||||
: m_projectParts(std::move(projectsParts)),
|
: m_projectParts(std::move(projectsParts)),
|
||||||
@@ -239,7 +239,7 @@ Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() cons
|
|||||||
return compilerArguments;
|
return compilerArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> PchCreator::generateGlobalPchIncludeIds() const
|
std::vector<FilePathIndex> PchCreator::generateGlobalPchIncludeIds() const
|
||||||
{
|
{
|
||||||
IncludeCollector collector(m_filePathCache);
|
IncludeCollector collector(m_filePathCache);
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ std::size_t contentSize(const std::vector<Utils::PathString> &includes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Utils::SmallString PchCreator::generatePchIncludeFileContent(
|
Utils::SmallString PchCreator::generatePchIncludeFileContent(
|
||||||
const std::vector<uint> &includeIds) const
|
const std::vector<FilePathIndex> &includeIds) const
|
||||||
{
|
{
|
||||||
Utils::SmallString fileContent;
|
Utils::SmallString fileContent;
|
||||||
const std::size_t lineTemplateSize = 12;
|
const std::size_t lineTemplateSize = 12;
|
||||||
@@ -461,7 +461,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaderAndSourcePaths(
|
|||||||
return includeAndSources;
|
return includeAndSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint> PchCreator::generateProjectPartPchIncludes(
|
std::vector<FilePathIndex> PchCreator::generateProjectPartPchIncludes(
|
||||||
const V2::ProjectPartContainer &projectPart) const
|
const V2::ProjectPartContainer &projectPart) const
|
||||||
{
|
{
|
||||||
Utils::SmallString jointedFileContent = generateProjectPartHeaderAndSourcesContent(projectPart);
|
Utils::SmallString jointedFileContent = generateProjectPartHeaderAndSourcesContent(projectPart);
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ class PchCreator final : public PchCreatorInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PchCreator(Environment &environment,
|
PchCreator(Environment &environment,
|
||||||
StringCache<Utils::PathString> &filePathCache);
|
FilePathCache<> &filePathCache);
|
||||||
PchCreator(V2::ProjectPartContainers &&projectsParts,
|
PchCreator(V2::ProjectPartContainers &&projectsParts,
|
||||||
Environment &environment,
|
Environment &environment,
|
||||||
StringCache<Utils::PathString> &filePathCache,
|
FilePathCache<> &filePathCache,
|
||||||
PchGeneratorInterface *pchGenerator,
|
PchGeneratorInterface *pchGenerator,
|
||||||
V2::FileContainers &&generatedFiles);
|
V2::FileContainers &&generatedFiles);
|
||||||
|
|
||||||
@@ -70,9 +70,9 @@ unittest_public:
|
|||||||
Utils::SmallStringVector generateGlobalPchCompilerArguments() const;
|
Utils::SmallStringVector generateGlobalPchCompilerArguments() const;
|
||||||
Utils::SmallStringVector generateGlobalClangCompilerArguments() const;
|
Utils::SmallStringVector generateGlobalClangCompilerArguments() const;
|
||||||
|
|
||||||
std::vector<uint> generateGlobalPchIncludeIds() const;
|
std::vector<FilePathIndex> generateGlobalPchIncludeIds() const;
|
||||||
|
|
||||||
Utils::SmallString generatePchIncludeFileContent(const std::vector<uint> &includeIds) const;
|
Utils::SmallString generatePchIncludeFileContent(const std::vector<FilePathIndex> &includeIds) const;
|
||||||
Utils::SmallString generateGlobalPchHeaderFileContent() const;
|
Utils::SmallString generateGlobalPchHeaderFileContent() const;
|
||||||
std::unique_ptr<QFile> generateGlobalPchHeaderFile();
|
std::unique_ptr<QFile> generateGlobalPchHeaderFile();
|
||||||
void generatePch(Utils::SmallStringVector &&commandLineArguments,
|
void generatePch(Utils::SmallStringVector &&commandLineArguments,
|
||||||
@@ -97,7 +97,7 @@ unittest_public:
|
|||||||
const V2::ProjectPartContainer &projectPart);
|
const V2::ProjectPartContainer &projectPart);
|
||||||
static Utils::PathStringVector generateProjectPartHeaderAndSourcePaths(
|
static Utils::PathStringVector generateProjectPartHeaderAndSourcePaths(
|
||||||
const V2::ProjectPartContainer &projectPart);
|
const V2::ProjectPartContainer &projectPart);
|
||||||
std::vector<uint> generateProjectPartPchIncludes(
|
std::vector<FilePathIndex> generateProjectPartPchIncludes(
|
||||||
const V2::ProjectPartContainer &projectPart) const;
|
const V2::ProjectPartContainer &projectPart) const;
|
||||||
Utils::SmallString generateProjectPathPchHeaderFilePath(
|
Utils::SmallString generateProjectPathPchHeaderFilePath(
|
||||||
const V2::ProjectPartContainer &projectPart) const;
|
const V2::ProjectPartContainer &projectPart) const;
|
||||||
@@ -127,7 +127,7 @@ private:
|
|||||||
std::vector<ProjectPartPch> m_projectPartPchs;
|
std::vector<ProjectPartPch> m_projectPartPchs;
|
||||||
std::vector<IdPaths> m_projectsIncludeIds;
|
std::vector<IdPaths> m_projectsIncludeIds;
|
||||||
Environment &m_environment;
|
Environment &m_environment;
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
PchGeneratorInterface *m_pchGenerator = nullptr;
|
PchGeneratorInterface *m_pchGenerator = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
PchManagerServer::PchManagerServer(StringCache<Utils::PathString> &filePathCache,
|
PchManagerServer::PchManagerServer(FilePathCache<> &filePathCache,
|
||||||
ClangPathWatcherInterface &fileSystemWatcher,
|
ClangPathWatcherInterface &fileSystemWatcher,
|
||||||
PchCreatorInterface &pchCreator,
|
PchCreatorInterface &pchCreator,
|
||||||
ProjectPartsInterface &projectParts)
|
ProjectPartsInterface &projectParts)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class PchManagerServer : public PchManagerServerInterface,
|
|||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PchManagerServer(StringCache<Utils::PathString> &filePathCache,
|
PchManagerServer(FilePathCache<> &filePathCache,
|
||||||
ClangPathWatcherInterface &fileSystemWatcher,
|
ClangPathWatcherInterface &fileSystemWatcher,
|
||||||
PchCreatorInterface &pchCreator,
|
PchCreatorInterface &pchCreator,
|
||||||
ProjectPartsInterface &projectParts);
|
ProjectPartsInterface &projectParts);
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override;
|
void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCache<Utils::PathString> &m_filePathCache;
|
FilePathCache<> &m_filePathCache;
|
||||||
ClangPathWatcherInterface &m_fileSystemWatcher;
|
ClangPathWatcherInterface &m_fileSystemWatcher;
|
||||||
PchCreatorInterface &m_pchCreator;
|
PchCreatorInterface &m_pchCreator;
|
||||||
ProjectPartsInterface &m_projectParts;
|
ProjectPartsInterface &m_projectParts;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ClangQuery::ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache,
|
ClangQuery::ClangQuery(FilePathCache<std::mutex> &filePathCache,
|
||||||
Utils::SmallString &&query)
|
Utils::SmallString &&query)
|
||||||
: query(std::move(query)),
|
: query(std::move(query)),
|
||||||
filePathCache(filePathCache)
|
filePathCache(filePathCache)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace ClangBackEnd {
|
|||||||
class ClangQuery : public ClangTool
|
class ClangQuery : public ClangTool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache, Utils::SmallString &&query={});
|
ClangQuery(FilePathCache<std::mutex> &filePathCache, Utils::SmallString &&query={});
|
||||||
|
|
||||||
void setQuery(Utils::SmallString &&query);
|
void setQuery(Utils::SmallString &&query);
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ private:
|
|||||||
SourceRangesContainer sourceRangesContainer;
|
SourceRangesContainer sourceRangesContainer;
|
||||||
Utils::SmallString query;
|
Utils::SmallString query;
|
||||||
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_;
|
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_;
|
||||||
StringCache<Utils::PathString, std::mutex> &filePathCache;
|
FilePathCache<std::mutex> &filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
|
ClangQueryGatherer::ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache,
|
||||||
std::vector<V2::FileContainer> &&sources,
|
std::vector<V2::FileContainer> &&sources,
|
||||||
std::vector<V2::FileContainer> &&unsaved,
|
std::vector<V2::FileContainer> &&unsaved,
|
||||||
Utils::SmallString &&query)
|
Utils::SmallString &&query)
|
||||||
@@ -43,7 +43,7 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex
|
|||||||
|
|
||||||
SourceRangesForQueryMessage
|
SourceRangesForQueryMessage
|
||||||
ClangQueryGatherer::createSourceRangesForSource(
|
ClangQueryGatherer::createSourceRangesForSource(
|
||||||
StringCache<Utils::PathString, std::mutex> *filePathCache,
|
FilePathCache<std::mutex> *filePathCache,
|
||||||
V2::FileContainer &&source,
|
V2::FileContainer &&source,
|
||||||
const std::vector<V2::FileContainer> &unsaved,
|
const std::vector<V2::FileContainer> &unsaved,
|
||||||
Utils::SmallString &&query)
|
Utils::SmallString &&query)
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ public:
|
|||||||
using Future = std::future<SourceRangesForQueryMessage>;
|
using Future = std::future<SourceRangesForQueryMessage>;
|
||||||
|
|
||||||
ClangQueryGatherer() = default;
|
ClangQueryGatherer() = default;
|
||||||
ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
|
ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache,
|
||||||
std::vector<V2::FileContainer> &&sources,
|
std::vector<V2::FileContainer> &&sources,
|
||||||
std::vector<V2::FileContainer> &&unsaved,
|
std::vector<V2::FileContainer> &&unsaved,
|
||||||
Utils::SmallString &&query);
|
Utils::SmallString &&query);
|
||||||
|
|
||||||
static SourceRangesForQueryMessage createSourceRangesForSource(
|
static SourceRangesForQueryMessage createSourceRangesForSource(
|
||||||
StringCache<Utils::PathString, std::mutex> *filePathCache,
|
FilePathCache<std::mutex> *filePathCache,
|
||||||
V2::FileContainer &&source,
|
V2::FileContainer &&source,
|
||||||
const std::vector<V2::FileContainer> &unsaved,
|
const std::vector<V2::FileContainer> &unsaved,
|
||||||
Utils::SmallString &&query);
|
Utils::SmallString &&query);
|
||||||
@@ -69,7 +69,7 @@ protected:
|
|||||||
std::vector<Future> finishedFutures();
|
std::vector<Future> finishedFutures();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCache<Utils::PathString, std::mutex> *m_filePathCache = nullptr;
|
FilePathCache<std::mutex> *m_filePathCache = nullptr;
|
||||||
SourceRangeFilter m_sourceRangeFilter;
|
SourceRangeFilter m_sourceRangeFilter;
|
||||||
std::vector<V2::FileContainer> m_sources;
|
std::vector<V2::FileContainer> m_sources;
|
||||||
std::vector<V2::FileContainer> m_unsaved;
|
std::vector<V2::FileContainer> m_unsaved;
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ HEADERS += \
|
|||||||
$$PWD/collectsymbolsastvisitor.h \
|
$$PWD/collectsymbolsastvisitor.h \
|
||||||
$$PWD/sourcelocationentry.h \
|
$$PWD/sourcelocationentry.h \
|
||||||
$$PWD/symbolscollectorinterface.h \
|
$$PWD/symbolscollectorinterface.h \
|
||||||
$$PWD/symbolstorageinterface.h
|
$$PWD/symbolstorageinterface.h \
|
||||||
|
$$PWD/symbolstorage.h \
|
||||||
|
$$PWD/storagesqlitestatementfactory.h
|
||||||
|
|
||||||
!isEmpty(LIBTOOLING_LIBS) {
|
!isEmpty(LIBTOOLING_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -52,4 +54,5 @@ SOURCES += \
|
|||||||
$$PWD/collectsymbolsaction.cpp \
|
$$PWD/collectsymbolsaction.cpp \
|
||||||
$$PWD/collectmacrossourcefilecallbacks.cpp \
|
$$PWD/collectmacrossourcefilecallbacks.cpp \
|
||||||
$$PWD/symbolentry.cpp \
|
$$PWD/symbolentry.cpp \
|
||||||
$$PWD/sourcelocationentry.cpp
|
$$PWD/sourcelocationentry.cpp \
|
||||||
|
$$PWD/symbolstorage.cpp
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
|
|
||||||
bool VisitNamedDecl(const clang::NamedDecl *declaration)
|
bool VisitNamedDecl(const clang::NamedDecl *declaration)
|
||||||
{
|
{
|
||||||
auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding();
|
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
|
||||||
auto sourceLocation = declaration->getLocation();
|
auto sourceLocation = declaration->getLocation();
|
||||||
|
|
||||||
auto found = m_symbolEntries.find(globalId);
|
auto found = m_symbolEntries.find(globalId);
|
||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
bool VisitDeclRefExpr(const clang::DeclRefExpr *expression)
|
bool VisitDeclRefExpr(const clang::DeclRefExpr *expression)
|
||||||
{
|
{
|
||||||
auto declaration = expression->getFoundDecl();
|
auto declaration = expression->getFoundDecl();
|
||||||
auto globalId = declaration->getCanonicalDecl()->getLocation().getRawEncoding();
|
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
|
||||||
auto sourceLocation = expression->getLocation();
|
auto sourceLocation = expression->getLocation();
|
||||||
|
|
||||||
m_sourceLocationEntries.emplace_back(globalId,
|
m_sourceLocationEntries.emplace_back(globalId,
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint filePathId(clang::SourceLocation sourceLocation)
|
FilePathIndex filePathId(clang::SourceLocation sourceLocation)
|
||||||
{
|
{
|
||||||
auto filePath = m_sourceManager.getFilename(sourceLocation);
|
auto filePath = m_sourceManager.getFilename(sourceLocation);
|
||||||
|
|
||||||
@@ -114,6 +114,11 @@ public:
|
|||||||
return usr;
|
return usr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SymbolIndex toSymbolIndex(const void *pointer)
|
||||||
|
{
|
||||||
|
return SymbolIndex(reinterpret_cast<std::uintptr_t>(pointer));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SymbolEntries &m_symbolEntries;
|
SymbolEntries &m_symbolEntries;
|
||||||
SourceLocationEntries &m_sourceLocationEntries;
|
SourceLocationEntries &m_sourceLocationEntries;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ private:
|
|||||||
Utils::SmallString &&query);
|
Utils::SmallString &&query);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCache<Utils::PathString, std::mutex> m_filePathCache;
|
FilePathCache<std::mutex> m_filePathCache;
|
||||||
ClangQueryGatherer m_gatherer;
|
ClangQueryGatherer m_gatherer;
|
||||||
QTimer m_pollTimer;
|
QTimer m_pollTimer;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stringcachefwd.h>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
@@ -51,11 +53,13 @@ public:
|
|||||||
uint column = 0;
|
uint column = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using SymbolIndex = long long;
|
||||||
|
|
||||||
class SourceLocationEntry
|
class SourceLocationEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SourceLocationEntry(uint symbolId,
|
SourceLocationEntry(SymbolIndex symbolId,
|
||||||
uint fileId,
|
FilePathIndex fileId,
|
||||||
LineColumn lineColumn,
|
LineColumn lineColumn,
|
||||||
SymbolType symbolType)
|
SymbolType symbolType)
|
||||||
: symbolId(symbolId),
|
: symbolId(symbolId),
|
||||||
@@ -65,8 +69,8 @@ public:
|
|||||||
symbolType(symbolType)
|
symbolType(symbolType)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
uint symbolId = 0;
|
SymbolIndex symbolId = 0;
|
||||||
uint fileId = std::numeric_limits<uint>::max();
|
FilePathIndex fileId = std::numeric_limits<uint>::max();
|
||||||
uint line = 0;
|
uint line = 0;
|
||||||
uint column = 0;
|
uint column = 0;
|
||||||
SymbolType symbolType;
|
SymbolType symbolType;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace ClangBackEnd {
|
|||||||
SourceRangeExtractor::SourceRangeExtractor(
|
SourceRangeExtractor::SourceRangeExtractor(
|
||||||
const clang::SourceManager &sourceManager,
|
const clang::SourceManager &sourceManager,
|
||||||
const clang::LangOptions &languageOptions,
|
const clang::LangOptions &languageOptions,
|
||||||
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
|
ClangBackEnd::FilePathCache<std::mutex> &filePathCache,
|
||||||
SourceRangesContainer &sourceRangesContainer)
|
SourceRangesContainer &sourceRangesContainer)
|
||||||
: sourceManager(sourceManager),
|
: sourceManager(sourceManager),
|
||||||
languageOptions(languageOptions),
|
languageOptions(languageOptions),
|
||||||
@@ -145,7 +145,7 @@ void SourceRangeExtractor::insertSourceRange(uint fileId,
|
|||||||
std::move(lineSnippet));
|
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());
|
auto found = m_fileIdMapping.find(fileId.getHashValue());
|
||||||
if (found != m_fileIdMapping.end()) {
|
if (found != m_fileIdMapping.end()) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class SourceRangeExtractor
|
|||||||
public:
|
public:
|
||||||
SourceRangeExtractor(const clang::SourceManager &sourceManager,
|
SourceRangeExtractor(const clang::SourceManager &sourceManager,
|
||||||
const clang::LangOptions &languageOptions,
|
const clang::LangOptions &languageOptions,
|
||||||
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
|
ClangBackEnd::FilePathCache<std::mutex> &filePathCache,
|
||||||
SourceRangesContainer &sourceRangesContainer);
|
SourceRangesContainer &sourceRangesContainer);
|
||||||
|
|
||||||
void addSourceRange(const clang::SourceRange &sourceRange);
|
void addSourceRange(const clang::SourceRange &sourceRange);
|
||||||
@@ -82,13 +82,13 @@ private:
|
|||||||
uint endOffset,
|
uint endOffset,
|
||||||
Utils::SmallString &&lineSnippet);
|
Utils::SmallString &&lineSnippet);
|
||||||
|
|
||||||
uint findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
|
FilePathIndex findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::unordered_map<uint, uint> m_fileIdMapping;
|
mutable std::unordered_map<uint, uint> m_fileIdMapping;
|
||||||
const clang::SourceManager &sourceManager;
|
const clang::SourceManager &sourceManager;
|
||||||
const clang::LangOptions &languageOptions;
|
const clang::LangOptions &languageOptions;
|
||||||
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache;
|
ClangBackEnd::FilePathCache<std::mutex> &filePathCache;
|
||||||
SourceRangesContainer &sourceRangesContainer;
|
SourceRangesContainer &sourceRangesContainer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 <createtablesqlstatementbuilder.h>
|
||||||
|
|
||||||
|
#include <sqlitetransaction.h>
|
||||||
|
#include <sqlitetable.h>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
template<typename Database,
|
||||||
|
typename ReadStatement,
|
||||||
|
typename WriteStatement>
|
||||||
|
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<DatabaseType> 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<DatabaseType> 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<DatabaseType> 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<DatabaseType> 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<DatabaseType> 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
|
||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stringcachefwd.h>
|
||||||
|
|
||||||
#include <utils/smallstring.h>
|
#include <utils/smallstring.h>
|
||||||
|
|
||||||
#include <llvm/ADT/SmallVector.h>
|
#include <llvm/ADT/SmallVector.h>
|
||||||
@@ -36,6 +38,8 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
using SymbolIndex = long long;
|
||||||
|
|
||||||
class SymbolEntry
|
class SymbolEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -60,7 +64,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using SymbolEntries = std::unordered_map<uint, SymbolEntry>;
|
using SymbolEntries = std::unordered_map<SymbolIndex, SymbolEntry>;
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry);
|
std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry);
|
||||||
|
|
||||||
|
|||||||
30
src/tools/clangrefactoringbackend/source/symbolstorage.cpp
Normal file
30
src/tools/clangrefactoringbackend/source/symbolstorage.cpp
Normal file
@@ -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
|
||||||
155
src/tools/clangrefactoringbackend/source/symbolstorage.h
Normal file
155
src/tools/clangrefactoringbackend/source/symbolstorage.h
Normal file
@@ -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 <sqlitetransaction.h>
|
||||||
|
#include <stringcache.h>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
template <typename StatementFactory>
|
||||||
|
class SymbolStorage : public SymbolStorageInterface
|
||||||
|
{
|
||||||
|
using Transaction = Sqlite::SqliteImmediateTransaction<typename StatementFactory::DatabaseType>;
|
||||||
|
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<FilePathIndex>(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
|
||||||
@@ -33,7 +33,7 @@ namespace ClangBackEnd {
|
|||||||
class SymbolStorageInterface
|
class SymbolStorageInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEentries,
|
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||||
const SourceLocationEntries &sourceLocations) = 0;
|
const SourceLocationEntries &sourceLocations) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ using testing::NiceMock;
|
|||||||
|
|
||||||
using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, FakeTimer>;
|
using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, FakeTimer>;
|
||||||
using ClangBackEnd::WatcherEntry;
|
using ClangBackEnd::WatcherEntry;
|
||||||
|
using ClangBackEnd::FilePathIndices;
|
||||||
|
|
||||||
class ClangPathWatcher : public testing::Test
|
class ClangPathWatcher : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::StringCache<Utils::PathString> pathCache;
|
ClangBackEnd::FilePathCache<> pathCache;
|
||||||
NiceMock<MockClangPathWatcherNotifier> notifier;
|
NiceMock<MockClangPathWatcherNotifier> notifier;
|
||||||
Watcher watcher{pathCache, ¬ifier};
|
Watcher watcher{pathCache, ¬ifier};
|
||||||
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
|
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
|
||||||
@@ -55,8 +56,8 @@ protected:
|
|||||||
Utils::SmallString id3{"id3"};
|
Utils::SmallString id3{"id3"};
|
||||||
Utils::PathString path1{"/path/path1"};
|
Utils::PathString path1{"/path/path1"};
|
||||||
Utils::PathString path2{"/path/path2"};
|
Utils::PathString path2{"/path/path2"};
|
||||||
std::vector<uint> paths = watcher.pathCache().stringIds({path1, path2});
|
FilePathIndices paths{watcher.pathCache().stringIds({path1, path2})};
|
||||||
std::vector<uint> ids = watcher.idCache().stringIds({id1, id2, id3});
|
FilePathIndices ids{watcher.idCache().stringIds({id1, id2, id3})};
|
||||||
WatcherEntry watcherEntry1{ids[0], paths[0]};
|
WatcherEntry watcherEntry1{ids[0], paths[0]};
|
||||||
WatcherEntry watcherEntry2{ids[1], paths[0]};
|
WatcherEntry watcherEntry2{ids[1], paths[0]};
|
||||||
WatcherEntry watcherEntry3{ids[0], paths[1]};
|
WatcherEntry watcherEntry3{ids[0], paths[1]};
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
using ClangBackEnd::ClangQuery;
|
using ClangBackEnd::ClangQuery;
|
||||||
using ClangBackEnd::StringCache;
|
using ClangBackEnd::FilePathCache;
|
||||||
|
|
||||||
using testing::AllOf;
|
using testing::AllOf;
|
||||||
using testing::Contains;
|
using testing::Contains;
|
||||||
@@ -48,7 +48,7 @@ protected:
|
|||||||
void SetUp() override;
|
void SetUp() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StringCache<Utils::PathString, std::mutex> filePathCache;
|
FilePathCache<std::mutex> filePathCache;
|
||||||
::ClangQuery simpleFunctionQuery{filePathCache};
|
::ClangQuery simpleFunctionQuery{filePathCache};
|
||||||
::ClangQuery simpleClassQuery{filePathCache};
|
::ClangQuery simpleClassQuery{filePathCache};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ protected:
|
|||||||
void SetUp() override;
|
void SetUp() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
|
ClangBackEnd::FilePathCache<std::mutex> filePathCache;
|
||||||
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
|
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
|
||||||
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
||||||
sourceContent.clone(),
|
sourceContent.clone(),
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ protected:
|
|||||||
uint id(const Utils::SmallString &path);
|
uint id(const Utils::SmallString &path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::StringCache<Utils::PathString> filePathCache;
|
ClangBackEnd::FilePathCache<> filePathCache;
|
||||||
ClangBackEnd::IncludeCollector collector{filePathCache};
|
ClangBackEnd::IncludeCollector collector{filePathCache};
|
||||||
ClangBackEnd::IncludeCollector emptyCollector{filePathCache};
|
ClangBackEnd::IncludeCollector emptyCollector{filePathCache};
|
||||||
Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.h",
|
Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.h",
|
||||||
|
|||||||
41
tests/unit/unittest/mocksqlitedatabase.h
Normal file
41
tests/unit/unittest/mocksqlitedatabase.h
Normal file
@@ -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 <sqlitetable.h>
|
||||||
|
|
||||||
|
#include <utils/smallstringview.h>
|
||||||
|
|
||||||
|
class MockSqliteDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MOCK_METHOD1(execute,
|
||||||
|
void (Utils::SmallStringView sqlStatement));
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
76
tests/unit/unittest/mocksqlitereadstatement.cpp
Normal file
76
tests/unit/unittest/mocksqlitereadstatement.cpp
Normal file
@@ -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 <typename ResultType,
|
||||||
|
typename... QueryType>
|
||||||
|
std::vector<ResultType> values(std::size_t, QueryType...)
|
||||||
|
{
|
||||||
|
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ResultType>
|
||||||
|
std::vector<std::tuple<ResultType...>> values(std::size_t,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
uint,
|
||||||
|
uint)
|
||||||
|
{
|
||||||
|
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ResultType,
|
||||||
|
template <typename...> class ContainerType,
|
||||||
|
typename ElementType>
|
||||||
|
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t,
|
||||||
|
const ContainerType<ElementType> &)
|
||||||
|
{
|
||||||
|
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<FilePathIndex> MockSqliteReadStatement::values<FilePathIndex>(std::size_t reserveSize)
|
||||||
|
{
|
||||||
|
return valuesReturnStdVectorInt(reserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<std::tuple<int64_t, int64_t, int64_t>>
|
||||||
|
MockSqliteReadStatement::tupleValues<int64_t, int64_t, int64_t>(
|
||||||
|
std::size_t reserveSize,
|
||||||
|
const Utils::PathString &sourcePath,
|
||||||
|
const uint &line,
|
||||||
|
const uint &column)
|
||||||
|
{
|
||||||
|
return valuesReturnStdVectorTupleInt64Int64Int64(reserveSize, sourcePath, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<std::tuple<int64_t, Utils::PathString>>
|
||||||
|
MockSqliteReadStatement::tupleValues<int64_t, Utils::PathString>(std::size_t reserveSize,
|
||||||
|
const std::vector<int64_t> &sourceIds)
|
||||||
|
{
|
||||||
|
return valuesReturnStdVectorTupleInt64PathString(reserveSize, sourceIds);
|
||||||
|
}
|
||||||
92
tests/unit/unittest/mocksqlitereadstatement.h
Normal file
92
tests/unit/unittest/mocksqlitereadstatement.h
Normal file
@@ -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 <stringcachefwd.h>
|
||||||
|
|
||||||
|
#include "mocksqlitedatabase.h"
|
||||||
|
|
||||||
|
#include <utils/smallstring.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<FilePathIndex>(std::size_t));
|
||||||
|
|
||||||
|
MOCK_CONST_METHOD4(valuesReturnStdVectorTupleInt64Int64Int64,
|
||||||
|
std::vector<std::tuple<int64_t, int64_t, int64_t>>(std::size_t, Utils::SmallStringView, int64_t, int64_t));
|
||||||
|
|
||||||
|
MOCK_CONST_METHOD2(valuesReturnStdVectorTupleInt64PathString,
|
||||||
|
std::vector<std::tuple<int64_t, Utils::PathString>>(std::size_t, const std::vector<int64_t> &));
|
||||||
|
|
||||||
|
template <typename ResultType,
|
||||||
|
typename... QueryType>
|
||||||
|
std::vector<ResultType> values(std::size_t, QueryType...);
|
||||||
|
|
||||||
|
template <typename... ResultType,
|
||||||
|
typename... QueryType>
|
||||||
|
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const QueryType&... queryValues);
|
||||||
|
|
||||||
|
template <typename... ResultType,
|
||||||
|
template <typename...> class ContainerType,
|
||||||
|
typename ElementType>
|
||||||
|
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const ContainerType<ElementType> &queryValues);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Utils::SmallString sqlStatement;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<int> MockSqliteReadStatement::values<int>(std::size_t reserveSize);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<std::tuple<int64_t, int64_t, int64_t>>
|
||||||
|
MockSqliteReadStatement::tupleValues<int64_t, int64_t, int64_t>(
|
||||||
|
std::size_t reserveSize,
|
||||||
|
const Utils::PathString &sourcePath,
|
||||||
|
const uint &line,
|
||||||
|
const uint &column);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::vector<std::tuple<int64_t, Utils::PathString>>
|
||||||
|
MockSqliteReadStatement::tupleValues<int64_t, Utils::PathString>(std::size_t reserveSize,
|
||||||
|
const std::vector<int64_t> &);
|
||||||
|
|
||||||
|
|
||||||
59
tests/unit/unittest/mocksqlitewritestatement.h
Normal file
59
tests/unit/unittest/mocksqlitewritestatement.h
Normal file
@@ -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 <utils/smallstring.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
@@ -68,7 +68,7 @@ protected:
|
|||||||
uint id(const Utils::PathString &path);
|
uint id(const Utils::PathString &path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::StringCache<Utils::PathString> filePathCache;
|
ClangBackEnd::FilePathCache<> filePathCache;
|
||||||
PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
|
PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
|
||||||
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
|
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
|
||||||
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
|
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ protected:
|
|||||||
NiceMock<MockPchCreator> mockPchCreator;
|
NiceMock<MockPchCreator> mockPchCreator;
|
||||||
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
||||||
NiceMock<MockProjectParts> mockProjectParts;
|
NiceMock<MockProjectParts> mockProjectParts;
|
||||||
ClangBackEnd::StringCache<Utils::PathString> filePathCache;
|
ClangBackEnd::FilePathCache<> filePathCache;
|
||||||
ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts};
|
ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts};
|
||||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||||
SmallString projectPartId1 = "project1";
|
SmallString projectPartId1 = "project1";
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ protected:
|
|||||||
TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}};
|
TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}};
|
||||||
ClangBackEnd::SourceRangesContainer sourceRangesContainer;
|
ClangBackEnd::SourceRangesContainer sourceRangesContainer;
|
||||||
const clang::SourceManager &sourceManager{clangTool.sourceManager()};
|
const clang::SourceManager &sourceManager{clangTool.sourceManager()};
|
||||||
ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
|
ClangBackEnd::FilePathCache<std::mutex> filePathCache;
|
||||||
ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer};
|
ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer};
|
||||||
clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID());
|
clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID());
|
||||||
clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4);
|
clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4);
|
||||||
|
|||||||
@@ -340,7 +340,6 @@ TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
|
|||||||
Output{"poo", "40", 3}));
|
Output{"poo", "40", 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes)
|
TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes)
|
||||||
{
|
{
|
||||||
SqliteReadStatement statement("SELECT name FROM test WHERE number=?", database);
|
SqliteReadStatement statement("SELECT name FROM test WHERE number=?", database);
|
||||||
|
|||||||
186
tests/unit/unittest/storagesqlitestatementfactory-test.cpp
Normal file
186
tests/unit/unittest/storagesqlitestatementfactory-test.cpp
Normal file
@@ -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 <storagesqlitestatementfactory.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>,
|
||||||
|
MockSqliteReadStatement,
|
||||||
|
MockSqliteWriteStatement>;
|
||||||
|
|
||||||
|
using Sqlite::SqliteTable;
|
||||||
|
|
||||||
|
class StorageSqliteStatementFactory : public testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
NiceMock<MockSqliteDatabase> 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -31,13 +31,16 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ClangBackEnd::StringCacheEntries;
|
|
||||||
using ClangBackEnd::StringCacheException;
|
using ClangBackEnd::StringCacheException;
|
||||||
|
|
||||||
|
using uint64 = unsigned long long;
|
||||||
|
|
||||||
|
using CacheEntries = ClangBackEnd::FileCacheCacheEntries;
|
||||||
|
|
||||||
class StringCache : public testing::Test
|
class StringCache : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::StringCache<Utils::PathString> cache;
|
ClangBackEnd::FilePathCache<> cache;
|
||||||
Utils::PathString filePath1{"/file/pathOne"};
|
Utils::PathString filePath1{"/file/pathOne"};
|
||||||
Utils::PathString filePath2{"/file/pathTwo"};
|
Utils::PathString filePath2{"/file/pathTwo"};
|
||||||
Utils::PathString filePath3{"/file/pathThree"};
|
Utils::PathString filePath3{"/file/pathThree"};
|
||||||
@@ -144,7 +147,7 @@ TEST_F(StringCache, IsNotEmpty)
|
|||||||
|
|
||||||
TEST_F(StringCache, PopulateWithEmptyVector)
|
TEST_F(StringCache, PopulateWithEmptyVector)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries;
|
CacheEntries entries;
|
||||||
|
|
||||||
cache.uncheckedPopulate(std::move(entries));
|
cache.uncheckedPopulate(std::move(entries));
|
||||||
|
|
||||||
@@ -153,10 +156,10 @@ TEST_F(StringCache, PopulateWithEmptyVector)
|
|||||||
|
|
||||||
TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries)
|
TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0},
|
CacheEntries entries{{filePath1.clone(), 0},
|
||||||
{filePath2.clone(), 1},
|
{filePath2.clone(), 1},
|
||||||
{filePath3.clone(), 2},
|
{filePath3.clone(), 2},
|
||||||
{filePath4.clone(), 3}};
|
{filePath4.clone(), 3}};
|
||||||
|
|
||||||
cache.uncheckedPopulate(std::move(entries));
|
cache.uncheckedPopulate(std::move(entries));
|
||||||
|
|
||||||
@@ -165,10 +168,10 @@ TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries)
|
|||||||
|
|
||||||
TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries)
|
TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0},
|
CacheEntries entries{{filePath1.clone(), 0},
|
||||||
{filePath2.clone(), 1},
|
{filePath2.clone(), 1},
|
||||||
{filePath3.clone(), 2},
|
{filePath3.clone(), 2},
|
||||||
{filePath4.clone(), 3}};
|
{filePath4.clone(), 3}};
|
||||||
cache.uncheckedPopulate(std::move(entries));
|
cache.uncheckedPopulate(std::move(entries));
|
||||||
|
|
||||||
auto string = cache.string(2);
|
auto string = cache.string(2);
|
||||||
@@ -178,30 +181,30 @@ TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries)
|
|||||||
|
|
||||||
TEST_F(StringCache, EntriesHaveUniqueIds)
|
TEST_F(StringCache, EntriesHaveUniqueIds)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0},
|
CacheEntries entries{{filePath1.clone(), 0},
|
||||||
{filePath2.clone(), 1},
|
{filePath2.clone(), 1},
|
||||||
{filePath3.clone(), 2},
|
{filePath3.clone(), 2},
|
||||||
{filePath4.clone(), 2}};
|
{filePath4.clone(), 2}};
|
||||||
|
|
||||||
ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
|
ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StringCache, IdsAreHigherLowerEntriesSize)
|
TEST_F(StringCache, IdsAreHigherLowerEntriesSize)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0},
|
CacheEntries entries{{filePath1.clone(), 0},
|
||||||
{filePath2.clone(), 1},
|
{filePath2.clone(), 1},
|
||||||
{filePath3.clone(), 4},
|
{filePath3.clone(), 4},
|
||||||
{filePath4.clone(), 3}};
|
{filePath4.clone(), 3}};
|
||||||
|
|
||||||
ASSERT_THROW(cache.populate(std::move(entries)), std::out_of_range);
|
ASSERT_THROW(cache.populate(std::move(entries)), std::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StringCache, MultipleEntries)
|
TEST_F(StringCache, MultipleEntries)
|
||||||
{
|
{
|
||||||
StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0},
|
CacheEntries entries{{filePath1.clone(), 0},
|
||||||
{filePath1.clone(), 1},
|
{filePath1.clone(), 1},
|
||||||
{filePath3.clone(), 2},
|
{filePath3.clone(), 2},
|
||||||
{filePath4.clone(), 3}};
|
{filePath4.clone(), 3}};
|
||||||
|
|
||||||
ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
|
ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ using testing::_;
|
|||||||
using ClangBackEnd::SourceLocationEntry;
|
using ClangBackEnd::SourceLocationEntry;
|
||||||
using ClangBackEnd::SymbolEntry;
|
using ClangBackEnd::SymbolEntry;
|
||||||
using ClangBackEnd::SymbolType;
|
using ClangBackEnd::SymbolType;
|
||||||
|
using ClangBackEnd::SymbolIndex;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ protected:
|
|||||||
return filePathCache.stringId(string);
|
return filePathCache.stringId(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint symbolIdForSymbolName(const Utils::SmallString &symbolName);
|
SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::FilePathCache<> filePathCache;
|
ClangBackEnd::FilePathCache<> filePathCache;
|
||||||
@@ -149,7 +150,7 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
|
|||||||
Field(&SourceLocationEntry::column, 5))));
|
Field(&SourceLocationEntry::column, 5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName)
|
SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName)
|
||||||
{
|
{
|
||||||
for (const auto &entry : collector.symbols()) {
|
for (const auto &entry : collector.symbols()) {
|
||||||
if (entry.second.symbolName == symbolName)
|
if (entry.second.symbolName == symbolName)
|
||||||
|
|||||||
203
tests/unit/unittest/symbolstorage-test.cpp
Normal file
203
tests/unit/unittest/symbolstorage-test.cpp
Normal file
@@ -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 <storagesqlitestatementfactory.h>
|
||||||
|
#include <symbolstorage.h>
|
||||||
|
#include <sqlitedatabase.h>
|
||||||
|
|
||||||
|
#include <storagesqlitestatementfactory.h>
|
||||||
|
|
||||||
|
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<MockSqliteDatabase,
|
||||||
|
MockSqliteReadStatement,
|
||||||
|
MockSqliteWriteStatement>;
|
||||||
|
using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
|
||||||
|
|
||||||
|
class SymbolStorage : public testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void SetUp();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FilePathCache<> filePathCache;
|
||||||
|
NiceMock<MockSqliteDatabase> 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<FilePathIndex>{0, 1, 2}));
|
||||||
|
|
||||||
|
filePathCache.stringIds({"/path/to/source1", "/path/to/source2", "/path/to/source3"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,10 @@ SOURCES += \
|
|||||||
symbolindexer-test.cpp \
|
symbolindexer-test.cpp \
|
||||||
stringcache-test.cpp \
|
stringcache-test.cpp \
|
||||||
unittests-main.cpp \
|
unittests-main.cpp \
|
||||||
utf8-test.cpp
|
utf8-test.cpp \
|
||||||
|
symbolstorage-test.cpp \
|
||||||
|
storagesqlitestatementfactory-test.cpp \
|
||||||
|
mocksqlitereadstatement.cpp
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -188,7 +191,11 @@ HEADERS += \
|
|||||||
spydummy.h \
|
spydummy.h \
|
||||||
testenvironment.h \
|
testenvironment.h \
|
||||||
mocksymbolscollector.h \
|
mocksymbolscollector.h \
|
||||||
mocksymbolstorage.h
|
mocksymbolstorage.h \
|
||||||
|
mocksqlitewritestatement.h \
|
||||||
|
mocksqlitedatabase.h \
|
||||||
|
mocksqlitereadstatement.h \
|
||||||
|
google-using-directive.h
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
|||||||
Reference in New Issue
Block a user