QmlDesigner: Support enumeration aliases in qmltypes

Task-number: QDS-6768
Change-Id: I93de3c336cf1dacd0789526945929d10011a9132
Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
Marco Bubke
2022-04-19 16:44:28 +02:00
parent 697fd3ac5c
commit d4eb0aff56
2 changed files with 146 additions and 15 deletions

View File

@@ -140,18 +140,32 @@ Storage::ExportedTypes createExports(const QList<QQmlJSScope::Export> &qmlExport
return exportedTypes; return exportedTypes;
} }
Storage::ExportedTypes createCppEnumerationExports(Utils::SmallStringView interanalName, Utils::SmallString createCppEnumerationExport(Utils::SmallStringView typeName,
Utils::SmallStringView enumerationName)
{
Utils::SmallString cppExportedTypeName{typeName};
cppExportedTypeName += "::";
cppExportedTypeName += enumerationName;
return cppExportedTypeName;
}
Storage::ExportedTypes createCppEnumerationExports(Utils::SmallStringView typeName,
ModuleId cppModuleId, ModuleId cppModuleId,
Utils::SmallStringView enumeration) Utils::SmallStringView enumerationName,
Utils::SmallStringView enumerationAlias)
{ {
Storage::ExportedTypes exportedTypes; Storage::ExportedTypes exportedTypes;
exportedTypes.reserve(1);
Utils::SmallString cppExportedTypeName{interanalName}; if (!enumerationAlias.empty()) {
cppExportedTypeName += "::"; exportedTypes.reserve(2);
cppExportedTypeName += enumeration; exportedTypes.emplace_back(cppModuleId,
createCppEnumerationExport(typeName, enumerationAlias));
} else {
exportedTypes.reserve(1);
}
exportedTypes.emplace_back(cppModuleId, cppExportedTypeName); exportedTypes.emplace_back(cppModuleId, createCppEnumerationExport(typeName, enumerationName));
return exportedTypes; return exportedTypes;
} }
@@ -317,6 +331,38 @@ Storage::EnumerationDeclarations createEnumeration(const QHash<QString, QQmlJSMe
return enumerationDeclarations; return enumerationDeclarations;
} }
void addEnumerationType(EnumerationTypes &enumerationTypes,
Storage::Types &types,
Utils::SmallStringView typeName,
Utils::SmallStringView enumerationName,
SourceId sourceId,
ModuleId cppModuleId,
Utils::SmallStringView enumerationAlias)
{
auto fullTypeName = Utils::SmallString::join({typeName, "::", enumerationName});
types.emplace_back(fullTypeName,
Storage::ImportedType{Utils::SmallString{}},
Storage::TypeAccessSemantics::Value | Storage::TypeAccessSemantics::IsEnum,
sourceId,
createCppEnumerationExports(typeName,
cppModuleId,
enumerationName,
enumerationAlias));
enumerationTypes.emplace_back(enumerationName, std::move(fullTypeName));
}
QSet<QString> createEnumerationAliases(const QHash<QString, QQmlJSMetaEnum> &qmlEnumerations)
{
QSet<QString> aliases;
for (const QQmlJSMetaEnum &qmlEnumeration : qmlEnumerations) {
if (auto &&alias = qmlEnumeration.alias(); !alias.isEmpty())
aliases.insert(alias);
}
return aliases;
}
EnumerationTypes addEnumerationTypes(Storage::Types &types, EnumerationTypes addEnumerationTypes(Storage::Types &types,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
SourceId sourceId, SourceId sourceId,
@@ -326,15 +372,21 @@ EnumerationTypes addEnumerationTypes(Storage::Types &types,
EnumerationTypes enumerationTypes; EnumerationTypes enumerationTypes;
enumerationTypes.reserve(Utils::usize(qmlEnumerations)); enumerationTypes.reserve(Utils::usize(qmlEnumerations));
QSet<QString> aliases = createEnumerationAliases(qmlEnumerations);
for (const QQmlJSMetaEnum &qmlEnumeration : qmlEnumerations) { for (const QQmlJSMetaEnum &qmlEnumeration : qmlEnumerations) {
if (aliases.contains(qmlEnumeration.name()))
continue;
Utils::SmallString enumerationName{qmlEnumeration.name()}; Utils::SmallString enumerationName{qmlEnumeration.name()};
auto fullTypeName = Utils::SmallString::join({typeName, "::", enumerationName}); Utils::SmallString enumerationAlias{qmlEnumeration.alias()};
types.emplace_back(fullTypeName, addEnumerationType(enumerationTypes,
Storage::ImportedType{Utils::SmallString{}}, types,
Storage::TypeAccessSemantics::Value | Storage::TypeAccessSemantics::IsEnum, typeName,
enumerationName,
sourceId, sourceId,
createCppEnumerationExports(typeName, cppModuleId, enumerationName)); cppModuleId,
enumerationTypes.emplace_back(enumerationName, std::move(fullTypeName)); enumerationAlias);
} }
return enumerationTypes; return enumerationTypes;

View File

@@ -481,8 +481,6 @@ TEST_F(QmlTypesParser, Enumerations)
TEST_F(QmlTypesParser, EnumerationIsExportedAsType) TEST_F(QmlTypesParser, EnumerationIsExportedAsType)
{ {
ModuleId qmlModuleId = storage.moduleId("QML");
ModuleId qtQmlModuleId = storage.moduleId("QtQml");
QString source{R"(import QtQuick.tooling 1.2 QString source{R"(import QtQuick.tooling 1.2
Module{ Module{
Component { name: "QObject" Component { name: "QObject"
@@ -526,6 +524,87 @@ TEST_F(QmlTypesParser, EnumerationIsExportedAsType)
_)); _));
} }
TEST_F(QmlTypesParser, EnumerationIsExportedAsTypeWithAlias)
{
QString source{R"(import QtQuick.tooling 1.2
Module{
Component { name: "QObject"
Enum {
name: "NamedColorSpaces"
alias: "NamedColorSpace"
values: [
"Unknown",
"SRgb",
"AdobeRgb",
"DisplayP3",
]
}
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"};
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
UnorderedElementsAre(
AllOf(IsType("QObject::NamedColorSpaces",
Storage::ImportedType{},
Storage::TypeAccessSemantics::Value | Storage::TypeAccessSemantics::IsEnum,
qmltypesFileSourceId),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qtQmlNativeModuleId,
"QObject::NamedColorSpace",
Storage::Version{}),
IsExportedType(qtQmlNativeModuleId,
"QObject::NamedColorSpaces",
Storage::Version{})))),
_));
}
TEST_F(QmlTypesParser, EnumerationIsExportedAsTypeWithAliasToo)
{
QString source{R"(import QtQuick.tooling 1.2
Module{
Component { name: "QObject"
Enum {
name: "NamedColorSpaces"
alias: "NamedColorSpace"
values: [
"Unknown",
"SRgb",
"AdobeRgb",
"DisplayP3",
]
}
Enum {
name: "NamedColorSpace"
values: [
"Unknown",
"SRgb",
"AdobeRgb",
"DisplayP3",
]
}
exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
}})"};
parser.parse(source, imports, types, projectData);
ASSERT_THAT(types,
UnorderedElementsAre(
AllOf(IsType("QObject::NamedColorSpaces",
Storage::ImportedType{},
Storage::TypeAccessSemantics::Value | Storage::TypeAccessSemantics::IsEnum,
qmltypesFileSourceId),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qtQmlNativeModuleId,
"QObject::NamedColorSpace",
Storage::Version{}),
IsExportedType(qtQmlNativeModuleId,
"QObject::NamedColorSpaces",
Storage::Version{})))),
_));
}
TEST_F(QmlTypesParser, EnumerationIsReferencedByQualifiedName) TEST_F(QmlTypesParser, EnumerationIsReferencedByQualifiedName)
{ {
QString source{R"(import QtQuick.tooling 1.2 QString source{R"(import QtQuick.tooling 1.2