QmlDesigner: Use one synchronization struct

The arguments of the synchronization function are changing constantly, so
all tests have to adapted even for default arguments. To reduce this
changes now a struct is used as parameter.

Task-number: QDS-5196
Change-Id: Id3b6a530bcb8ab043eccce6526088f345d746235
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marco Bubke
2021-10-20 17:34:46 +02:00
committed by Tim Jenssen
parent b4fcd05451
commit 428a9ee509
8 changed files with 1264 additions and 2019 deletions

View File

@@ -60,10 +60,7 @@ public:
moduleCache.populate();
}
void synchronize(Storage::Imports imports,
Storage::Types types,
SourceIds sourceIds,
FileStatuses fileStatuses) override
void synchronize(Storage::SynchronizationPackage package) override
{
Sqlite::ImmediateTransaction transaction{database};
@@ -76,19 +73,19 @@ public:
TypeIds deletedTypeIds;
TypeIds updatedTypeIds;
updatedTypeIds.reserve(types.size());
updatedTypeIds.reserve(package.types.size());
TypeIds typeIdsToBeDeleted;
auto sourceIdValues = Utils::transform<std::vector>(sourceIds, [](SourceId sourceId) {
auto sourceIdValues = Utils::transform<std::vector>(package.sourceIds, [](SourceId sourceId) {
return &sourceId;
});
std::sort(sourceIdValues.begin(), sourceIdValues.end());
synchronizeFileStatuses(fileStatuses, sourceIdValues);
synchronizeImports(imports, sourceIdValues);
synchronizeTypes(types,
synchronizeFileStatuses(package.fileStatuses, sourceIdValues);
synchronizeImports(package.imports, sourceIdValues);
synchronizeTypes(package.types,
updatedTypeIds,
insertedAliasPropertyDeclarations,
updatedAliasPropertyDeclarations,
@@ -897,22 +894,26 @@ private:
if (!type.moduleId)
throw QmlDesigner::ModuleDoesNotExists{};
if (type.version) {
insertExportedTypeNamesWithVersionStatement.write(&type.moduleId,
type.name,
type.version.major.value,
type.version.minor.value,
&type.typeId);
try {
if (type.version) {
insertExportedTypeNamesWithVersionStatement.write(&type.moduleId,
type.name,
type.version.major.value,
type.version.minor.value,
&type.typeId);
} else if (type.version.major) {
insertExportedTypeNamesWithMajorVersionStatement.write(&type.moduleId,
type.name,
type.version.major.value,
&type.typeId);
} else {
insertExportedTypeNamesWithoutVersionStatement.write(&type.moduleId,
type.name,
&type.typeId);
} else if (type.version.major) {
insertExportedTypeNamesWithMajorVersionStatement.write(&type.moduleId,
type.name,
type.version.major.value,
&type.typeId);
} else {
insertExportedTypeNamesWithoutVersionStatement.write(&type.moduleId,
type.name,
&type.typeId);
}
} catch (const Sqlite::ConstraintPreventsModification &) {
throw QmlDesigner::ModuleDoesNotExists{};
}
};
@@ -1858,8 +1859,7 @@ private:
auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
foreignModuleIdColumn,
Sqlite::ForeignKeyAction::NoAction,
Sqlite::ForeignKeyAction::NoAction,
Sqlite::Enforment::Deferred);
Sqlite::ForeignKeyAction::NoAction);
auto &nameColumn = table.addColumn("name");
auto &typeIdColumn = table.addColumn("typeId");
auto &majorVersionColumn = table.addColumn("majorVersion");

View File

@@ -33,11 +33,7 @@ namespace QmlDesigner {
class ProjectStorageInterface
{
public:
virtual void synchronize(Storage::Imports imports,
Storage::Types types,
SourceIds sourceIds,
FileStatuses fileStatuses)
= 0;
virtual void synchronize(Storage::SynchronizationPackage package) = 0;
virtual ModuleId moduleId(Utils::SmallStringView name) = 0;

View File

@@ -25,6 +25,7 @@
#pragma once
#include "filestatus.h"
#include "projectstorageids.h"
#include <utils/smallstring.h>
@@ -726,4 +727,34 @@ public:
using ProjectDatas = std::vector<ProjectData>;
class SynchronizationPackage
{
public:
SynchronizationPackage() = default;
SynchronizationPackage(Imports imports, Types types, SourceIds sourceIds)
: imports{std::move(imports)}
, types{std::move(types)}
, sourceIds(std::move(sourceIds))
{}
SynchronizationPackage(Types types)
: types{std::move(types)}
{}
SynchronizationPackage(SourceIds sourceIds)
: sourceIds(std::move(sourceIds))
{}
SynchronizationPackage(SourceIds sourceIds, FileStatuses fileStatuses)
: sourceIds(std::move(sourceIds))
, fileStatuses(std::move(fileStatuses))
{}
public:
Imports imports;
Types types;
SourceIds sourceIds;
FileStatuses fileStatuses;
};
} // namespace QmlDesigner::Storage

View File

@@ -52,40 +52,34 @@ ComponentReferences createComponentReferences(const QMultiHash<QString, QmlDirPa
void ProjectUpdater::update()
{
Storage::Imports imports;
Storage::Types types;
SourceIds sourceIds;
FileStatuses fileStatuses;
Storage::SynchronizationPackage package;
for (const QString &qmldirPath : m_projectManager.qtQmlDirs()) {
SourcePath qmldirSourcePath{qmldirPath};
SourceId qmlDirSourceId = m_pathCache.sourceId(qmldirSourcePath);
switch (fileState(qmlDirSourceId, fileStatuses)) {
switch (fileState(qmlDirSourceId, package.fileStatuses)) {
case FileState::Changed: {
QmlDirParser parser;
parser.parse(m_fileSystem.contentAsQString(qmldirPath));
sourceIds.push_back(qmlDirSourceId);
package.sourceIds.push_back(qmlDirSourceId);
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
Utils::PathString moduleName{parser.typeNamespace()};
ModuleId moduleId = m_projectStorage.moduleId(moduleName);
parseTypeInfos(parser.typeInfos(), directoryId, imports, types, sourceIds, fileStatuses);
parseTypeInfos(parser.typeInfos(), directoryId, package);
parseQmlComponents(createComponentReferences(parser.components()),
directoryId,
moduleId,
imports,
types,
sourceIds,
fileStatuses);
package);
break;
}
case FileState::NotChanged: {
auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId);
parseTypeInfos(qmlProjectDatas, imports, types, sourceIds, fileStatuses);
parseTypeInfos(qmlProjectDatas, package);
break;
}
case FileState::NotExists: {
@@ -95,20 +89,14 @@ void ProjectUpdater::update()
}
}
m_projectStorage.synchronize(std::move(imports),
std::move(types),
std::move(sourceIds),
std::move(fileStatuses));
m_projectStorage.synchronize(std::move(package));
}
void ProjectUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) {}
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
Storage::SynchronizationPackage &package)
{
QString directory{m_pathCache.sourceContextPath(directoryId)};
@@ -118,44 +106,35 @@ void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
Storage::ProjectData projectData{ModuleId{}, sourceId};
parseTypeInfo(projectData, qmltypesPath, imports, types, sourceIds, fileStatuses);
parseTypeInfo(projectData, qmltypesPath, package);
}
}
void ProjectUpdater::parseTypeInfos(const Storage::ProjectDatas &projectDatas,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
Storage::SynchronizationPackage &package)
{
for (const Storage::ProjectData &projectData : projectDatas) {
QString qmltypesPath = m_pathCache.sourcePath(projectData.sourceId).toQString();
parseTypeInfo(projectData, qmltypesPath, imports, types, sourceIds, fileStatuses);
parseTypeInfo(projectData, qmltypesPath, package);
}
}
void ProjectUpdater::parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
Storage::SynchronizationPackage &package)
{
if (fileState(projectData.sourceId, fileStatuses) == FileState::Changed) {
sourceIds.push_back(projectData.sourceId);
if (fileState(projectData.sourceId, package.fileStatuses) == FileState::Changed) {
package.sourceIds.push_back(projectData.sourceId);
const auto content = m_fileSystem.contentAsQString(qmltypesPath);
m_qmlTypesParser.parse(content, imports, types, projectData);
m_qmlTypesParser.parse(content, package.imports, package.types, projectData);
}
}
void ProjectUpdater::parseQmlComponents(ComponentReferences components,
SourceContextId directoryId,
ModuleId moduleId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses)
Storage::SynchronizationPackage &package)
{
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
return std::tie(first.get().typeName, first.get().majorVersion, first.get().minorVersion)
@@ -175,13 +154,13 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components,
Utils::SmallString fileName{component.fileName};
SourceId sourceId = m_pathCache.sourceId(directoryId, fileName);
if (fileState(sourceId, fileStatuses) != FileState::Changed)
if (fileState(sourceId, package.fileStatuses) != FileState::Changed)
continue;
sourceIds.push_back(sourceId);
package.sourceIds.push_back(sourceId);
const auto content = m_fileSystem.contentAsQString(directory + "/" + component.fileName);
auto type = m_qmlDocumentParser.parse(content, imports);
auto type = m_qmlDocumentParser.parse(content, package.imports);
type.typeName = fileName;
type.accessSemantics = Storage::TypeAccessSemantics::Reference;
@@ -191,7 +170,7 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components,
Utils::SmallString{component.typeName},
Storage::Version{component.majorVersion, component.minorVersion}});
types.push_back(std::move(type));
package.types.push_back(std::move(type));
}
}

