forked from qt-creator/qt-creator
QmlDesigner: Add Model::moduleIdsStartsWith()
Get modul ids that start with that string and are of that kind. If no string is given there are no ids returned. The returned ids are not sorted. auto moduleIds = model->moduleIdsStartsWith("QtQuick", Storage::ModuleKind::QmlLibrary); std::ranges::sort(moduleIds); auto isQtQuickModule = Utils::set_has_common_element(otherSortedModuleIds, moduleIds); Change-Id: I85f7dadca5be88885e54237b5d560ba02b61c75b Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Burak Hancerli <burak.hancerli@qt.io>
This commit is contained in:
@@ -148,6 +148,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Module module(Utils::SmallStringView moduleName, Storage::ModuleKind moduleKind);
|
Module module(Utils::SmallStringView moduleName, Storage::ModuleKind moduleKind);
|
||||||
|
SmallModuleIds<128> moduleIdsStartsWith(Utils::SmallStringView startsWith,
|
||||||
|
Storage::ModuleKind kind) const;
|
||||||
NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
|
NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
|
||||||
NodeMetaInfo metaInfo(Module module,
|
NodeMetaInfo metaInfo(Module module,
|
||||||
Utils::SmallStringView typeName,
|
Utils::SmallStringView typeName,
|
||||||
|
@@ -45,6 +45,8 @@ using EnumerationDeclarationIds = std::vector<EnumerationDeclarationId>;
|
|||||||
using ModuleId = Sqlite::BasicId<ProjectStorageIdType::Module, int>;
|
using ModuleId = Sqlite::BasicId<ProjectStorageIdType::Module, int>;
|
||||||
using ModuleIds = std::vector<ModuleId>;
|
using ModuleIds = std::vector<ModuleId>;
|
||||||
using ModuleIdSpan = Utils::span<ModuleId>;
|
using ModuleIdSpan = Utils::span<ModuleId>;
|
||||||
|
template<std::size_t size>
|
||||||
|
using SmallModuleIds = QVarLengthArray<ModuleId, size>;
|
||||||
|
|
||||||
using ProjectPartId = Sqlite::BasicId<ProjectStorageIdType::ProjectPartId>;
|
using ProjectPartId = Sqlite::BasicId<ProjectStorageIdType::ProjectPartId>;
|
||||||
using ProjectPartIds = std::vector<ProjectPartId>;
|
using ProjectPartIds = std::vector<ProjectPartId>;
|
||||||
|
@@ -2917,6 +2917,15 @@ Module Model::module(Utils::SmallStringView moduleName, Storage::ModuleKind modu
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallModuleIds<128> Model::moduleIdsStartsWith(Utils::SmallStringView startsWith,
|
||||||
|
Storage::ModuleKind kind) const
|
||||||
|
{
|
||||||
|
if constexpr (useProjectStorage())
|
||||||
|
return d->projectStorage->moduleIdsStartsWith(startsWith, kind);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/*! \name View related functions
|
/*! \name View related functions
|
||||||
*/
|
*/
|
||||||
//\{
|
//\{
|
||||||
|
@@ -1424,7 +1424,8 @@ ModuleId ProjectStorage::moduleId(Utils::SmallStringView moduleName, Storage::Mo
|
|||||||
using NanotraceHR::keyValue;
|
using NanotraceHR::keyValue;
|
||||||
NanotraceHR::Tracer tracer{"get module id",
|
NanotraceHR::Tracer tracer{"get module id",
|
||||||
projectStorageCategory(),
|
projectStorageCategory(),
|
||||||
keyValue("module name", moduleName)};
|
keyValue("module name", moduleName),
|
||||||
|
keyValue("module kind", kind)};
|
||||||
|
|
||||||
if (moduleName.empty())
|
if (moduleName.empty())
|
||||||
return ModuleId{};
|
return ModuleId{};
|
||||||
@@ -1436,6 +1437,27 @@ ModuleId ProjectStorage::moduleId(Utils::SmallStringView moduleName, Storage::Mo
|
|||||||
return moduleId;
|
return moduleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallModuleIds<128> ProjectStorage::moduleIdsStartsWith(Utils::SmallStringView startsWith,
|
||||||
|
Storage::ModuleKind kind) const
|
||||||
|
{
|
||||||
|
using NanotraceHR::keyValue;
|
||||||
|
NanotraceHR::Tracer tracer{"get module ids that starts with",
|
||||||
|
projectStorageCategory(),
|
||||||
|
keyValue("module name starts with", startsWith),
|
||||||
|
keyValue("module kind", kind)};
|
||||||
|
|
||||||
|
if (startsWith.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto projection = [&](ModuleView view) -> ModuleView {
|
||||||
|
return {view.name.substr(0, startsWith.size()), view.kind};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto moduleIds = moduleCache.ids<128>({startsWith, kind}, projection);
|
||||||
|
|
||||||
|
return moduleIds;
|
||||||
|
}
|
||||||
|
|
||||||
Storage::Module ProjectStorage::module(ModuleId moduleId) const
|
Storage::Module ProjectStorage::module(ModuleId moduleId) const
|
||||||
{
|
{
|
||||||
using NanotraceHR::keyValue;
|
using NanotraceHR::keyValue;
|
||||||
|
@@ -62,6 +62,9 @@ public:
|
|||||||
|
|
||||||
ModuleId moduleId(Utils::SmallStringView moduleName, Storage::ModuleKind kind) const override;
|
ModuleId moduleId(Utils::SmallStringView moduleName, Storage::ModuleKind kind) const override;
|
||||||
|
|
||||||
|
SmallModuleIds<128> moduleIdsStartsWith(Utils::SmallStringView startsWith,
|
||||||
|
Storage::ModuleKind kind) const override;
|
||||||
|
|
||||||
Storage::Module module(ModuleId moduleId) const override;
|
Storage::Module module(ModuleId moduleId) const override;
|
||||||
|
|
||||||
TypeId typeId(ModuleId moduleId,
|
TypeId typeId(ModuleId moduleId,
|
||||||
@@ -252,9 +255,9 @@ private:
|
|||||||
Utils::SmallStringView name;
|
Utils::SmallStringView name;
|
||||||
Storage::ModuleKind kind;
|
Storage::ModuleKind kind;
|
||||||
|
|
||||||
friend bool operator<(ModuleView first, ModuleView second)
|
friend std::strong_ordering operator<=>(ModuleView first, ModuleView second)
|
||||||
{
|
{
|
||||||
return std::tie(first.kind, first.name) < std::tie(second.kind, second.name);
|
return std::tie(first.kind, first.name) <=> std::tie(second.kind, second.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const Storage::Module &first, ModuleView second)
|
friend bool operator==(const Storage::Module &first, ModuleView second)
|
||||||
|
@@ -32,6 +32,8 @@ public:
|
|||||||
virtual void removeObserver(ProjectStorageObserver *observer) = 0;
|
virtual void removeObserver(ProjectStorageObserver *observer) = 0;
|
||||||
|
|
||||||
virtual ModuleId moduleId(::Utils::SmallStringView name, Storage::ModuleKind kind) const = 0;
|
virtual ModuleId moduleId(::Utils::SmallStringView name, Storage::ModuleKind kind) const = 0;
|
||||||
|
virtual SmallModuleIds<128>
|
||||||
|
moduleIdsStartsWith(Utils::SmallStringView startsWith, Storage::ModuleKind kind) const = 0;
|
||||||
virtual QmlDesigner::Storage::Module module(ModuleId moduleId) const = 0;
|
virtual QmlDesigner::Storage::Module module(ModuleId moduleId) const = 0;
|
||||||
virtual std::optional<Storage::Info::PropertyDeclaration>
|
virtual std::optional<Storage::Info::PropertyDeclaration>
|
||||||
propertyDeclaration(PropertyDeclarationId propertyDeclarationId) const = 0;
|
propertyDeclaration(PropertyDeclarationId propertyDeclarationId) const = 0;
|
||||||
|
@@ -201,38 +201,50 @@ public:
|
|||||||
{
|
{
|
||||||
std::shared_lock<Mutex> sharedLock(m_mutex);
|
std::shared_lock<Mutex> sharedLock(m_mutex);
|
||||||
|
|
||||||
auto found = find(view);
|
auto [iter, found] = find(view);
|
||||||
|
|
||||||
if (found != m_entries.end())
|
if (found)
|
||||||
return found->id;
|
return iter->id;
|
||||||
|
|
||||||
sharedLock.unlock();
|
sharedLock.unlock();
|
||||||
std::lock_guard<Mutex> exclusiveLock(m_mutex);
|
std::lock_guard<Mutex> exclusiveLock(m_mutex);
|
||||||
|
|
||||||
if constexpr (!std::is_base_of_v<NonLockingMutex, Mutex>)
|
if constexpr (!std::is_base_of_v<NonLockingMutex, Mutex>)
|
||||||
found = find(view);
|
std::tie(iter, found) = find(view);
|
||||||
if (found == m_entries.end())
|
if (!found)
|
||||||
found = insertEntry(found, view, m_storage.fetchId(view));
|
iter = insertEntry(iter, view, m_storage.fetchId(view));
|
||||||
|
|
||||||
return found->id;
|
return iter->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
template<typename ValueType = ViewType>
|
||||||
std::vector<IndexType> ids(const Container &values)
|
std::vector<IndexType> ids(Utils::span<const ValueType> values)
|
||||||
{
|
{
|
||||||
std::vector<IndexType> ids;
|
std::vector<IndexType> ids;
|
||||||
ids.reserve(values.size());
|
ids.reserve(values.size());
|
||||||
|
|
||||||
std::ranges::transform(values, std::back_inserter(ids), [&](const auto &values) {
|
std::ranges::transform(values, std::back_inserter(ids), [&](ViewType value) {
|
||||||
return this->id(values);
|
return this->id(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IndexType> ids(std::initializer_list<Type> values)
|
template<std::indirectly_readable I, std::indirectly_regular_unary_invocable<I> Proj>
|
||||||
|
using projected_value_t = std::remove_cvref_t<std::invoke_result_t<Proj &, std::iter_value_t<I> &>>;
|
||||||
|
|
||||||
|
template<std::size_t size,
|
||||||
|
typename Projection = std::identity,
|
||||||
|
typename Value = projected_value_t<std::ranges::iterator_t<CacheEntries>, Projection>>
|
||||||
|
QVarLengthArray<IndexType, size> ids(Value value, Projection projection)
|
||||||
{
|
{
|
||||||
return ids<std::initializer_list<Type>>(values);
|
std::shared_lock<Mutex> sharedLock(m_mutex);
|
||||||
|
|
||||||
|
auto range = std::ranges::equal_range(m_entries, value, Compare{}, projection);
|
||||||
|
|
||||||
|
QVarLengthArray<IndexType, size> ids;
|
||||||
|
std::ranges::transform(range, std::back_inserter(ids), &CacheEntry::id);
|
||||||
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultType value(IndexType id)
|
ResultType value(IndexType id)
|
||||||
@@ -250,7 +262,7 @@ public:
|
|||||||
std::lock_guard<Mutex> exclusiveLock(m_mutex);
|
std::lock_guard<Mutex> exclusiveLock(m_mutex);
|
||||||
|
|
||||||
Type value{m_storage.fetchValue(id)};
|
Type value{m_storage.fetchValue(id)};
|
||||||
auto interator = insertEntry(find(value), value, id);
|
auto interator = insertEntry(std::get<0>(find(value)), value, id);
|
||||||
|
|
||||||
return interator->value;
|
return interator->value;
|
||||||
}
|
}
|
||||||
@@ -290,24 +302,21 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Entries>
|
template<typename Entries>
|
||||||
static auto find(Entries &&entries, ViewType view)
|
static std::tuple<std::ranges::iterator_t<Entries>, bool> find(Entries &&entries, ViewType view)
|
||||||
{
|
{
|
||||||
auto found = std::ranges::lower_bound(entries, view, Compare{});
|
auto found = std::ranges::lower_bound(entries, view, Compare{});
|
||||||
|
|
||||||
if (found != entries.end() && *found == view)
|
return {found, found != entries.end() && *found == view};
|
||||||
return found;
|
|
||||||
|
|
||||||
return entries.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexType id(ViewType view) const
|
IndexType id(ViewType view) const
|
||||||
{
|
{
|
||||||
std::shared_lock<Mutex> sharedLock(m_mutex);
|
std::shared_lock<Mutex> sharedLock(m_mutex);
|
||||||
|
|
||||||
auto found = find(view);
|
auto [iter, found] = find(view);
|
||||||
|
|
||||||
if (found != m_entries.end())
|
if (found)
|
||||||
return found->id;
|
return iter->id;
|
||||||
|
|
||||||
return IndexType();
|
return IndexType();
|
||||||
}
|
}
|
||||||
|
@@ -133,6 +133,10 @@ public:
|
|||||||
moduleId,
|
moduleId,
|
||||||
(::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind),
|
(::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind),
|
||||||
(const, override));
|
(const, override));
|
||||||
|
MOCK_METHOD(QmlDesigner::SmallModuleIds<128>,
|
||||||
|
moduleIdsStartsWith,
|
||||||
|
(::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind),
|
||||||
|
(const, override));
|
||||||
MOCK_METHOD(QmlDesigner::Storage::Module, module, (QmlDesigner::ModuleId), (const, override));
|
MOCK_METHOD(QmlDesigner::Storage::Module, module, (QmlDesigner::ModuleId), (const, override));
|
||||||
|
|
||||||
MOCK_METHOD(std::optional<QmlDesigner::Storage::Info::PropertyDeclaration>,
|
MOCK_METHOD(std::optional<QmlDesigner::Storage::Info::PropertyDeclaration>,
|
||||||
|
@@ -1137,6 +1137,16 @@ TEST_F(Model_MetaInfo, get_invalid_meta_info_by_module_for_wrong_module)
|
|||||||
ASSERT_THAT(metaInfo, IsFalse());
|
ASSERT_THAT(metaInfo, IsFalse());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Model_MetaInfo, get_module_ids_that_starts_with)
|
||||||
|
{
|
||||||
|
ON_CALL(projectStorageMock, moduleIdsStartsWith(Eq("Q"), ModuleKind::QmlLibrary))
|
||||||
|
.WillByDefault(Return(QmlDesigner::SmallModuleIds<128>{qtQuickModuleId}));
|
||||||
|
|
||||||
|
auto moduleIds = model.moduleIdsStartsWith("Q", ModuleKind::QmlLibrary);
|
||||||
|
|
||||||
|
ASSERT_THAT(moduleIds, Contains(qtQuickModuleId));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(Model_MetaInfo, add_project_storage_observer_to_project_storage)
|
TEST_F(Model_MetaInfo, add_project_storage_observer_to_project_storage)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(projectStorageMock, addObserver(_));
|
EXPECT_CALL(projectStorageMock, addObserver(_));
|
||||||
|
@@ -5827,6 +5827,30 @@ TEST_F(ProjectStorage, populate_module_cache)
|
|||||||
ASSERT_THAT(newStorage.module(id), IsModule("Qml", ModuleKind::QmlLibrary));
|
ASSERT_THAT(newStorage.module(id), IsModule("Qml", ModuleKind::QmlLibrary));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorage, get_no_module_ids_if_they_starts_with_nothing)
|
||||||
|
{
|
||||||
|
storage.moduleId("QtQml", ModuleKind::QmlLibrary);
|
||||||
|
|
||||||
|
auto ids = storage.moduleIdsStartsWith("", ModuleKind::QmlLibrary);
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorage, get_module_ids_if_they_starts_with_New)
|
||||||
|
{
|
||||||
|
auto quickId = storage.moduleId("NewQuick", ModuleKind::QmlLibrary);
|
||||||
|
storage.moduleId("NewQuick", ModuleKind::CppLibrary);
|
||||||
|
auto quick3dId = storage.moduleId("NewQuick3D", ModuleKind::QmlLibrary);
|
||||||
|
storage.moduleId("NewQml", ModuleKind::CppLibrary);
|
||||||
|
auto qmlId = storage.moduleId("NewQml", ModuleKind::QmlLibrary);
|
||||||
|
storage.moduleId("Foo", ModuleKind::QmlLibrary);
|
||||||
|
storage.moduleId("Zoo", ModuleKind::QmlLibrary);
|
||||||
|
|
||||||
|
auto ids = storage.moduleIdsStartsWith("New", ModuleKind::QmlLibrary);
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, UnorderedElementsAre(qmlId, quickId, quick3dId));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProjectStorage, add_directory_infoes)
|
TEST_F(ProjectStorage, add_directory_infoes)
|
||||||
{
|
{
|
||||||
Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId,
|
Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectDirectoryPathId,
|
||||||
|
@@ -514,4 +514,41 @@ TYPED_TEST(StorageCache, fetch_ids_from_storage_calls)
|
|||||||
|
|
||||||
this->cache.ids({"foo", "bar"});
|
this->cache.ids({"foo", "bar"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(StorageCache, getting_ids_that_start_with_po)
|
||||||
|
{
|
||||||
|
ON_CALL(this->mockStorage, fetchDirectoryPathId(Eq("poh"))).WillByDefault(Return(this->id43));
|
||||||
|
this->cache.add({"poo", "foo", "poh", "taa"});
|
||||||
|
auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView {
|
||||||
|
return text.substr(0, 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ids = this->cache.template ids<4>("po", projection);
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, UnorderedElementsAre(this->id43, this->id44));
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(StorageCache, getting_no_ids_if_there_is_no_entry_starts_with_oh)
|
||||||
|
{
|
||||||
|
this->cache.add({"poo", "taa", "foo", "bar"});
|
||||||
|
auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView {
|
||||||
|
return text.substr(0, 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ids = this->cache.template ids<4>("oh", projection);
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(StorageCache, get_all_ids_if_the_string_is_empty)
|
||||||
|
{
|
||||||
|
this->cache.add({"foo", "bar", "poo", "taa"});
|
||||||
|
auto projection = [](Utils::SmallStringView text) -> Utils::SmallStringView {
|
||||||
|
return text.substr(0, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ids = this->cache.template ids<4>("", projection);
|
||||||
|
|
||||||
|
ASSERT_THAT(ids, UnorderedElementsAre(this->id42, this->id43, this->id44, this->id45));
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user