QmlDesigner: Remove template parameter from project storage

There are now other ways to prevent locking bugs. So we don't need the
template parameter anymore. That makes it possible to move much of the
code to a cpp file. Maybe later we have to move some functions back for
performance reasons.

Change-Id: I01269912618d7cf5e070219e7edaa3a00623b7cf
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2024-04-22 14:29:50 +02:00
parent e262ec1ebb
commit b74c47ec66
18 changed files with 4002 additions and 3636 deletions

View File

@@ -210,6 +210,14 @@ public:
struct is_container<QVarLengthArray<T, Prealloc>> : std::true_type struct is_container<QVarLengthArray<T, Prealloc>> : std::true_type
{}; {};
template<typename T>
struct is_small_container : std::false_type
{};
template<typename T, qsizetype Prealloc>
struct is_small_container<QVarLengthArray<T, Prealloc>> : std::true_type
{};
template<typename Container, template<typename Container,
std::size_t capacity = 32, std::size_t capacity = 32,
typename = std::enable_if_t<is_container<Container>::value>, typename = std::enable_if_t<is_container<Container>::value>,
@@ -223,14 +231,16 @@ public:
Resetter resetter{this}; Resetter resetter{this};
Container resultValues; Container resultValues;
resultValues.reserve(std::max(capacity, m_maximumResultCount)); using size_tupe = typename Container::size_type;
if constexpr (!is_small_container<Container>::value)
resultValues.reserve(static_cast<size_tupe>(std::max(capacity, m_maximumResultCount)));
bindValues(queryValues...); bindValues(queryValues...);
while (BaseStatement::next()) while (BaseStatement::next())
emplaceBackValues(resultValues); emplaceBackValues(resultValues);
setMaximumResultCount(resultValues.size()); setMaximumResultCount(static_cast<std::size_t>(resultValues.size()));
return resultValues; return resultValues;
} }

View File

@@ -77,7 +77,7 @@ constexpr bool useProjectStorage()
using ProjectStorageType = ProjectStorageInterface; using ProjectStorageType = ProjectStorageInterface;
using PathCacheType = SourcePathCacheInterface; using PathCacheType = SourcePathCacheInterface;
#else #else
using ProjectStorageType = ProjectStorage<Sqlite::Database>; using ProjectStorageType = ProjectStorage;
using PathCacheType = SourcePathCache<ProjectStorageType, NonLockingMutex>; using PathCacheType = SourcePathCache<ProjectStorageType, NonLockingMutex>;
#endif #endif

View File

