QmlDesigner: Synchronize alias properties

Alias property declarations are handled like normal property declarations
except that the have an value for the target property declaration id.
So they are distinguishable by the alias id. If it is not set it is a
normal property declaration. If it is set it is alias property
declaration. Alias property declaration are always synchronized after
all normal property declaration are synchronized. This synchronization
is not checking if the target property declaration changed. This update
has to be executed by the target property declaration.

Task-number: QDS-4524
Change-Id: I483840c821e12c93f1be67bf5ed6da396f8b45a3
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2021-06-09 17:56:34 +02:00
parent 90cc7fed3b
commit 66ba9c4843
6 changed files with 570 additions and 161 deletions

View File

@@ -73,6 +73,9 @@ public:
for (auto &&type : types) for (auto &&type : types)
syncType(type); syncType(type);
for (auto &&type : types)
synchronizeAliasPropertyDeclarations(type);
deleteNotUpdatedTypes(updatedTypeIds, sourceIds); deleteNotUpdatedTypes(updatedTypeIds, sourceIds);
transaction.commit(); transaction.commit();
@@ -119,7 +122,7 @@ public:
PropertyDeclarationId fetchPropertyDeclarationByTypeIdAndName(TypeId typeId, PropertyDeclarationId fetchPropertyDeclarationByTypeIdAndName(TypeId typeId,
Utils::SmallStringView name) Utils::SmallStringView name)
{ {
return selectPropertyDeclarationByTypeIdAndNameStatement return selectPropertyDeclarationIdByTypeIdAndNameStatement
.template valueWithTransaction<PropertyDeclarationId>(&typeId, name); .template valueWithTransaction<PropertyDeclarationId>(&typeId, name);
} }
@@ -485,7 +488,7 @@ private:
auto insert = [&](const Storage::PropertyDeclaration &value) { auto insert = [&](const Storage::PropertyDeclaration &value) {
auto propertyTypeId = fetchTypeIdByNameUngarded(value.typeName, importIds); auto propertyTypeId = fetchTypeIdByNameUngarded(value.typeName, importIds);
insertPropertyDeclarationStatement.write(&typeId, upsertPropertyDeclarationStatement.write(&typeId,
value.name, value.name,
&propertyTypeId, &propertyTypeId,
static_cast<int>(value.traits)); static_cast<int>(value.traits));
@@ -510,6 +513,56 @@ private:
Sqlite::insertUpdateDelete(range, propertyDeclarations, compareKey, insert, update, remove); Sqlite::insertUpdateDelete(range, propertyDeclarations, compareKey, insert, update, remove);
} }
void synchronizeAliasPropertyDeclarations(Storage::Type &type)
{
auto &aliasDeclarations = type.aliasDeclarations;
TypeId typeId = type.typeId;
ImportIds &importIds = type.importIds;
std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) {
return Sqlite::compare(first.name, second.name) < 0;
});
auto range = selectPropertyDeclarationsWithAliasForTypeIdStatement
.template range<Storage::AliasPropertyDeclarationView>(&typeId);
auto compareKey = [](const Storage::AliasPropertyDeclarationView &view,
const Storage::AliasPropertyDeclaration &value) {
return Sqlite::compare(view.name, value.name);
};
auto insert = [&](const Storage::AliasPropertyDeclaration &value) {
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeNameAndName(
value.aliasTypeName, value.aliasPropertyName, importIds);
insertPropertyDeclarationWithAliasStatement.write(&typeId,
value.name,
&aliasTypeId,
propertyTraits,
&aliasId);
};
auto update = [&](const Storage::AliasPropertyDeclarationView &view,
const Storage::AliasPropertyDeclaration &value) {
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeNameAndName(
value.aliasTypeName, value.aliasPropertyName, importIds);
if (view.aliasId == aliasId)
return;
updatePropertyDeclarationWithAliasStatement.write(&view.id,
&aliasTypeId,
propertyTraits,
&aliasId);
};
auto remove = [&](const Storage::AliasPropertyDeclarationView &view) {
deletePropertyDeclarationStatement.write(&view.id);
};
Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
}
Utils::PathString createJson(const Storage::ParameterDeclarations &parameters) Utils::PathString createJson(const Storage::ParameterDeclarations &parameters)
{ {
Utils::PathString json; Utils::PathString json;
@@ -524,7 +577,7 @@ private:
json.append(parameter.name); json.append(parameter.name);
json.append("\",\"tn\":\""); json.append("\",\"tn\":\"");
json.append(parameter.typeName); json.append(parameter.typeName);
if (parameter.traits == Storage::DeclarationTraits::Non) { if (parameter.traits == Storage::PropertyDeclarationTraits::Non) {
json.append("\"}"); json.append("\"}");
} else { } else {
json.append("\",\"tr\":"); json.append("\",\"tr\":");
@@ -748,6 +801,22 @@ private:
throw TypeNameDoesNotExists{}; throw TypeNameDoesNotExists{};
} }
using PropertyDeclarationViewTuple = std::tuple<TypeId, PropertyDeclarationId, long long>;
PropertyDeclarationViewTuple fetchPropertyDeclarationByTypeNameAndName(
const Storage::TypeName &typeName, Utils::SmallStringView name, ImportIds &importIds)
{
TypeId typeId = fetchTypeIdByNameUngarded(typeName, importIds);
auto propertyDeclaration = selectPropertyDeclarationByTypeIdAndNameStatement
.template value<PropertyDeclarationViewTuple>(&typeId, name);
if (auto id = std::get<PropertyDeclarationId>(propertyDeclaration); id)
return propertyDeclaration;
throw PropertyNameDoesNotExists{};
}
SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath) SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath)
{ {
return selectSourceContextIdFromSourceContextsBySourceContextPathStatement return selectSourceContextIdFromSourceContextsBySourceContextPathStatement
@@ -933,6 +1002,7 @@ private:
Sqlite::ForeignKeyAction::NoAction, Sqlite::ForeignKeyAction::NoAction,
Sqlite::ForeignKeyAction::Restrict); Sqlite::ForeignKeyAction::Restrict);
propertyDeclarationTable.addColumn("propertyTraits"); propertyDeclarationTable.addColumn("propertyTraits");
propertyDeclarationTable.addColumn("aliasPropertyDeclarationId");
propertyDeclarationTable.addUniqueIndex({typeIdColumn, nameColumn}); propertyDeclarationTable.addUniqueIndex({typeIdColumn, nameColumn});
@@ -1056,13 +1126,7 @@ public:
" SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) " " SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) "
"SELECT typeId FROM typeSelection WHERE typeId=?2 LIMIT 1", "SELECT typeId FROM typeSelection WHERE typeId=?2 LIMIT 1",
database}; database};
ReadWriteStatement<1> upsertPropertyDeclarationStatement{ mutable ReadStatement<1> selectPropertyDeclarationIdByTypeIdAndNameStatement{
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits) "
"VALUES(?1, ?2, ?3, nullif(?4, 0)) ON CONFLICT DO UPDATE SET typeId=excluded.typeId, "
"name=excluded.name, propertyTypeId=excluded.propertyTypeId, "
"propertyTraits=excluded.propertyTraits RETURNING propertyDeclarationId",
database};
mutable ReadStatement<1> selectPropertyDeclarationByTypeIdAndNameStatement{
"WITH RECURSIVE " "WITH RECURSIVE "
" typeSelection(typeId) AS (" " typeSelection(typeId) AS ("
" VALUES(?1) " " VALUES(?1) "
@@ -1071,6 +1135,16 @@ public:
"SELECT propertyDeclarationId FROM propertyDeclarations JOIN typeSelection USING(typeId) " "SELECT propertyDeclarationId FROM propertyDeclarations JOIN typeSelection USING(typeId) "
" WHERE name=?2 LIMIT 1", " WHERE name=?2 LIMIT 1",
database}; database};
mutable ReadStatement<3> selectPropertyDeclarationByTypeIdAndNameStatement{
"WITH RECURSIVE "
" typeSelection(typeId) AS ("
" VALUES(?1) "
" UNION ALL "
" SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) "
"SELECT typeId, propertyDeclarationId, propertyTraits FROM propertyDeclarations JOIN "
"typeSelection USING(typeId) "
" WHERE name=?2 LIMIT 1",
database};
WriteStatement upsertExportedTypesStatement{"INSERT INTO exportedTypes(importId, name, typeId) " WriteStatement upsertExportedTypesStatement{"INSERT INTO exportedTypes(importId, name, typeId) "
"VALUES(?1, ?2, ?3) ON CONFLICT DO NOTHING", "VALUES(?1, ?2, ?3) ON CONFLICT DO NOTHING",
database}; database};
@@ -1133,11 +1207,13 @@ public:
database}; database};
ReadStatement<4> selectPropertyDeclarationsForTypeIdStatement{ ReadStatement<4> selectPropertyDeclarationsForTypeIdStatement{
"SELECT name, propertyTraits, propertyTypeId, propertyDeclarationId FROM " "SELECT name, propertyTraits, propertyTypeId, propertyDeclarationId FROM "
"propertyDeclarations WHERE typeId=? ORDER BY name", "propertyDeclarations WHERE typeId=? AND aliasPropertyDeclarationId IS NULL ORDER BY "
"name",
database}; database};
WriteStatement insertPropertyDeclarationStatement{ WriteStatement upsertPropertyDeclarationStatement{
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits) " "INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits) "
"VALUES(?1, ?2, ?3, ?4) ", "VALUES(?1, ?2, ?3, ?4) ON CONFLICT DO UPDATE SET propertyTypeId=excluded.propertyTypeId, "
"propertyTraits=excluded.propertyTraits, aliasPropertyDeclarationId=NULL",
database}; database};
WriteStatement updatePropertyDeclarationStatement{ WriteStatement updatePropertyDeclarationStatement{
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3 WHERE " "UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3 WHERE "
@@ -1145,6 +1221,18 @@ public:
database}; database};
WriteStatement deletePropertyDeclarationStatement{ WriteStatement deletePropertyDeclarationStatement{
"DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database}; "DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database};
ReadStatement<3> selectPropertyDeclarationsWithAliasForTypeIdStatement{
"SELECT name, propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations "
"WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL ORDER BY name",
database};
WriteStatement insertPropertyDeclarationWithAliasStatement{
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, "
"aliasPropertyDeclarationId) VALUES(?1, ?2, ?3, ?4, ?5) ",
database};
WriteStatement updatePropertyDeclarationWithAliasStatement{
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, "
"aliasPropertyDeclarationId=?4 WHERE propertyDeclarationId=?1",
database};
mutable ReadStatement<4> selectFunctionDeclarationsForTypeIdStatement{ mutable ReadStatement<4> selectFunctionDeclarationsForTypeIdStatement{
"SELECT name, returnTypeName, signature, functionDeclarationId FROM " "SELECT name, returnTypeName, signature, functionDeclarationId FROM "
"functionDeclarations WHERE typeId=? ORDER BY name", "functionDeclarations WHERE typeId=? ORDER BY name",

View File

@@ -83,4 +83,10 @@ public:
const char *what() const noexcept override { return "The type name does not exist!"; } const char *what() const noexcept override { return "The type name does not exist!"; }
}; };
class PropertyNameDoesNotExists : std::exception
{
public:
const char *what() const noexcept override { return "The property name does not exist!"; }
};
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -36,19 +36,20 @@ namespace QmlDesigner::Storage {
enum class TypeAccessSemantics : int { Invalid, Reference, Value, Sequence, IsEnum = 1 << 8 }; enum class TypeAccessSemantics : int { Invalid, Reference, Value, Sequence, IsEnum = 1 << 8 };
enum class DeclarationTraits : unsigned int { enum class PropertyDeclarationTraits : unsigned int {
Non = 0, Non = 0,
IsReadOnly = 1 << 0, IsReadOnly = 1 << 0,
IsPointer = 1 << 1, IsPointer = 1 << 1,
IsList = 1 << 2 IsList = 1 << 2
}; };
constexpr DeclarationTraits operator|(DeclarationTraits first, DeclarationTraits second) constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first,
PropertyDeclarationTraits second)
{ {
return static_cast<DeclarationTraits>(static_cast<int>(first) | static_cast<int>(second)); return static_cast<PropertyDeclarationTraits>(static_cast<int>(first) | static_cast<int>(second));
} }
constexpr bool operator&(DeclarationTraits first, DeclarationTraits second) constexpr bool operator&(PropertyDeclarationTraits first, PropertyDeclarationTraits second)
{ {
return static_cast<int>(first) & static_cast<int>(second); return static_cast<int>(first) & static_cast<int>(second);
} }
@@ -219,7 +220,7 @@ public:
explicit ParameterDeclaration() = default; explicit ParameterDeclaration() = default;
explicit ParameterDeclaration(Utils::SmallStringView name, explicit ParameterDeclaration(Utils::SmallStringView name,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
DeclarationTraits traits = {}) PropertyDeclarationTraits traits = {})
: name{name} : name{name}
, typeName{typeName} , typeName{typeName}
, traits{traits} , traits{traits}
@@ -228,7 +229,7 @@ public:
explicit ParameterDeclaration(Utils::SmallStringView name, Utils::SmallStringView typeName, int traits) explicit ParameterDeclaration(Utils::SmallStringView name, Utils::SmallStringView typeName, int traits)
: name{name} : name{name}
, typeName{typeName} , typeName{typeName}
, traits{static_cast<DeclarationTraits>(traits)} , traits{static_cast<PropertyDeclarationTraits>(traits)}
{} {}
friend bool operator==(const ParameterDeclaration &first, const ParameterDeclaration &second) friend bool operator==(const ParameterDeclaration &first, const ParameterDeclaration &second)
@@ -240,7 +241,7 @@ public:
public: public:
Utils::SmallString name; Utils::SmallString name;
Utils::SmallString typeName; Utils::SmallString typeName;
DeclarationTraits traits = {}; PropertyDeclarationTraits traits = {};
}; };
using ParameterDeclarations = std::vector<ParameterDeclaration>; using ParameterDeclarations = std::vector<ParameterDeclaration>;
@@ -345,7 +346,9 @@ class PropertyDeclaration
{ {
public: public:
explicit PropertyDeclaration() = default; explicit PropertyDeclaration() = default;
explicit PropertyDeclaration(Utils::SmallStringView name, TypeName typeName, DeclarationTraits traits) explicit PropertyDeclaration(Utils::SmallStringView name,
TypeName typeName,
PropertyDeclarationTraits traits)
: name{name} : name{name}
, typeName{std::move(typeName)} , typeName{std::move(typeName)}
, traits{traits} , traits{traits}
@@ -354,13 +357,13 @@ public:
explicit PropertyDeclaration(Utils::SmallStringView name, Utils::SmallStringView typeName, int traits) explicit PropertyDeclaration(Utils::SmallStringView name, Utils::SmallStringView typeName, int traits)
: name{name} : name{name}
, typeName{NativeType{typeName}} , typeName{NativeType{typeName}}
, traits{static_cast<DeclarationTraits>(traits)} , traits{static_cast<PropertyDeclarationTraits>(traits)}
{} {}
public: public:
Utils::SmallString name; Utils::SmallString name;
TypeName typeName; TypeName typeName;
DeclarationTraits traits = {}; PropertyDeclarationTraits traits = {};
TypeId typeId; TypeId typeId;
}; };
@@ -374,7 +377,7 @@ public:
long long typeId, long long typeId,
long long id) long long id)
: name{name} : name{name}
, traits{static_cast<DeclarationTraits>(traits)} , traits{static_cast<PropertyDeclarationTraits>(traits)}
, typeId{typeId} , typeId{typeId}
, id{id} , id{id}
@@ -382,11 +385,45 @@ public:
public: public:
Utils::SmallStringView name; Utils::SmallStringView name;
DeclarationTraits traits = {}; PropertyDeclarationTraits traits = {};
TypeId typeId; TypeId typeId;
PropertyDeclarationId id; PropertyDeclarationId id;
}; };
class AliasPropertyDeclaration
{
public:
explicit AliasPropertyDeclaration(Utils::SmallStringView name,
TypeName aliasTypeName,
Utils::SmallStringView aliasPropertyName)
: name{name}
, aliasTypeName{std::move(aliasTypeName)}
, aliasPropertyName{aliasPropertyName}
{}
public:
Utils::SmallString name;
TypeName aliasTypeName;
Utils::SmallString aliasPropertyName;
};
using AliasDeclarations = std::vector<AliasPropertyDeclaration>;
class AliasPropertyDeclarationView
{
public:
explicit AliasPropertyDeclarationView(Utils::SmallStringView name, long long id, long long aliasId)
: name{name}
, id{id}
, aliasId{aliasId}
{}
public:
Utils::SmallString name;
PropertyDeclarationId id;
PropertyDeclarationId aliasId;
};
class Type class Type
{ {
public: public:
@@ -402,6 +439,7 @@ public:
FunctionDeclarations functionDeclarations = {}, FunctionDeclarations functionDeclarations = {},
SignalDeclarations signalDeclarations = {}, SignalDeclarations signalDeclarations = {},
EnumerationDeclarations enumerationDeclarations = {}, EnumerationDeclarations enumerationDeclarations = {},
AliasDeclarations aliasDeclarations = {},
TypeId typeId = TypeId{}) TypeId typeId = TypeId{})
: typeName{typeName} : typeName{typeName}
, prototype{std::move(prototype)} , prototype{std::move(prototype)}
@@ -411,6 +449,7 @@ public:
, functionDeclarations{std::move(functionDeclarations)} , functionDeclarations{std::move(functionDeclarations)}
, signalDeclarations{std::move(signalDeclarations)} , signalDeclarations{std::move(signalDeclarations)}
, enumerationDeclarations{std::move(enumerationDeclarations)} , enumerationDeclarations{std::move(enumerationDeclarations)}
, aliasDeclarations{std::move(aliasDeclarations)}
, accessSemantics{accessSemantics} , accessSemantics{accessSemantics}
, sourceId{sourceId} , sourceId{sourceId}
, typeId{typeId} , typeId{typeId}
@@ -454,6 +493,7 @@ public:
FunctionDeclarations functionDeclarations; FunctionDeclarations functionDeclarations;
SignalDeclarations signalDeclarations; SignalDeclarations signalDeclarations;
EnumerationDeclarations enumerationDeclarations; EnumerationDeclarations enumerationDeclarations;
AliasDeclarations aliasDeclarations;
TypeAccessSemantics accessSemantics = TypeAccessSemantics::Invalid; TypeAccessSemantics accessSemantics = TypeAccessSemantics::Invalid;
SourceId sourceId; SourceId sourceId;
TypeId typeId; TypeId typeId;

