QmlDesigner: Add ProjectStorage::propertyDeclarationId

The properties has to respect overloading. So it should chose the
nearest property declaration with the requested name.

Task-number: QDS-7280
Change-Id: I13ff9cf1f9389ec6b48c6e692368ef33795b61fe
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
2022-07-13 13:40:26 +02:00
parent d842862944
commit dac7cca02b
2 changed files with 90 additions and 20 deletions

View File

@@ -151,18 +151,24 @@ public:
.template valueWithTransaction<TypeId>(&moduleId, exportedTypeName); .template valueWithTransaction<TypeId>(&moduleId, exportedTypeName);
} }
PropertyDeclarationIds propertyIds(TypeId typeId) const PropertyDeclarationIds propertyDeclarationIds(TypeId typeId) const
{ {
return selectPropertyDeclarationIdsForTypeStatement return selectPropertyDeclarationIdsForTypeStatement
.template valuesWithTransaction<PropertyDeclarationId>(32, &typeId); .template valuesWithTransaction<PropertyDeclarationId>(32, &typeId);
} }
PropertyDeclarationIds localPropertyIds(TypeId typeId) const PropertyDeclarationIds localPropertyDeclarationIds(TypeId typeId) const
{ {
return selectLocalPropertyDeclarationIdsForTypeStatement return selectLocalPropertyDeclarationIdsForTypeStatement
.template valuesWithTransaction<PropertyDeclarationId>(16, &typeId); .template valuesWithTransaction<PropertyDeclarationId>(16, &typeId);
} }
PropertyDeclarationId propertyDeclarationId(TypeId typeId, Utils::SmallStringView propertyName) const
{
return selectPropertyDeclarationIdForTypeAndPropertyNameStatement
.template valueWithTransaction<PropertyDeclarationId>(&typeId, propertyName);
}
Utils::optional<Utils::SmallString> propertyName(PropertyDeclarationId propertyDeclarationId) const Utils::optional<Utils::SmallString> propertyName(PropertyDeclarationId propertyDeclarationId) const
{ {
return selectPropertyNameStatement.template optionalValueWithTransaction<Utils::SmallString>( return selectPropertyNameStatement.template optionalValueWithTransaction<Utils::SmallString>(
@@ -2898,6 +2904,16 @@ public:
"WHERE typeId=? " "WHERE typeId=? "
"ORDER BY propertyDeclarationId", "ORDER BY propertyDeclarationId",
database}; database};
mutable ReadStatement<1, 2> selectPropertyDeclarationIdForTypeAndPropertyNameStatement{
"WITH RECURSIVE "
" typeChain(typeId, level) AS ("
" VALUES(?1, 0)"
" UNION ALL "
" SELECT prototypeId, typeChain.level + 1 FROM types JOIN typeChain "
" USING(typeId) WHERE prototypeId IS NOT NULL)"
"SELECT propertyDeclarationId FROM typeChain JOIN propertyDeclarations "
" USING(typeId) WHERE name=?2 ORDER BY level LIMIT 1",
database};
}; };
extern template class ProjectStorage<Sqlite::Database>; extern template class ProjectStorage<Sqlite::Database>;
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -5555,13 +5555,13 @@ TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionForWrongMajorVersion)
ASSERT_FALSE(typeId); ASSERT_FALSE(typeId);
} }
TEST_F(ProjectStorage, GetProperties) TEST_F(ProjectStorage, GetPropertyDeclarationIds)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "QObject3"); auto typeId = fetchTypeId(sourceId1, "QObject3");
auto propertyIds = storage.propertyIds(itemTypeId); auto propertyIds = storage.propertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, ASSERT_THAT(propertyIds,
UnorderedElementsAre(HasName("data"), UnorderedElementsAre(HasName("data"),
@@ -5572,24 +5572,24 @@ TEST_F(ProjectStorage, GetProperties)
HasName("children3"))); HasName("children3")));
} }
TEST_F(ProjectStorage, GetPropertiesAreReturnedSorted) TEST_F(ProjectStorage, GetPropertyDeclarationIdsAreReturnedSorted)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "QObject3"); auto typeId = fetchTypeId(sourceId1, "QObject3");
auto propertyIds = storage.propertyIds(itemTypeId); auto propertyIds = storage.propertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, IsSorted()); ASSERT_THAT(propertyIds, IsSorted());
} }
TEST_F(ProjectStorage, GetNoPropertiesPropertiesFromDerivedTypes) TEST_F(ProjectStorage, GetNoPropertyDeclarationIdsPropertiesFromDerivedTypes)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "QObject2"); auto typeId = fetchTypeId(sourceId1, "QObject2");
auto propertyIds = storage.propertyIds(itemTypeId); auto propertyIds = storage.propertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, ASSERT_THAT(propertyIds,
UnorderedElementsAre(HasName("data"), UnorderedElementsAre(HasName("data"),
@@ -5598,37 +5598,91 @@ TEST_F(ProjectStorage, GetNoPropertiesPropertiesFromDerivedTypes)
HasName("children2"))); HasName("children2")));
} }
TEST_F(ProjectStorage, GetNoPropertiesForWrongTypeId) TEST_F(ProjectStorage, GetNoPropertyDeclarationIdsForWrongTypeId)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "WrongObject"); auto typeId = fetchTypeId(sourceId1, "WrongObject");
auto propertyIds = storage.propertyIds(itemTypeId); auto propertyIds = storage.propertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, IsEmpty()); ASSERT_THAT(propertyIds, IsEmpty());
} }
TEST_F(ProjectStorage, GetLocalProperties) TEST_F(ProjectStorage, GetLocalPropertyDeclarationIds)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "QObject2"); auto typeId = fetchTypeId(sourceId1, "QObject2");
auto propertyIds = storage.localPropertyIds(itemTypeId); auto propertyIds = storage.localPropertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, UnorderedElementsAre(HasName("data2"), HasName("children2"))); ASSERT_THAT(propertyIds, UnorderedElementsAre(HasName("data2"), HasName("children2")));
} }
TEST_F(ProjectStorage, GetLocalPropertiesAreReturnedSorted) TEST_F(ProjectStorage, GetLocalPropertyDeclarationIdsAreReturnedSorted)
{ {
auto package{createPackageWithProperties()}; auto package{createPackageWithProperties()};
storage.synchronize(package); storage.synchronize(package);
auto itemTypeId = fetchTypeId(sourceId1, "QObject2"); auto typeId = fetchTypeId(sourceId1, "QObject2");
auto propertyIds = storage.localPropertyIds(itemTypeId); auto propertyIds = storage.localPropertyDeclarationIds(typeId);
ASSERT_THAT(propertyIds, IsSorted()); ASSERT_THAT(propertyIds, IsSorted());
} }
TEST_F(ProjectStorage, GetPropertyDeclarationId)
{
auto package{createPackageWithProperties()};
storage.synchronize(package);
auto typeId = fetchTypeId(sourceId1, "QObject3");
auto propertyId = storage.propertyDeclarationId(typeId, "data");
ASSERT_THAT(propertyId, HasName("data"));
}
TEST_F(ProjectStorage, GetLatestPropertyDeclarationId)
{
auto package{createPackageWithProperties()};
storage.synchronize(package);
auto typeId = fetchTypeId(sourceId1, "QObject3");
auto oldPropertyId = storage.propertyDeclarationId(typeId, "data");
auto found = std::find_if(package.types.begin(), package.types.end(), [](const auto &type) {
return type.typeName == "QObject3";
});
found->propertyDeclarations.push_back(Storage::Synchronization::PropertyDeclaration{
"data",
Storage::Synchronization::ImportedType{"Object"},
Storage::Synchronization::PropertyDeclarationTraits::IsList});
storage.synchronize(package);
auto propertyId = storage.propertyDeclarationId(typeId, "data");
ASSERT_THAT(propertyId, AllOf(Not(oldPropertyId), HasName("data")));
ASSERT_THAT(oldPropertyId, HasName("data"));
}
TEST_F(ProjectStorage, GetInvalidPropertyDeclarationIdForInvalidTypeId)
{
auto package{createPackageWithProperties()};
storage.synchronize(package);
auto typeId = fetchTypeId(sourceId1, "WrongObject");
auto propertyId = storage.propertyDeclarationId(typeId, "data");
ASSERT_FALSE(propertyId);
}
TEST_F(ProjectStorage, GetInvalidPropertyDeclarationIdForWrongPropertyName)
{
auto package{createPackageWithProperties()};
storage.synchronize(package);
auto typeId = fetchTypeId(sourceId1, "Object3");
auto propertyId = storage.propertyDeclarationId(typeId, "wrongName");
ASSERT_FALSE(propertyId);
}
} // namespace } // namespace