diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp index 7b3b091f636..d5641d75d40 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp @@ -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 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); } } } diff --git a/tests/unit/unittest/qmldocumentparser-test.cpp b/tests/unit/unittest/qmldocumentparser-test.cpp index 5a1992ebb6c..40147a38c9a 100644 --- a/tests/unit/unittest/qmldocumentparser-test.cpp +++ b/tests/unit/unittest/qmldocumentparser-test.cpp @@ -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 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 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 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