View File

@@ -88,28 +88,16 @@ private:
void parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
Storage::SynchronizationPackage &package);
void parseTypeInfos(const Storage::ProjectDatas &projectDatas,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
Storage::SynchronizationPackage &package);
void parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
Storage::SynchronizationPackage &package);
void parseQmlComponents(ComponentReferences components,
SourceContextId directoryId,
ModuleId moduleId,
Storage::Imports &imports,
Storage::Types &types,
SourceIds &sourceIds,
FileStatuses &fileStatuses);
Storage::SynchronizationPackage &package);
FileState fileState(SourceId sourceId, FileStatuses &fileStatuses) const;

File diff suppressed because it is too large Load Diff

View File

@@ -36,13 +36,7 @@
class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface
{
public:
MOCK_METHOD(void,
synchronize,
(QmlDesigner::Storage::Imports imports,
QmlDesigner::Storage::Types types,
QmlDesigner::SourceIds sourceIds,
QmlDesigner::FileStatuses fileStatuses),
(override));
MOCK_METHOD(void, synchronize, (QmlDesigner::Storage::SynchronizationPackage package), (override));
MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (Utils::SmallStringView), (override));

View File

@@ -47,6 +47,7 @@ using QmlDesigner::SourceId;
using QmlDesigner::Storage::TypeAccessSemantics;
namespace Storage = QmlDesigner::Storage;
using QmlDesigner::IdPaths;
using QmlDesigner::Storage::SynchronizationPackage;
using QmlDesigner::Storage::Version;
MATCHER_P4(IsStorageType,
@@ -106,6 +107,14 @@ MATCHER_P3(IsFileStatus,
&& fileStatus.lastModified == lastModified;
}
MATCHER(PackageIsEmpty, std::string(negation ? "isn't empty" : "is empty"))
{
const Storage::SynchronizationPackage &package = arg;
return package.imports.empty() && package.types.empty() && package.fileStatuses.empty()
&& package.sourceIds.empty();
}
class ProjectStorageUpdater : public testing::Test
{
public:
@@ -317,7 +326,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeIsEmptyForNoChange)
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 21, 421}));
EXPECT_CALL(projectStorageMock, synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty()));
updater.update();
}
@@ -338,11 +347,14 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
EXPECT_CALL(projectStorageMock, moduleId(Eq("Example")));
EXPECT_CALL(projectStorageMock,
synchronize(ElementsAre(import),
ElementsAre(Eq(objectType)),
UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmltypesPathSourceId, 21, 421))));
synchronize(
AllOf(Field(&SynchronizationPackage::imports, ElementsAre(import)),
Field(&SynchronizationPackage::types, ElementsAre(Eq(objectType))),
Field(&SynchronizationPackage::sourceIds,
UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmltypesPathSourceId, 21, 421))))));
updater.update();
}
@@ -361,7 +373,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
EXPECT_CALL(projectStorageMock, synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty()));
updater.update();
}
@@ -410,34 +422,38 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
EXPECT_CALL(
projectStorageMock,
synchronize(UnorderedElementsAre(import1, import2, import3),
UnorderedElementsAre(
AllOf(IsStorageType("First.qml",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId1),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
AllOf(IsStorageType("First.2.qml",
Storage::ImportedType{"Object2"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId2),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
AllOf(IsStorageType("Second.qml",
Storage::ImportedType{"Object3"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId3),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2))))),
UnorderedElementsAre(qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13),
IsFileStatus(qmlDocumentSourceId3, 22, 14))));
synchronize(AllOf(
Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2, import3)),
Field(&SynchronizationPackage::types,
UnorderedElementsAre(
AllOf(IsStorageType("First.qml",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId1),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
AllOf(IsStorageType("First.2.qml",
Storage::ImportedType{"Object2"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId2),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
AllOf(IsStorageType("Second.qml",
Storage::ImportedType{"Object3"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId3),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2)))))),
Field(&SynchronizationPackage::sourceIds,
UnorderedElementsAre(qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13),
IsFileStatus(qmlDocumentSourceId3, 22, 14))))));
updater.update();
}
@@ -452,24 +468,28 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
EXPECT_CALL(
projectStorageMock,
synchronize(UnorderedElementsAre(import1, import2),
UnorderedElementsAre(
AllOf(IsStorageType("First.qml",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId1),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
AllOf(IsStorageType("First.2.qml",
Storage::ImportedType{"Object2"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId2),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2))))),
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2),
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13))));
synchronize(AllOf(
Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2)),
Field(&SynchronizationPackage::types,
UnorderedElementsAre(
AllOf(IsStorageType("First.qml",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId1),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
AllOf(IsStorageType("First.2.qml",
Storage::ImportedType{"Object2"},
TypeAccessSemantics::Reference,
qmlDocumentSourceId2),
Field(&Storage::Type::exportedTypes,
ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))))),
Field(&SynchronizationPackage::sourceIds,
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13))))));
updater.update();
}