QmlDesigner: Imports updates are source id aware

Imports are now only updated for their source id. The source id is now
used as import id too.

Task-number: QDS-4724
Change-Id: I12988e9c19746291bbc26d5c80fc7dfdd33528e9
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marco Bubke
2021-07-21 14:53:14 +02:00
parent f04da274f1
commit a98d2a6770
4 changed files with 319 additions and 231 deletions

View File

@@ -71,7 +71,7 @@ public:
TypeIds deletedTypeIds;
synchronizeImports(importDependencies, deletedTypeIds);
synchronizeImports(importDependencies, deletedTypeIds, sourceIds);
synchronizeDocuments(documents);
synchronizeTypes(types,
updatedTypeIds,
@@ -271,13 +271,13 @@ public:
Storage::ImportDependencies imports;
imports.reserve(128);
auto callback = [&](Utils::SmallStringView name, int version, int sourceId, long long importId) {
auto callback = [&](Utils::SmallStringView name, int version, int importId) {
auto &lastImport = imports.emplace_back(name,
Storage::VersionNumber{version},
SourceId{sourceId});
SourceId{importId});
lastImport.importDependencies = selectImportsForThatDependentOnThisImportIdStatement
.template values<Storage::Import>(6, importId);
lastImport.dependencies = selectImportsForThatDependentOnThisImportIdStatement
.template values<Storage::Import>(6, importId);
return Sqlite::CallbackControl::Continue;
};
@@ -407,13 +407,16 @@ private:
syncDeclarations(type, insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
}
void synchronizeImports(Storage::ImportDependencies &imports, TypeIds &deletedTypeIds)
void synchronizeImports(Storage::ImportDependencies &imports,
TypeIds &deletedTypeIds,
const SourceIds &sourceIds)
{
if (imports.empty())
return;
auto importIdValues = Utils::transform<std::vector>(sourceIds, [](SourceId sourceId) {
return &sourceId;
});
synchronizeImportsAndUpdatesImportIds(imports, deletedTypeIds);
synchronizeImportDependencies(createSortedImportDependecies(imports));
synchronizeImportsAndUpdatesImportIds(imports, deletedTypeIds, importIdValues);
synchronizeImportDependencies(createSortedImportDependecies(imports), importIdValues);
}
void synchronizeDocuments(Storage::Documents &documents)
@@ -423,57 +426,52 @@ private:
}
void synchronizeImportsAndUpdatesImportIds(Storage::ImportDependencies &imports,
TypeIds &deletedTypeIds)
TypeIds &deletedTypeIds,
std::vector<int> &importIds)
{
auto compareKey = [](auto &&first, auto &&second) {
auto nameCompare = Sqlite::compare(first.name, second.name);
if (nameCompare != 0)
return nameCompare;
return first.version.version - second.version.version;
return first.sourceId.id - second.sourceId.id;
};
std::sort(imports.begin(), imports.end(), [&](auto &&first, auto &&second) {
return compareKey(first, second) < 0;
});
auto range = selectAllImportsStatement.template range<Storage::ImportView>();
auto range = selectImportsForIdsStatement.template range<Storage::ImportView>(
Utils::span(importIds));
auto insert = [&](Storage::ImportDependency &import) {
import.importId = insertImportStatement.template value<ImportId>(import.name,
import.version.version,
&import.sourceId);
insertImportStatement.write(import.name, import.version.version, &import.sourceId);
};
auto update = [&](const Storage::ImportView &importView, Storage::ImportDependency &import) {
if (importView.sourceId.id != import.sourceId.id)
updateImportStatement.write(&importView.importId, &import.sourceId);
import.importId = importView.importId;
if (importView.name != import.name || importView.version != import.version)
updateImportStatement.write(&importView.sourceId, import.name, import.version.version);
};
auto remove = [&](const Storage::ImportView &importView) {
deleteImportStatement.write(&importView.importId);
selectTypeIdsForImportIdStatement.readTo(deletedTypeIds, &importView.importId);
deleteImportStatement.write(&importView.sourceId);
selectTypeIdsForImportIdStatement.readTo(deletedTypeIds, &importView.sourceId);
};
Sqlite::insertUpdateDelete(range, imports, compareKey, insert, update, remove);
}
std::vector<ImportDependency> createSortedImportDependecies(
const Storage::ImportDependencies &imports) const
const Storage::ImportDependencies &importDependencies) const
{
std::vector<ImportDependency> importDependecies;
importDependecies.reserve(imports.size() * 5);
importDependecies.reserve(importDependencies.size() * 5);
for (const Storage::ImportDependency &import : imports) {
for (const Storage::Import &importDependency : import.importDependencies) {
auto importIdForDependency = fetchImportId(importDependency);
for (const Storage::ImportDependency &importDependency : importDependencies) {
for (const Storage::Import &dependency : importDependency.dependencies) {
auto importIdForDependency = fetchImportId(dependency);
if (!importIdForDependency)
throw ImportDoesNotExists{};
importDependecies.emplace_back(import.importId, importIdForDependency);
importDependecies.emplace_back(ImportId{&importDependency.sourceId},
importIdForDependency);
}
}
@@ -484,7 +482,8 @@ private:
return importDependecies;
}
void synchronizeImportDependencies(const std::vector<ImportDependency> &importDependecies)
void synchronizeImportDependencies(const std::vector<ImportDependency> &importDependecies,
std::vector<int> &importIds)
{
auto compareKey = [](ImportDependency first, ImportDependency second) {
auto idCompare = first.id.id - second.id.id;
@@ -495,7 +494,8 @@ private:
return first.dependencyId.id - second.dependencyId.id;
};
auto range = selectAllImportDependenciesStatement.template range<ImportDependency>();
auto range = selectImportDependenciesForIdsStatement.template range<ImportDependency>(
Utils::span(importIds));
auto insert = [&](ImportDependency dependency) {
insertImportDependencyStatement.write(&dependency.id, &dependency.dependencyId);
@@ -1635,7 +1635,6 @@ private:
table.addColumn("importId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
auto &nameColumn = table.addColumn("name");
auto &versionColumn = table.addColumn("version");
table.addColumn("sourceId");
table.addUniqueIndex({nameColumn, versionColumn});
@@ -1907,23 +1906,28 @@ public:
database};
WriteStatement deleteEnumerationDeclarationStatement{
"DELETE FROM enumerationDeclarations WHERE enumerationDeclarationId=?", database};
mutable ReadWriteStatement<1> insertImportStatement{
"INSERT INTO imports(name, version, sourceId) VALUES(?1, ?2, ?3) RETURNING importId",
database};
WriteStatement updateImportStatement{"UPDATE imports SET sourceId=?2 WHERE importId=?1", database};
WriteStatement insertImportStatement{
"INSERT INTO imports(name, version, importId) VALUES(?1, ?2, ?3)", database};
WriteStatement updateImportStatement{"UPDATE imports SET name=?2, version=?3 WHERE importId=?1",
database};
WriteStatement deleteImportStatement{"DELETE FROM imports WHERE importId=?", database};
mutable ReadStatement<1> selectImportIdByNameStatement{
"SELECT importId FROM imports WHERE name=? ORDER BY version DESC LIMIT 1", database};
mutable ReadStatement<1> selectImportIdByNameAndVersionStatement{
"SELECT importId FROM imports WHERE name=? AND version=?", database};
mutable ReadStatement<4> selectAllImportsStatement{
"SELECT name, version, sourceId, importId FROM imports ORDER BY name, version", database};
mutable ReadStatement<3> selectImportsForIdsStatement{
"SELECT name, version, importId FROM imports WHERE importId IN carray(?1) ORDER BY "
"importId",
database};
mutable ReadStatement<3> selectAllImportsStatement{
"SELECT name, version, importId FROM imports ORDER BY importId", database};
WriteStatement insertImportDependencyStatement{
"INSERT INTO importDependencies(importId, parentImportId) VALUES(?1, ?2)", database};
WriteStatement deleteImportDependencyStatement{
"DELETE FROM importDependencies WHERE importId=?1 AND parentImportId=?2", database};
mutable ReadStatement<2> selectAllImportDependenciesStatement{
"SELECT importId, parentImportId FROM importDependencies ORDER BY importId, parentImportId",
mutable ReadStatement<2> selectImportDependenciesForIdsStatement{
"SELECT importId, parentImportId FROM importDependencies WHERE importId IN carray(?1) "
"ORDER BY importId, parentImportId",
database};
mutable ReadStatement<2> selectImportsForThatDependentOnThisImportIdStatement{
"SELECT name, version FROM importDependencies JOIN imports ON "

View File

@@ -71,6 +71,11 @@ public:
return first.version == second.version;
}
friend bool operator!=(VersionNumber first, VersionNumber second) noexcept
{
return !(first == second);
}
public:
int version = -1;
};
@@ -545,11 +550,11 @@ class ImportDependency : public Import
{
public:
explicit ImportDependency(Utils::SmallStringView name,
VersionNumber version = VersionNumber{},
SourceId sourceId = SourceId{},
VersionNumber version,
SourceId sourceId,
Imports importDependencies = {})
: Import(name, version)
, importDependencies{std::move(importDependencies)}
, dependencies{std::move(importDependencies)}
, sourceId{sourceId}
{}
@@ -561,14 +566,12 @@ public:
friend bool operator==(const ImportDependency &first, const ImportDependency &second)
{
return static_cast<const Import &>(first) == static_cast<const Import &>(second)
&& first.sourceId == second.sourceId
&& first.importDependencies == second.importDependencies;
&& first.sourceId == second.sourceId && first.dependencies == second.dependencies;
}
public:
Imports importDependencies;
Imports dependencies;
SourceId sourceId;
ImportId importId;
};
using ImportDependencies = std::vector<ImportDependency>;
@@ -576,11 +579,10 @@ using ImportDependencies = std::vector<ImportDependency>;
class ImportView
{
public:
explicit ImportView(Utils::SmallStringView name, int version, int sourceId, long long importId)
explicit ImportView(Utils::SmallStringView name, int version, int sourceId)
: name{name}
, version{version}
, sourceId{sourceId}
, importId{importId}
{}
friend bool operator==(const ImportView &first, const ImportView &second)
@@ -593,7 +595,6 @@ public:
Utils::SmallStringView name;
VersionNumber version;
SourceId sourceId;
ImportId importId;
};
} // namespace QmlDesigner::Storage

View File

@@ -1111,7 +1111,7 @@ std::ostream &operator<<(std::ostream &out, const Import &import)
std::ostream &operator<<(std::ostream &out, const ImportDependency &import)
{
return out << "(" << import.name << ", " << import.version << ", " << import.sourceId << ", "
<< import.importDependencies << ")";
<< import.dependencies << ")";
}
} // namespace Storage

View File

@@ -140,18 +140,17 @@ MATCHER_P4(IsPropertyDeclaration,
&& propertyDeclaration.traits == traits;
}
MATCHER_P2(IsBasicImport,
MATCHER_P2(IsImport,
name,
version,
std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::ImportDependency{name, version}))
std::string(negation ? "isn't " : "is ") + PrintToString(Storage::Import{name, version}))
{
const Storage::Import &import = arg;
return import.name == name && import.version == version;
}
MATCHER_P3(IsImport,
MATCHER_P3(IsImportDependency,
name,
version,
sourceId,
@@ -605,18 +604,19 @@ protected:
importSourceId1 = sourcePathCache.sourceId(importPath1);
importSourceId2 = sourcePathCache.sourceId(importPath2);
importSourceId3 = sourcePathCache.sourceId(importPath3);
importSourceId5 = sourcePathCache.sourceId("/path/to/.");
return Storage::ImportDependencies{
Storage::ImportDependency{"Qml", Storage::VersionNumber{2}, importSourceId1, {}},
Storage::ImportDependency{"QtQuick",
Storage::VersionNumber{},
importSourceId2,
{Storage::ImportDependency{"Qml", Storage::VersionNumber{2}}}},
{Storage::Import{"Qml", Storage::VersionNumber{2}}}},
Storage::ImportDependency{"/path/to",
Storage::VersionNumber{},
SourceId{},
{Storage::ImportDependency{"QtQuick"},
Storage::ImportDependency{"Qml", Storage::VersionNumber{2}}}}};
importSourceId5,
{Storage::Import{"QtQuick"},
Storage::Import{"Qml", Storage::VersionNumber{2}}}}};
}
Storage::Imports createImports()
@@ -632,7 +632,7 @@ protected:
auto importDependencies = createImportDependencies();
importDependencies.push_back(
Storage::ImportDependency{"Qml2", Storage::VersionNumber{3}, importSourceId1, {}});
Storage::ImportDependency{"Qml2", Storage::VersionNumber{3}, importSourceId4, {}});
return importDependencies;
}
@@ -655,7 +655,17 @@ protected:
Storage::Document{sourceId4, imports},
Storage::Document{sourceId5, imports}};
storage.synchronize(importDependencies, documents, {}, {});
storage.synchronize(importDependencies,
documents,
{},
{sourceId1,
sourceId2,
sourceId3,
sourceId4,
sourceId5,
importSourceId1,
importSourceId2,
importSourceId5});
importIds = storage.fetchImportIds(imports);
importId1 = importIds[0];
importId2 = importIds[1];
@@ -688,6 +698,7 @@ protected:
SourceId importSourceId2;
SourceId importSourceId3;
SourceId importSourceId4;
SourceId importSourceId5;
Storage::Imports imports;
ImportId importId1;
ImportId importId2;
@@ -2089,285 +2100,357 @@ TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddImports)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImport("/path/to", Storage::VersionNumber{}, SourceId{})));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddImportsAgain)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImport("/path/to", Storage::VersionNumber{}, SourceId{})));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddMoreImports)
TEST_F(ProjectStorageSlowTest, SynchronizeImportsUpdateToMoreImports)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
importDependencies.push_back(
Storage::ImportDependency{"QtQuick.Foo", Storage::VersionNumber{1}, importSourceId3});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies,
{},
{},
{importSourceId1, importSourceId2, importSourceId3, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
IsImport("QtQuick.Foo", Storage::VersionNumber{1}, importSourceId3)));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
IsImportDependency("QtQuick.Foo", Storage::VersionNumber{1}, importSourceId3)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddOneMoreImports)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto newImportDependency = Storage::ImportDependency{"QtQuick.Foo",
Storage::VersionNumber{1},
importSourceId3};
storage.synchronize({newImportDependency}, {}, {}, {importSourceId3});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
IsImportDependency("QtQuick.Foo", Storage::VersionNumber{1}, importSourceId3)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddSameImportNameButDifferentVersion)
{
auto importSourceIdQml4 = sourcePathCache.sourceId("/path/Qml.4");
auto importSourceIdQml3 = sourcePathCache.sourceId("/path/Qml.3");
Storage::ImportDependencies importDependencies{createImportDependencies()};
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{4}, importSourceId3});
storage.synchronize(importDependencies, {}, {}, {});
importDependencies.pop_back();
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceId3});
Storage::ImportDependency{"Qml", Storage::VersionNumber{4}, importSourceIdQml4});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto newImportDependency = Storage::ImportDependency{"Qml",
Storage::VersionNumber{3},
importSourceIdQml3};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({newImportDependency}, {}, {}, {importSourceIdQml4, importSourceIdQml3});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("Qml", Storage::VersionNumber{3}, importSourceId3),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImport("/path/to", Storage::VersionNumber{}, SourceId{})));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("Qml", Storage::VersionNumber{3}, importSourceIdQml3),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsRemoveImport)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
importDependencies.pop_back();
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({}, {}, {}, {importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2)));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsUpdateImport)
TEST_F(ProjectStorageSlowTest, SynchronizeImportsChangeSourceId)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
importDependencies[1].sourceId = importSourceId3;
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[1]}, {}, {}, {importSourceId2, importSourceId3});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImport("QtQuick", Storage::VersionNumber{}, importSourceId3),
IsImport("/path/to", Storage::VersionNumber{}, SourceId{})));
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId3),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsChangeName)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
importDependencies[0].name = "Qml2";
importDependencies[1].dependencies[0].name = "Qml2";
importDependencies[2].dependencies[1].name = "Qml2";
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
IsImportDependency("Qml2", Storage::VersionNumber{2}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsChangeVersion)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
importDependencies[0].version = Storage::VersionNumber{3};
importDependencies[1].dependencies[0].version = Storage::VersionNumber{3};
importDependencies[2].dependencies[1].version = Storage::VersionNumber{3};
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
IsImportDependency("Qml", Storage::VersionNumber{3}, importSourceId1),
IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5)));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddImportDependecies)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
ElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QtQuick",
Storage::VersionNumber{}))))));
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
ElementsAre(IsImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddImportDependeciesWhichDoesNotExitsThrows)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
importDependencies[1].importDependencies.push_back(
Storage::ImportDependency{"QmlBase", Storage::VersionNumber{2}});
importDependencies[1].dependencies.push_back(Storage::Import{"QmlBase", Storage::VersionNumber{2}});
ASSERT_THROW(storage.synchronize(importDependencies, {}, {}, {}),
ASSERT_THROW(storage.synchronize(importDependencies,
{},
{},
{importSourceId1, importSourceId2, importSourceId5}),
QmlDesigner::ImportDoesNotExists);
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsRemovesDependeciesForRemovedImports)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto last = importDependencies.back();
importDependencies.pop_back();
storage.synchronize(importDependencies, {}, {}, {});
last.importDependencies.pop_back();
storage.synchronize({}, {}, {}, {importSourceId5});
last.dependencies.pop_back();
importDependencies.push_back(last);
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[2]}, {}, {}, {importSourceId5});
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
ElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
ElementsAre(IsImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddMoreImportDependecies)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto importSourceIdQmlBase = sourcePathCache.sourceId("/path/QmlBase");
importDependencies.push_back(
Storage::ImportDependency{"QmlBase", Storage::VersionNumber{2}, importSourceId1, {}});
importDependencies[1].importDependencies.push_back(
Storage::ImportDependency{"QmlBase", Storage::VersionNumber{2}});
Storage::ImportDependency{"QmlBase", Storage::VersionNumber{2}, importSourceIdQmlBase});
importDependencies[1].dependencies.push_back(Storage::Import{"QmlBase", Storage::VersionNumber{2}});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[1], importDependencies[3]},
{},
{},
{importSourceId2, importSourceIdQmlBase});
ASSERT_THAT(
storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QmlBase", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QmlBase", Storage::VersionNumber{2})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QmlBase", Storage::VersionNumber{2}, importSourceIdQmlBase),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QmlBase", Storage::VersionNumber{2})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsAddMoreImportDependeciesWithDifferentVersionNumber)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto importSourceIdQml3 = sourcePathCache.sourceId("/path/Qml.3");
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceId1, {}});
importDependencies[1].importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}});
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceIdQml3, {}});
importDependencies[1].dependencies.push_back(Storage::Import{"Qml", Storage::VersionNumber{3}});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[1], importDependencies[3]},
{},
{},
{importSourceId2, importSourceIdQml3});
ASSERT_THAT(
storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("Qml", Storage::VersionNumber{3}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("Qml", Storage::VersionNumber{3})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("Qml", Storage::VersionNumber{3}, importSourceIdQml3),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("Qml", Storage::VersionNumber{3})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsDependencyGetsHighestVersionIfNoVersionIsSupplied)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto importSourceIdQml3 = sourcePathCache.sourceId("/path/Qml.3");
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceId1, {}});
importDependencies[1].importDependencies.push_back(Storage::ImportDependency{"Qml"});
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceIdQml3, {}});
importDependencies[1].dependencies.push_back(Storage::Import{"Qml"});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[1], importDependencies[3]},
{},
{},
{importSourceId2, importSourceIdQml3});
ASSERT_THAT(
storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("Qml", Storage::VersionNumber{3}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("Qml", Storage::VersionNumber{3})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("Qml", Storage::VersionNumber{3}, importSourceIdQml3),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("Qml", Storage::VersionNumber{3})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsDependencyGetsOnlyTheHighestDependency)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto importSourceIdQml1 = sourcePathCache.sourceId("/path/Qml.1");
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{1}, importSourceId1, {}});
importDependencies[1].importDependencies.push_back(Storage::ImportDependency{"Qml"});
Storage::ImportDependency{"Qml", Storage::VersionNumber{1}, importSourceIdQml1, {}});
importDependencies[1].dependencies.push_back(Storage::Import{"Qml"});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[1], importDependencies[3]},
{},
{},
{importSourceId2, importSourceIdQml1});
ASSERT_THAT(
storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("Qml", Storage::VersionNumber{1}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("Qml", Storage::VersionNumber{1}, importSourceIdQml1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeImportsDependencyRemoveDuplicateDependencies)
{
Storage::ImportDependencies importDependencies{createImportDependencies()};
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize(importDependencies, {}, {}, {importSourceId1, importSourceId2, importSourceId5});
auto importSourceIdQml3 = sourcePathCache.sourceId("/path/Qml.3");
importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceId1, {}});
importDependencies[2].importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}});
importDependencies[2].importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{2}});
importDependencies[2].importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}});
importDependencies[2].importDependencies.push_back(
Storage::ImportDependency{"Qml", Storage::VersionNumber{2}});
Storage::ImportDependency{"Qml", Storage::VersionNumber{3}, importSourceIdQml3});
importDependencies[2].dependencies.push_back(Storage::Import{"Qml", Storage::VersionNumber{3}});
importDependencies[2].dependencies.push_back(Storage::Import{"Qml", Storage::VersionNumber{2}});
importDependencies[2].dependencies.push_back(Storage::Import{"Qml", Storage::VersionNumber{3}});
importDependencies[2].dependencies.push_back(Storage::Import{"Qml", Storage::VersionNumber{2}});
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({importDependencies[2], importDependencies[3]},
{},
{},
{importSourceId5, importSourceIdQml3});
ASSERT_THAT(
storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImport("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("Qml", Storage::VersionNumber{3}, importSourceId1),
Field(&Storage::ImportDependency::importDependencies, IsEmpty())),
AllOf(IsImport("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImport("/path/to", Storage::VersionNumber{}, SourceId{}),
Field(&Storage::ImportDependency::importDependencies,
UnorderedElementsAre(IsBasicImport("Qml", Storage::VersionNumber{2}),
IsBasicImport("Qml", Storage::VersionNumber{3}),
IsBasicImport("QtQuick", Storage::VersionNumber{}))))));
ASSERT_THAT(storage.fetchAllImports(),
UnorderedElementsAre(
AllOf(IsImportDependency("Qml", Storage::VersionNumber{2}, importSourceId1),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("Qml", Storage::VersionNumber{3}, importSourceIdQml3),
Field(&Storage::ImportDependency::dependencies, IsEmpty())),
AllOf(IsImportDependency("QtQuick", Storage::VersionNumber{}, importSourceId2),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2})))),
AllOf(IsImportDependency("/path/to", Storage::VersionNumber{}, importSourceId5),
Field(&Storage::ImportDependency::dependencies,
UnorderedElementsAre(IsImport("Qml", Storage::VersionNumber{2}),
IsImport("Qml", Storage::VersionNumber{3}),
IsImport("QtQuick", Storage::VersionNumber{}))))));
}
TEST_F(ProjectStorageSlowTest, RemovingImportRemovesDependentTypesToo)
@@ -2377,7 +2460,7 @@ TEST_F(ProjectStorageSlowTest, RemovingImportRemovesDependentTypesToo)
Storage::ImportDependencies importDependencies{createImportDependencies()};
importDependencies.pop_back();
importDependencies.pop_back();
storage.synchronize(importDependencies, {}, {}, {});
storage.synchronize({}, {}, {}, {importSourceId2, importSourceId5});
ASSERT_THAT(storage.fetchTypes(),
UnorderedElementsAre(AllOf(IsStorageType(importId1,