View File

@@ -1053,22 +1053,22 @@ std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyD
<< "\", " << propertyDeclaration.traits << ", " << propertyDeclaration.typeId << ")"; << "\", " << propertyDeclaration.traits << ", " << propertyDeclaration.typeId << ")";
} }
std::ostream &operator<<(std::ostream &out, DeclarationTraits traits) std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
{ {
const char *padding = ""; const char *padding = "";
out << "("; out << "(";
if (traits & DeclarationTraits::IsReadOnly) { if (traits & PropertyDeclarationTraits::IsReadOnly) {
out << "readonly"; out << "readonly";
padding = ", "; padding = ", ";
} }
if (traits & DeclarationTraits::IsPointer) { if (traits & PropertyDeclarationTraits::IsPointer) {
out << padding << "pointer"; out << padding << "pointer";
padding = ", "; padding = ", ";
} }
if (traits & DeclarationTraits::IsList) if (traits & PropertyDeclarationTraits::IsList)
out << padding << "list"; out << padding << "list";
return out << ")"; return out << ")";

View File

@@ -243,7 +243,7 @@ using TypeName = Utils::variant<NativeType, ExportedType, ExplicitExportedType>;
class Version; class Version;
class VersionNumber; class VersionNumber;
enum class TypeAccessSemantics : int; enum class TypeAccessSemantics : int;
enum class DeclarationTraits : unsigned int; enum class PropertyDeclarationTraits : unsigned int;
class PropertyDeclaration; class PropertyDeclaration;
class FunctionDeclaration; class FunctionDeclaration;
class ParameterDeclaration; class ParameterDeclaration;
@@ -261,7 +261,7 @@ std::ostream &operator<<(std::ostream &out, const ExportedType &exportedType);
std::ostream &operator<<(std::ostream &out, const NativeType &nativeType); std::ostream &operator<<(std::ostream &out, const NativeType &nativeType);
std::ostream &operator<<(std::ostream &out, const ExplicitExportedType &exportedType); std::ostream &operator<<(std::ostream &out, const ExplicitExportedType &exportedType);
std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration); std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration);
std::ostream &operator<<(std::ostream &out, DeclarationTraits traits); std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits);
std::ostream &operator<<(std::ostream &out, const FunctionDeclaration &functionDeclaration); std::ostream &operator<<(std::ostream &out, const FunctionDeclaration &functionDeclaration);
std::ostream &operator<<(std::ostream &out, const ParameterDeclaration &parameter); std::ostream &operator<<(std::ostream &out, const ParameterDeclaration &parameter);
std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration); std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration);