@@ -6,6 +6,7 @@
#include "filestatuscache.h" #include "filestatuscache.h"
#include "filesysteminterface.h" #include "filesysteminterface.h"
#include "nonlockingmutex.h" #include "nonlockingmutex.h"
#include "projectstoragefwd.h"
namespace Sqlite { namespace Sqlite {
class Database; class Database;
@@ -16,12 +17,9 @@ namespace QmlDesigner {
template<typename ProjectStorage, typename Mutex> template<typename ProjectStorage, typename Mutex>
class SourcePathCache; class SourcePathCache;
template<typename Database>
class ProjectStorage;
class FileSystem : public FileSystemInterface class FileSystem : public FileSystemInterface
{ {
using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>; using PathCache = SourcePathCache<ProjectStorage, NonLockingMutex>;
public: public:
FileSystem(PathCache &sourcePathCache) FileSystem(PathCache &sourcePathCache)

View File

@@ -11,7 +11,6 @@ namespace QmlDesigner {
class ProjectStorageInterface; class ProjectStorageInterface;
class SourcePathCacheInterface; class SourcePathCacheInterface;
template<typename Database>
class ProjectStorage; class ProjectStorage;
template<typename Type> template<typename Type>

View File

@@ -84,7 +84,7 @@ public:
virtual std::optional<Storage::Synchronization::ProjectData> fetchProjectData(SourceId sourceId) const = 0; virtual std::optional<Storage::Synchronization::ProjectData> fetchProjectData(SourceId sourceId) const = 0;
virtual SourceId propertyEditorPathId(TypeId typeId) const = 0; virtual SourceId propertyEditorPathId(TypeId typeId) const = 0;
virtual const Storage::Info::CommonTypeCache<ProjectStorageInterface> &commonTypeCache() const = 0; virtual const Storage::Info::CommonTypeCache<ProjectStorageType> &commonTypeCache() const = 0;
template<const char *moduleName, const char *typeName> template<const char *moduleName, const char *typeName>
TypeId commonTypeId() const TypeId commonTypeId() const

View File

@@ -32,7 +32,6 @@ class ProjectStorageInterface;
template<typename ProjectStorage, typename Mutex> template<typename ProjectStorage, typename Mutex>
class SourcePathCache; class SourcePathCache;
class FileStatusCache; class FileStatusCache;
template<typename Database>
class ProjectStorage; class ProjectStorage;
class QmlDocumentParserInterface; class QmlDocumentParserInterface;
class QmlTypesParserInterface; class QmlTypesParserInterface;
@@ -40,7 +39,7 @@ class QmlTypesParserInterface;
class ProjectStorageUpdater final : public ProjectStoragePathWatcherNotifierInterface class ProjectStorageUpdater final : public ProjectStoragePathWatcherNotifierInterface
{ {
public: public:
using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>; using PathCache = SourcePathCache<ProjectStorage, NonLockingMutex>;
ProjectStorageUpdater(FileSystemInterface &fileSystem, ProjectStorageUpdater(FileSystemInterface &fileSystem,
ProjectStorageType &projectStorage, ProjectStorageType &projectStorage,

View File

@@ -15,7 +15,7 @@ class SourcePathCache;
class QmlDocumentParser final : public QmlDocumentParserInterface class QmlDocumentParser final : public QmlDocumentParserInterface
{ {
public: public:
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>; using ProjectStorage = QmlDesigner::ProjectStorage;
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>; using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
#ifdef QDS_BUILD_QMLPARSER #ifdef QDS_BUILD_QMLPARSER

View File

@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "nonlockingmutex.h" #include "nonlockingmutex.h"
#include "projectstoragefwd.h"
#include "qmltypesparserinterface.h" #include "qmltypesparserinterface.h"
namespace Sqlite { namespace Sqlite {
@@ -12,17 +13,13 @@ class Database;
namespace QmlDesigner { namespace QmlDesigner {
template<typename Database>
class ProjectStorage;
template<typename ProjectStorage, typename Mutex> template<typename ProjectStorage, typename Mutex>
class SourcePathCache; class SourcePathCache;
class QmlTypesParser final : public QmlTypesParserInterface class QmlTypesParser final : public QmlTypesParserInterface
{ {
public: public:
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>; using ProjectStorage = QmlDesigner::ProjectStorage;
#ifdef QDS_BUILD_QMLPARSER #ifdef QDS_BUILD_QMLPARSER
QmlTypesParser(ProjectStorage &storage) QmlTypesParser(ProjectStorage &storage)
: m_storage{storage} : m_storage{storage}

View File

@@ -125,4 +125,6 @@ public:
SourceContextId sourceContextId; SourceContextId sourceContextId;
}; };
using SourceNameAndSourceContextIds = std::vector<SourceNameAndSourceContextId>;
} // namespace QmlDesigner::Cache } // namespace QmlDesigner::Cache

View File

@@ -181,7 +181,7 @@ public:
pathCache.sourceId(SourcePath{project->projectDirectory().toString() + "/."}).internalId())} pathCache.sourceId(SourcePath{project->projectDirectory().toString() + "/."}).internalId())}
{} {}
Sqlite::Database database; Sqlite::Database database;
ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; ProjectStorage storage{database, database.isInitialized()};
PathCacheType pathCache{storage}; PathCacheType pathCache{storage};
FileSystem fileSystem{pathCache}; FileSystem fileSystem{pathCache};
FileStatusCache fileStatusCache{fileSystem}; FileStatusCache fileStatusCache{fileSystem};
@@ -282,7 +282,7 @@ AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache()
} }
namespace { namespace {
[[maybe_unused]] ProjectStorage<Sqlite::Database> *dummyProjectStorage() [[maybe_unused]] ProjectStorage *dummyProjectStorage()
{ {
return nullptr; return nullptr;
} }

View File

@@ -202,7 +202,7 @@ class HasNameMatcher
public: public:
using is_gtest_matcher = void; using is_gtest_matcher = void;
HasNameMatcher(const QmlDesigner::ProjectStorage<Sqlite::Database> &storage, HasNameMatcher(const QmlDesigner::ProjectStorage &storage,
Utils::SmallStringView name) Utils::SmallStringView name)
: storage{storage} : storage{storage}
, name{name} , name{name}
@@ -231,7 +231,7 @@ public:
void DescribeNegationTo(std::ostream *os) const { *os << "is not '" << name << "'"; } void DescribeNegationTo(std::ostream *os) const { *os << "is not '" << name << "'"; }
private: private:
const QmlDesigner::ProjectStorage<Sqlite::Database> &storage; const QmlDesigner::ProjectStorage &storage;
Utils::SmallStringView name; Utils::SmallStringView name;
}; };
@@ -271,7 +271,7 @@ protected:
{ {
static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory);
static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage>(
*static_database, static_database->isInitialized()); *static_database, static_database->isInitialized());
} }
@@ -1136,9 +1136,9 @@ protected:
protected: protected:
inline static std::unique_ptr<Sqlite::Database> static_database; inline static std::unique_ptr<Sqlite::Database> static_database;
Sqlite::Database &database = *static_database; Sqlite::Database &database = *static_database;
inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; inline static std::unique_ptr<QmlDesigner::ProjectStorage> static_projectStorage;
QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; QmlDesigner::ProjectStorage &storage = *static_projectStorage;
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{
storage}; storage};
QmlDesigner::SourcePathView path1{"/path1/to"}; QmlDesigner::SourcePathView path1{"/path1/to"};
QmlDesigner::SourcePathView path2{"/path2/to"}; QmlDesigner::SourcePathView path2{"/path2/to"};
@@ -5102,7 +5102,7 @@ TEST_F(ProjectStorage, populate_module_cache)
{ {
auto id = storage.moduleId("Qml"); auto id = storage.moduleId("Qml");
QmlDesigner::ProjectStorage<Sqlite::Database> newStorage{database, database.isInitialized()}; QmlDesigner::ProjectStorage newStorage{database, database.isInitialized()};
ASSERT_THAT(newStorage.moduleName(id), Eq("Qml")); ASSERT_THAT(newStorage.moduleName(id), Eq("Qml"));
} }

View File

@@ -16,7 +16,7 @@
#include <utils/smallstring.h> #include <utils/smallstring.h>
namespace { namespace {
using SourcePathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>>; using SourcePathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage>;
using Watcher = QmlDesigner::ProjectStoragePathWatcher<NiceMock<MockQFileSytemWatcher>, using Watcher = QmlDesigner::ProjectStoragePathWatcher<NiceMock<MockQFileSytemWatcher>,
NiceMock<MockTimer>, NiceMock<MockTimer>,
SourcePathCache>; SourcePathCache>;
@@ -43,7 +43,7 @@ protected:
{ {
static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory);
static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage>(
*static_database, static_database->isInitialized()); *static_database, static_database->isInitialized());
} }
@@ -81,8 +81,8 @@ protected:
NiceMock<FileSystemMock> mockFileSystem; NiceMock<FileSystemMock> mockFileSystem;
inline static std::unique_ptr<Sqlite::Database> static_database; inline static std::unique_ptr<Sqlite::Database> static_database;
Sqlite::Database &database = *static_database; Sqlite::Database &database = *static_database;
inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; inline static std::unique_ptr<QmlDesigner::ProjectStorage> static_projectStorage;
QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; QmlDesigner::ProjectStorage &storage = *static_projectStorage;
SourcePathCache pathCache{storage}; SourcePathCache pathCache{storage};
Watcher watcher{pathCache, mockFileSystem, &notifier}; Watcher watcher{pathCache, mockFileSystem, &notifier};
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher(); NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();

View File

@@ -144,7 +144,7 @@ public:
{ {
static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory);
static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage>(
*static_database, static_database->isInitialized()); *static_database, static_database->isInitialized());
} }
@@ -312,9 +312,9 @@ protected:
QmlDesigner::FileStatusCache fileStatusCache{fileSystemMock}; QmlDesigner::FileStatusCache fileStatusCache{fileSystemMock};
inline static std::unique_ptr<Sqlite::Database> static_database; inline static std::unique_ptr<Sqlite::Database> static_database;
Sqlite::Database &database = *static_database; Sqlite::Database &database = *static_database;
inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; inline static std::unique_ptr<QmlDesigner::ProjectStorage> static_projectStorage;
QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; QmlDesigner::ProjectStorage &storage = *static_projectStorage;
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{
storage}; storage};
NiceMock<ProjectStoragePathWatcherMock> patchWatcherMock; NiceMock<ProjectStoragePathWatcherMock> patchWatcherMock;
QmlDesigner::ProjectPartId projectPartId = QmlDesigner::ProjectPartId::create(1); QmlDesigner::ProjectPartId projectPartId = QmlDesigner::ProjectPartId::create(1);

View File

@@ -143,8 +143,8 @@ class QmlDocumentParser : public ::testing::Test
public: public:
protected: protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; QmlDesigner::ProjectStorage storage{database, database.isInitialized()};
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{
storage}; storage};
QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache};
Storage::Imports imports; Storage::Imports imports;

View File

@@ -168,8 +168,8 @@ class QmlTypesParser : public ::testing::Test
public: public:
protected: protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; QmlDesigner::ProjectStorage storage{database, database.isInitialized()};
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{
storage}; storage};
QmlDesigner::QmlTypesParser parser{storage}; QmlDesigner::QmlTypesParser parser{storage};
Storage::Imports imports; Storage::Imports imports;

View File

@@ -20,7 +20,7 @@ protected:
{ {
static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory);
static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage>(
*static_database, static_database->isInitialized()); *static_database, static_database->isInitialized());
} }
@@ -35,8 +35,8 @@ protected:
protected: protected:
inline static std::unique_ptr<Sqlite::Database> static_database; inline static std::unique_ptr<Sqlite::Database> static_database;
Sqlite::Database &database = *static_database; Sqlite::Database &database = *static_database;
inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; inline static std::unique_ptr<QmlDesigner::ProjectStorage> static_projectStorage;
QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; QmlDesigner::ProjectStorage &storage = *static_projectStorage;
QmlDesigner::Storage::TypeAnnotationReader reader{storage}; QmlDesigner::Storage::TypeAnnotationReader reader{storage};
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(33); QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(33);
QmlDesigner::SourceId directorySourceId = QmlDesigner::SourceId::create(77); QmlDesigner::SourceId directorySourceId = QmlDesigner::SourceId::create(77);