aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2022-02-10 16:48:13 +0100
committerMarco Bubke <marco.bubke@qt.io>2022-02-15 17:18:40 +0000
commit6e9cb8ad544c1468d7f8bdea1a8562a77749b767 (patch)
treea783f734f8c74b7803be1d589d820c0c1d2a2a4a
parent59d9a2dcdc07e43a8ebda0c0b67a9f0fd41b6394 (diff)
QmlDesigner: Support qualified prototypes in the qml document parser
Task-number: QDS-6191 Change-Id: I459d09df4ed0ba901fd4f214dd3de81556ee7896 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp84
-rw-r--r--tests/unit/unittest/qmldocumentparser-test.cpp14
2 files changed, 78 insertions, 20 deletions
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp
index 81b01ddaba..8d0c904879 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp
@@ -41,6 +41,8 @@ namespace QmlDom = QQmlJS::Dom;
namespace {
+using QualifiedImports = std::map<QString, Storage::Import>;
+
int convertVersionNumber(qint32 versionNumber)
{
return versionNumber < 0 ? -1 : versionNumber;
@@ -64,24 +66,49 @@ Utils::PathString convertUri(const QString &uri)
return Utils::PathString{x.generic_string()};
}
+Storage::Import createImport(const QmlDom::Import &qmlImport,
+ SourceId sourceId,
+ Utils::SmallStringView directoryPath,
+ QmlDocumentParser::ProjectStorage &storage)
+{
+ if (qmlImport.uri == u"file://.") {
+ auto moduleId = storage.moduleId(directoryPath);
+ return Storage::Import(moduleId, Storage::Version{}, sourceId);
+ }
+
+ if (qmlImport.uri.startsWith(u"file://")) {
+ auto moduleId = storage.moduleId(convertUri(qmlImport.uri));
+ return Storage::Import(moduleId, Storage::Version{}, sourceId);
+ }
+
+ auto moduleId = storage.moduleId(Utils::SmallString{qmlImport.uri});
+ return Storage::Import(moduleId, convertVersion(qmlImport.version), sourceId);
+}
+
+QualifiedImports filterQualifiedImports(const QList<QmlDom::Import> &qmlImports,
+ SourceId sourceId,
+ Utils::SmallStringView directoryPath,
+ QmlDocumentParser::ProjectStorage &storage)
+{
+ QualifiedImports qualifiedImports;
+
+ for (const QmlDom::Import &qmlImport : qmlImports) {
+ if (!qmlImport.importId.isEmpty())
+ qualifiedImports.try_emplace(qmlImport.importId,
+ createImport(qmlImport, sourceId, directoryPath, storage));
+ }
+
+ return qualifiedImports;
+}
+
void addImports(Storage::Imports &imports,
const QList<QmlDom::Import> &qmlImports,
SourceId sourceId,
Utils::SmallStringView directoryPath,
QmlDocumentParser::ProjectStorage &storage)
{
- for (const QmlDom::Import &qmlImport : qmlImports) {
- if (qmlImport.uri == u"file://.") {
- auto moduleId = storage.moduleId(directoryPath);
- imports.emplace_back(moduleId, Storage::Version{}, sourceId);
- } else if (qmlImport.uri.startsWith(u"file://")) {
- auto moduleId = storage.moduleId(convertUri(qmlImport.uri));
- imports.emplace_back(moduleId, Storage::Version{}, sourceId);
- } else {
- auto moduleId = storage.moduleId(Utils::SmallString{qmlImport.uri});
- imports.emplace_back(moduleId, convertVersion(qmlImport.version), sourceId);
- }
- }
+ for (const QmlDom::Import &qmlImport : qmlImports)
+ imports.push_back(createImport(qmlImport, sourceId, directoryPath, storage));
auto end = imports.end();
auto begin = std::prev(end, qmlImports.size());
@@ -90,6 +117,30 @@ void addImports(Storage::Imports &imports,
imports.erase(std::unique(begin, end), end);
}
+Storage::ImportedTypeName createImportedTypeName(const QStringView rawtypeName,
+ const QList<QmlDom::Import> &qmlImports,
+ SourceId sourceId,
+ Utils::SmallStringView directoryPath,
+ QmlDocumentParser::ProjectStorage &storage)
+{
+ if (!rawtypeName.contains('.')) {
+ return Storage::ImportedType{Utils::SmallString{rawtypeName}};
+ }
+
+ auto qualifiedImports = filterQualifiedImports(qmlImports, sourceId, directoryPath, storage);
+
+ auto foundDot = std::find(rawtypeName.begin(), rawtypeName.end(), '.');
+
+ QStringView alias(rawtypeName.begin(), foundDot);
+
+ auto foundImport = qualifiedImports.find(alias.toString());
+
+ QStringView typeName(std::next(foundDot), rawtypeName.end());
+
+ return Storage::QualifiedImportedType{Utils::SmallString{typeName.toString()},
+ foundImport->second};
+}
+
void addPropertyDeclarations(Storage::Type &type, const QmlDom::QmlObject &rootObject)
{
for (const QmlDom::PropertyDefinition &propertyDeclaration : rootObject.propertyDefs()) {
@@ -188,10 +239,15 @@ Storage::Type QmlDocumentParser::parse(const QString &sourceContent,
const QmlDom::QmlObject &qmlObject = objects.front();
- type.prototype = Storage::ImportedType{Utils::SmallString{qmlObject.name()}};
-
+ const auto qmlImports = qmlFile->imports();
auto directoryPath{m_pathCache.sourceContextPath(m_pathCache.sourceContextId(sourceId))};
+ type.prototype = createImportedTypeName(qmlObject.name(),
+ qmlImports,
+ sourceId,
+ directoryPath,
+ m_storage);
+
addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage);
addPropertyDeclarations(type, qmlObject);
diff --git a/tests/unit/unittest/qmldocumentparser-test.cpp b/tests/unit/unittest/qmldocumentparser-test.cpp
index ecf6897535..5e7312a45f 100644
--- a/tests/unit/unittest/qmldocumentparser-test.cpp
+++ b/tests/unit/unittest/qmldocumentparser-test.cpp
@@ -143,17 +143,19 @@ TEST_F(QmlDocumentParser, Prototype)
ASSERT_THAT(type, HasPrototype(Storage::ImportedType("Example")));
}
-TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype)
+TEST_F(QmlDocumentParser, QualifiedPrototype)
{
auto exampleModuleId = storage.moduleId("Example");
- QString text = R"(import Example as Example
-
- Example.Item{})";
+ QString text = R"(import Example 2.1 as Example
+ Example.Item{})";
+
auto type = parser.parse(text, imports, qmlFileSourceId);
ASSERT_THAT(type,
- HasPrototype(Storage::QualifiedImportedType(
- "Item", Storage::Import{exampleModuleId, Storage::Version{}, qmlFileSourceId})));
+ HasPrototype(Storage::QualifiedImportedType("Item",
+ Storage::Import{exampleModuleId,
+ Storage::Version{2, 1},
+ qmlFileSourceId})));
}
TEST_F(QmlDocumentParser, Properties)