QmlDesigner: Support user defined list properties

Item{
    property list<Foo> foos
}

It is now a property of type Foo and a list trait.

Task-number: QDS-7121
Change-Id: Ic230b531c3264da6f5794f7523ebbd1a101a511a
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2022-06-08 16:58:15 +02:00
parent f888ec127e
commit b5a766b483
2 changed files with 103 additions and 9 deletions

View File

@@ -144,9 +144,6 @@ void addImports(Storage::Imports &imports,
Storage::ImportedTypeName createImportedTypeName(const QStringView rawtypeName,
const QualifiedImports &qualifiedImports)
{
if (!rawtypeName.contains('.'))
return Storage::ImportedType{Utils::SmallString{rawtypeName}};
auto foundDot = std::find(rawtypeName.begin(), rawtypeName.end(), '.');
QStringView alias(rawtypeName.begin(), foundDot);
@@ -161,6 +158,42 @@ Storage::ImportedTypeName createImportedTypeName(const QStringView rawtypeName,
foundImport->second};
}
bool isListProperty(const QStringView rawtypeName)
{
return rawtypeName.startsWith(u"list<") && rawtypeName.endsWith(u'>');
}
struct TypeNameViewAndTraits
{
QStringView typeName;
Storage::PropertyDeclarationTraits traits;
};
TypeNameViewAndTraits filteredListTypeName(const QStringView rawtypeName)
{
if (!isListProperty(rawtypeName))
return {rawtypeName, Storage::PropertyDeclarationTraits::None};
return {rawtypeName.mid(5, rawtypeName.size() - 6), Storage::PropertyDeclarationTraits::IsList};
};
struct TypeNameAndTraits
{
Storage::ImportedTypeName importedTypeName;
Storage::PropertyDeclarationTraits traits;
};
TypeNameAndTraits createImportedTypeNameAndTypeTraits(const QStringView rawtypeName,
const QualifiedImports &qualifiedImports)
{
auto [filteredTypeName, traits] = filteredListTypeName(rawtypeName);
if (!filteredTypeName.contains('.'))
return {Storage::ImportedType{Utils::SmallString{filteredTypeName}}, traits};
return {createImportedTypeName(filteredTypeName, qualifiedImports), traits};
}
std::pair<Utils::SmallString, Utils::SmallString> createAccessPaths(const QStringList &accessPath)
{
if (accessPath.size() == 1)
@@ -190,18 +223,21 @@ void addPropertyDeclarations(Storage::Type &type,
auto [aliasPropertyName, aliasPropertyNameTail] = createAccessPaths(
resolvedAlias.accessedPath);
auto [importedTypeName, traits] = createImportedTypeNameAndTypeTraits(
resolvedAlias.typeName, qualifiedImports);
type.propertyDeclarations.emplace_back(Utils::SmallString{propertyDeclaration.name},
createImportedTypeName(resolvedAlias.typeName,
qualifiedImports),
Storage::PropertyDeclarationTraits::None,
std::move(importedTypeName),
traits,
aliasPropertyName,
aliasPropertyNameTail);
}
} else {
auto [importedTypeName, traits] = createImportedTypeNameAndTypeTraits(
propertyDeclaration.typeName, qualifiedImports);
type.propertyDeclarations.emplace_back(Utils::SmallString{propertyDeclaration.name},
createImportedTypeName(propertyDeclaration.typeName,
qualifiedImports),
Storage::PropertyDeclarationTraits::None);
std::move(importedTypeName),
traits);
}
}
}

View File

@@ -474,4 +474,62 @@ TEST_F(QmlDocumentParser, InvalidAliasPropertiesAreSkipped)
ASSERT_THAT(type.propertyDeclarations, IsEmpty());
}
TEST_F(QmlDocumentParser, ListProperty)
{
auto type = parser.parse(R"(Item{
property list<Foo> foos
})",
imports,
qmlFileSourceId,
directoryPath);
ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("foos",
Storage::ImportedType{"Foo"},
Storage::PropertyDeclarationTraits::IsList)));
}
TEST_F(QmlDocumentParser, AliasOnListProperty)
{
auto type = parser.parse(R"(Item{
property alias foos: foo.foos
Item {
id: foo
property list<Foo> foos
}
})",
imports,
qmlFileSourceId,
directoryPath);
ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("foos",
Storage::ImportedType{"Foo"},
Storage::PropertyDeclarationTraits::IsList)));
}
TEST_F(QmlDocumentParser, QualifiedListProperty)
{
auto exampleModuleId = storage.moduleId("Example");
auto type = parser.parse(R"(import Example 2.1 as Example
Item{
property list<Example.Foo> foos
})",
imports,
qmlFileSourceId,
directoryPath);
ASSERT_THAT(type.propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration(
"foos",
Storage::QualifiedImportedType{"Foo",
Storage::Import{exampleModuleId,
Storage::Version{2, 1},
qmlFileSourceId}},
Storage::PropertyDeclarationTraits::IsList)));
}
} // namespace