View File

@@ -195,8 +195,6 @@ protected:
ProjectStorageMock storage{databaseMock, true}; ProjectStorageMock storage{databaseMock, true};
ReadWriteStatement<1> &upsertTypeStatement = storage.upsertTypeStatement; ReadWriteStatement<1> &upsertTypeStatement = storage.upsertTypeStatement;
ReadStatement<1> &selectTypeIdByExportedNameStatement = storage.selectTypeIdByExportedNameStatement; ReadStatement<1> &selectTypeIdByExportedNameStatement = storage.selectTypeIdByExportedNameStatement;
ReadWriteStatement<1> &upsertPropertyDeclarationStatement = storage.upsertPropertyDeclarationStatement;
ReadStatement<1> &selectPropertyDeclarationByTypeIdAndNameStatement = storage.selectPropertyDeclarationByTypeIdAndNameStatement;
WriteStatement &upsertExportedTypesStatement = storage.upsertExportedTypesStatement; WriteStatement &upsertExportedTypesStatement = storage.upsertExportedTypesStatement;
ReadStatement<1> &selectSourceContextIdFromSourceContextsBySourceContextPathStatement ReadStatement<1> &selectSourceContextIdFromSourceContextsBySourceContextPathStatement
= storage.selectSourceContextIdFromSourceContextsBySourceContextPathStatement; = storage.selectSourceContextIdFromSourceContextsBySourceContextPathStatement;
@@ -423,7 +421,7 @@ TEST_F(ProjectStorage, FetchTypeByTypeIdCalls)
TEST_F(ProjectStorage, FetchTypesCalls) TEST_F(ProjectStorage, FetchTypesCalls)
{ {
InSequence s; InSequence s;
Storage::Type type{ImportId{}, {}, {}, {}, SourceId{}, {}, {}, {}, {}, {}, {}, TypeId{55}}; Storage::Type type{ImportId{}, {}, {}, {}, SourceId{}, {}, {}, {}, {}, {}, {}, {}, TypeId{55}};
Storage::Types types{type}; Storage::Types types{type};
EXPECT_CALL(databaseMock, deferredBegin()); EXPECT_CALL(databaseMock, deferredBegin());
@@ -481,24 +479,28 @@ protected:
{Storage::ExportedType{"Item"}}, {Storage::ExportedType{"Item"}},
{Storage::PropertyDeclaration{"data", {Storage::PropertyDeclaration{"data",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsList}, Storage::PropertyDeclarationTraits::IsList},
Storage::PropertyDeclaration{"children", Storage::PropertyDeclaration{"children",
Storage::ExportedType{"Item"}, Storage::ExportedType{"Item"},
Storage::DeclarationTraits::IsList Storage::PropertyDeclarationTraits::IsList
| Storage::DeclarationTraits::IsReadOnly}}, | Storage::PropertyDeclarationTraits::IsReadOnly}},
{Storage::FunctionDeclaration{"execute", "", {Storage::ParameterDeclaration{"arg", ""}}}, {Storage::FunctionDeclaration{"execute", "", {Storage::ParameterDeclaration{"arg", ""}}},
Storage::FunctionDeclaration{ Storage::FunctionDeclaration{
"values", "values",
"Vector3D", "Vector3D",
{Storage::ParameterDeclaration{"arg1", "int"}, {Storage::ParameterDeclaration{"arg1", "int"},
Storage::ParameterDeclaration{"arg2", "QObject", Storage::DeclarationTraits::IsPointer}, Storage::ParameterDeclaration{"arg2",
"QObject",
Storage::PropertyDeclarationTraits::IsPointer},
Storage::ParameterDeclaration{"arg3", "string"}}}}, Storage::ParameterDeclaration{"arg3", "string"}}}},
{Storage::SignalDeclaration{"execute", {Storage::ParameterDeclaration{"arg", ""}}}, {Storage::SignalDeclaration{"execute", {Storage::ParameterDeclaration{"arg", ""}}},
Storage::SignalDeclaration{"values", Storage::SignalDeclaration{
{Storage::ParameterDeclaration{"arg1", "int"}, "values",
Storage::ParameterDeclaration{ {Storage::ParameterDeclaration{"arg1", "int"},
"arg2", "QObject", Storage::DeclarationTraits::IsPointer}, Storage::ParameterDeclaration{"arg2",
Storage::ParameterDeclaration{"arg3", "string"}}}}, "QObject",
Storage::PropertyDeclarationTraits::IsPointer},
Storage::ParameterDeclaration{"arg3", "string"}}}},
{Storage::EnumerationDeclaration{"Enum", {Storage::EnumerationDeclaration{"Enum",
{Storage::EnumeratorDeclaration{"Foo"}, {Storage::EnumeratorDeclaration{"Foo"},
Storage::EnumeratorDeclaration{"Bar", 32}}}, Storage::EnumeratorDeclaration{"Bar", 32}}},
@@ -514,6 +516,34 @@ protected:
{Storage::ExportedType{"Object"}, Storage::ExportedType{"Obj"}}}}; {Storage::ExportedType{"Object"}, Storage::ExportedType{"Obj"}}}};
} }
auto createTypesWithAliases()
{
auto types = createTypes();
types[1].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
types.push_back(Storage::Type{importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1,
importIds,
{Storage::ExportedType{"AliasItem"}}});
types.back().propertyDeclarations.push_back(
Storage::PropertyDeclaration{"data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
types.back().aliasDeclarations.push_back(
Storage::AliasPropertyDeclaration{"items", Storage::NativeType{"QQuickItem"}, "children"});
types.back().aliasDeclarations.push_back(
Storage::AliasPropertyDeclaration{"objects", Storage::NativeType{"QQuickItem"}, "objects"});
return types;
}
auto createImports() auto createImports()
{ {
importSourceId1 = sourcePathCache.sourceId(importPath1); importSourceId1 = sourcePathCache.sourceId(importPath1);
@@ -1089,21 +1119,22 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddPropertyDeclarations)
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsList), Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("children", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, TEST_F(ProjectStorageSlowTest,
@@ -1141,21 +1172,22 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddPropertyDeclarationExplicitTyp
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QQuickObject"}, Storage::NativeType{"QQuickObject"},
Storage::DeclarationTraits::IsList), Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("children", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesPropertyDeclarationType) TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesPropertyDeclarationType)
@@ -1167,74 +1199,77 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesPropertyDeclarationType)
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QQuickItem"}, Storage::NativeType{"QQuickItem"},
Storage::DeclarationTraits::IsList), Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("children", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesDeclarationTraits) TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesDeclarationTraits)
{ {
Storage::Types types{createTypes()}; Storage::Types types{createTypes()};
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
types[0].propertyDeclarations[0].traits = Storage::DeclarationTraits::IsPointer; types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsPointer), Storage::PropertyDeclarationTraits::IsPointer),
IsPropertyDeclaration("children", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesDeclarationTraitsAndType) TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesDeclarationTraitsAndType)
{ {
Storage::Types types{createTypes()}; Storage::Types types{createTypes()};
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
types[0].propertyDeclarations[0].traits = Storage::DeclarationTraits::IsPointer; types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
types[0].propertyDeclarations[0].typeName = Storage::NativeType{"QQuickItem"}; types[0].propertyDeclarations[0].typeName = Storage::NativeType{"QQuickItem"};
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QQuickItem"}, Storage::NativeType{"QQuickItem"},
Storage::DeclarationTraits::IsPointer), Storage::PropertyDeclarationTraits::IsPointer),
IsPropertyDeclaration("children", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesRemovesAPropertyDeclaration) TEST_F(ProjectStorageSlowTest, SynchronizeTypesRemovesAPropertyDeclaration)
@@ -1252,10 +1287,10 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesRemovesAPropertyDeclaration)
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(IsPropertyDeclaration(
IsPropertyDeclaration("data", "data",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsList)))))); Storage::PropertyDeclarationTraits::IsList))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsAPropertyDeclaration) TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsAPropertyDeclaration)
@@ -1265,29 +1300,30 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsAPropertyDeclaration)
types[0].propertyDeclarations.push_back( types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"object", Storage::PropertyDeclaration{"object",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsPointer}); Storage::PropertyDeclarationTraits::IsPointer});
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(
Contains(AllOf( storage.fetchTypes(),
IsStorageType(importId2, Contains(AllOf(
"QQuickItem", IsStorageType(importId2,
Storage::NativeType{"QObject"}, "QQuickItem",
TypeAccessSemantics::Reference, Storage::NativeType{"QObject"},
sourceId1), TypeAccessSemantics::Reference,
Field(&Storage::Type::propertyDeclarations, sourceId1),
UnorderedElementsAre( Field(&Storage::Type::propertyDeclarations,
IsPropertyDeclaration("object", UnorderedElementsAre(
Storage::NativeType{"QObject"}, IsPropertyDeclaration("object",
Storage::DeclarationTraits::IsPointer), Storage::NativeType{"QObject"},
IsPropertyDeclaration("data", Storage::PropertyDeclarationTraits::IsPointer),
Storage::NativeType{"QObject"}, IsPropertyDeclaration("data",
Storage::DeclarationTraits::IsList), Storage::NativeType{"QObject"},
IsPropertyDeclaration("children", Storage::PropertyDeclarationTraits::IsList),
Storage::NativeType{"QQuickItem"}, IsPropertyDeclaration("children",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesRenameAPropertyDeclaration) TEST_F(ProjectStorageSlowTest, SynchronizeTypesRenameAPropertyDeclaration)
@@ -1299,21 +1335,22 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesRenameAPropertyDeclaration)
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(), ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf( Contains(
IsStorageType(importId2, AllOf(IsStorageType(importId2,
"QQuickItem", "QQuickItem",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
TypeAccessSemantics::Reference, TypeAccessSemantics::Reference,
sourceId1), sourceId1),
Field(&Storage::Type::propertyDeclarations, Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre( UnorderedElementsAre(
IsPropertyDeclaration("data", IsPropertyDeclaration("data",
Storage::NativeType{"QObject"}, Storage::NativeType{"QObject"},
Storage::DeclarationTraits::IsList), Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("objects", IsPropertyDeclaration(
Storage::NativeType{"QQuickItem"}, "objects",
Storage::DeclarationTraits::IsList Storage::NativeType{"QQuickItem"},
| Storage::DeclarationTraits::IsReadOnly)))))); Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
} }
TEST_F(ProjectStorageSlowTest, UsingNonExistingNativePropertyTypeThrows) TEST_F(ProjectStorageSlowTest, UsingNonExistingNativePropertyTypeThrows)
@@ -1502,7 +1539,7 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesFunctionDeclarationChangeP
{ {
Storage::Types types{createTypes()}; Storage::Types types{createTypes()};
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
types[0].functionDeclarations[1].parameters[0].traits = QmlDesigner::Storage::DeclarationTraits::IsList; types[0].functionDeclarations[1].parameters[0].traits = QmlDesigner::Storage::PropertyDeclarationTraits::IsList;
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
@@ -1672,7 +1709,7 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangesSignalDeclarationChangePar
{ {
Storage::Types types{createTypes()}; Storage::Types types{createTypes()};
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
types[0].signalDeclarations[1].parameters[0].traits = QmlDesigner::Storage::DeclarationTraits::IsList; types[0].signalDeclarations[1].parameters[0].traits = QmlDesigner::Storage::PropertyDeclarationTraits::IsList;
storage.synchronizeTypes(types, {}); storage.synchronizeTypes(types, {});
@@ -2290,4 +2327,242 @@ TEST_F(ProjectStorageSlowTest, FetchImportDepencencyIdsForRootDepencency)
ASSERT_THAT(importIds, ElementsAre(importId1)); ASSERT_THAT(importIds, ElementsAre(importId1));
} }
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddAliasDeclarations)
{
Storage::Types types{createTypesWithAliases()};
storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddAliasDeclarationsAgain)
{
Storage::Types types{createTypesWithAliases()};
storage.synchronizeTypes(types, {});
storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesRemoveAliasDeclarations)
{
Storage::Types types{createTypesWithAliases()};
storage.synchronizeTypes(types, {});
types[2].aliasDeclarations.pop_back();
storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddAliasDeclarationsThrowsForWrongTypeName)
{
Storage::Types types{createTypesWithAliases()};
types[2].aliasDeclarations[0].aliasTypeName = Storage::NativeType{"QQuickItemWrong"};
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddAliasDeclarationsThrowsForWrongPropertyName)
{
Storage::Types types{createTypesWithAliases()};
types[2].aliasDeclarations[0].aliasPropertyName = "childrenWrong";
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::PropertyNameDoesNotExists);
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangeAliasDeclarationsTypeName)
{
Storage::Types types{createTypesWithAliases()};
types.push_back(Storage::Type{importId1,
"QObject2",
Storage::NativeType{},
TypeAccessSemantics::Reference,
sourceId2,
importIds,
{Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
types[3].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
storage.synchronizeTypes(types, {});
types[2].aliasDeclarations[1].aliasTypeName = Storage::ExportedType{"Obj2"};
storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QObject2"},
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangeAliasDeclarationsPropertyName)
{
Storage::Types types{createTypesWithAliases()};
storage.synchronizeTypes(types, {});
types[2].aliasDeclarations[1].aliasPropertyName = "children";
storage.synchronizeTypes(types, {});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
AllOf(IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangeAliasDeclarationsToPropertyDeclaration)
{
Storage::Types types{createTypesWithAliases()};
storage.synchronizeTypes(types, {});
types[2].aliasDeclarations.pop_back();
types[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
storage.synchronizeTypes(types, {});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
AllOf(IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorageSlowTest, SynchronizeTypesChangePropertyDeclarationsToAliasDeclaration)
{
Storage::Types types{createTypesWithAliases()};
auto typesChanged = types;
typesChanged[2].aliasDeclarations.pop_back();
typesChanged[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
storage.synchronizeTypes(typesChanged, {});
storage.synchronizeTypes(types, {});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
IsStorageType(importId2,
"QAliasItem",
Storage::NativeType{"QQuickItem"},
TypeAccessSemantics::Reference,
sourceId1),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
Storage::NativeType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
Storage::NativeType{"QObject"},
Storage::PropertyDeclarationTraits::IsList))))));
}
} // namespace } // namespace