aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlcompiler/qqmljsimporter.cpp51
-rw-r--r--src/qmlcompiler/qqmljsimporter_p.h4
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader.cpp5
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader_p.h4
-rw-r--r--src/qmldom/qqmldomtypesreader.cpp2
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt2
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/multiforeign.h51
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/multiforeign.qml10
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp11
9 files changed, 115 insertions, 25 deletions
diff --git a/src/qmlcompiler/qqmljsimporter.cpp b/src/qmlcompiler/qqmljsimporter.cpp
index f8adeb79c2..c491e6d86e 100644
--- a/src/qmlcompiler/qqmljsimporter.cpp
+++ b/src/qmlcompiler/qqmljsimporter.cpp
@@ -35,7 +35,7 @@ static QQmlDirParser createQmldirParserForFile(const QString &filename)
}
void QQmlJSImporter::readQmltypes(
- const QString &filename, QHash<QString, QQmlJSExportedScope> *objects,
+ const QString &filename, QList<QQmlJSExportedScope> *objects,
QList<QQmlDirParser::Import> *dependencies)
{
const QFileInfo fileInfo(filename);
@@ -198,7 +198,7 @@ QQmlJSImporter::Import QQmlJSImporter::readQmldir(const QString &path)
reader.typeNamespace(), it.key(), it->version, QTypeRevision()));
}
for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it)
- result.objects.insert(it.key(), it.value());
+ result.objects.append(it.value());
const auto scripts = reader.scripts();
for (const auto &script : scripts) {
@@ -224,7 +224,7 @@ QQmlJSImporter::Import QQmlJSImporter::readDirectory(const QString &directory)
for (const auto &entry : resources) {
const QString name = QFileInfo(entry.resourcePath).baseName();
if (name.front().isUpper()) {
- import.objects.insert(name, {
+ import.objects.append({
localFile2ScopeTree(entry.filePath),
{ QQmlJSScope::Export(QString(), name, QTypeRevision(), QTypeRevision()) }
});
@@ -244,12 +244,21 @@ QQmlJSImporter::Import QQmlJSImporter::readDirectory(const QString &directory)
QDir::NoFilter
};
while (it.hasNext()) {
- it.next();
- if (!it.fileName().front().isUpper())
- continue; // Non-uppercase names cannot be imported anyway.
+ QString name = it.nextFileInfo().completeBaseName();
- const QString name = QFileInfo(it.filePath()).baseName();
- import.objects.insert(name, {
+ // Non-uppercase names cannot be imported anyway.
+ if (!name.front().isUpper())
+ continue;
+
+ // .ui.qml is fine
+ if (name.endsWith(u".ui"))
+ name = name.chopped(3);
+
+ // Names with dots in them cannot be imported either.
+ if (name.contains(u'.'))
+ continue;
+
+ import.objects.append({
localFile2ScopeTree(it.filePath()),
{ QQmlJSScope::Export(QString(), name, QTypeRevision(), QTypeRevision()) }
});
@@ -415,9 +424,7 @@ void QQmlJSImporter::processImport(const QQmlJSScope::Import &importDescription,
}
// add objects
- for (auto it = import.objects.begin(); it != import.objects.end(); ++it) {
- const auto &val = it.value();
-
+ for (const auto &val : import.objects) {
const QString cppName = isComposite(val.scope)
? prefixedName(anonPrefix, internalName(val.scope))
: internalName(val.scope);
@@ -470,9 +477,7 @@ void QQmlJSImporter::processImport(const QQmlJSScope::Import &importDescription,
}
}
- for (auto it = import.objects.begin(); it != import.objects.end(); ++it) {
- const auto &val = it.value();
-
+ for (const auto &val : qAsConst(import.objects)) {
// Otherwise we have already done it in localFile2ScopeTree()
if (!val.scope.factory() && val.scope->baseType().isNull()) {
@@ -546,10 +551,22 @@ QQmlJSImporter::AvailableTypes QQmlJSImporter::builtinImportHelper()
const QQmlJSScope::Import builtinImport(
QString(), QStringLiteral("QML"), QTypeRevision::fromVersion(1, 0), false, true);
- const QQmlJSScope::ConstPtr intType = result.objects[u"int"_s].scope;
- Q_ASSERT(intType);
+ QQmlJSScope::ConstPtr intType;
+ QQmlJSScope::ConstPtr arrayType;
+
+ for (const QQmlJSExportedScope &exported : result.objects) {
+ if (exported.scope->internalName() == u"int"_s) {
+ intType = exported.scope;
+ if (!arrayType.isNull())
+ break;
+ } else if (exported.scope->internalName() == u"Array"_s) {
+ arrayType = exported.scope;
+ if (!intType.isNull())
+ break;
+ }
+ }
- const QQmlJSScope::ConstPtr arrayType = result.objects[u"Array"_s].scope;
+ Q_ASSERT(intType);
Q_ASSERT(arrayType);
m_builtins = AvailableTypes(ImportedTypes(
diff --git a/src/qmlcompiler/qqmljsimporter_p.h b/src/qmlcompiler/qqmljsimporter_p.h
index 017917d3cf..792e26a291 100644
--- a/src/qmlcompiler/qqmljsimporter_p.h
+++ b/src/qmlcompiler/qqmljsimporter_p.h
@@ -115,7 +115,7 @@ private:
bool isStaticModule = false;
bool isSystemModule = false;
- QHash<QString, QQmlJSExportedScope> objects;
+ QList<QQmlJSExportedScope> objects;
QHash<QString, QQmlJSExportedScope> scripts;
QList<QQmlDirParser::Import> imports;
QList<QQmlDirParser::Import> dependencies;
@@ -130,7 +130,7 @@ private:
void importDependencies(const QQmlJSImporter::Import &import, AvailableTypes *types,
const QString &prefix = QString(),
QTypeRevision version = QTypeRevision(), bool isDependency = false);
- void readQmltypes(const QString &filename, QHash<QString, QQmlJSExportedScope> *objects,
+ void readQmltypes(const QString &filename, QList<QQmlJSExportedScope> *objects,
QList<QQmlDirParser::Import> *dependencies);
Import readQmldir(const QString &dirname);
Import readDirectory(const QString &directory);
diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
index 8c6368dfde..9360119c5c 100644
--- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp
+++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp
@@ -31,8 +31,7 @@ QString toString(const UiQualifiedId *qualifiedId, QChar delimiter = QLatin1Char
}
bool QQmlJSTypeDescriptionReader::operator()(
- QHash<QString, QQmlJSExportedScope> *objects,
- QStringList *dependencies)
+ QList<QQmlJSExportedScope> *objects, QStringList *dependencies)
{
Engine engine;
@@ -260,7 +259,7 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast)
if (metaObjectRevisions)
checkMetaObjectRevisions(metaObjectRevisions, &exports);
- m_objects->insert(scope->internalName(), {scope, exports});
+ m_objects->append({scope, exports});
}
void QQmlJSTypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bool isMethod,
diff --git a/src/qmlcompiler/qqmljstypedescriptionreader_p.h b/src/qmlcompiler/qqmljstypedescriptionreader_p.h
index 58a01d6fb8..37dd388308 100644
--- a/src/qmlcompiler/qqmljstypedescriptionreader_p.h
+++ b/src/qmlcompiler/qqmljstypedescriptionreader_p.h
@@ -33,7 +33,7 @@ public:
explicit QQmlJSTypeDescriptionReader(QString fileName, QString data)
: m_fileName(std::move(fileName)), m_source(std::move(data)) {}
- bool operator()(QHash<QString, QQmlJSExportedScope> *objects, QStringList *dependencies);
+ bool operator()(QList<QQmlJSExportedScope> *objects, QStringList *dependencies);
QString errorMessage() const { return m_errorMessage; }
QString warningMessage() const { return m_warningMessage; }
@@ -73,7 +73,7 @@ private:
QString m_source;
QString m_errorMessage;
QString m_warningMessage;
- QHash<QString, QQmlJSExportedScope> *m_objects = nullptr;
+ QList<QQmlJSExportedScope> *m_objects = nullptr;
QStringList *m_dependencies = nullptr;
};
diff --git a/src/qmldom/qqmldomtypesreader.cpp b/src/qmldom/qqmldomtypesreader.cpp
index 355ef99eba..69fba60047 100644
--- a/src/qmldom/qqmldomtypesreader.cpp
+++ b/src/qmldom/qqmldomtypesreader.cpp
@@ -246,7 +246,7 @@ bool QmltypesReader::parse()
QQmlJSTypeDescriptionReader reader(qmltypesFilePtr()->canonicalFilePath(),
qmltypesFilePtr()->code());
QStringList dependencies;
- QHash<QString, QQmlJSExportedScope> objects;
+ QList<QQmlJSExportedScope> objects;
m_isValid = reader(&objects, &dependencies);
for (const auto &obj : std::as_const(objects))
insertComponent(obj.scope, obj.exports);
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index b7f8f28aeb..5bb30f1969 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -8,6 +8,7 @@ set(cpp_sources
dynamicmeta.h
gadgetwithenum.h
invisible.h
+ multiforeign.h
objectwithmethod.h
person.cpp person.h
state.h
@@ -119,6 +120,7 @@ set(qml_files
methods.qml
modulePrefix.qml
moveRegVoid.qml
+ multiforeign.qml
noBindingLoop.qml
noQQmlData.qml
nonNotifyable.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/multiforeign.h b/tests/auto/qml/qmlcppcodegen/data/multiforeign.h
new file mode 100644
index 0000000000..290b6370f5
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/multiforeign.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MULTIFOREIGN_H
+#define MULTIFOREIGN_H
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+
+class Autochthon : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString location READ location WRITE setLocation NOTIFY locationChanged FINAL)
+
+public:
+ const QString &location() const
+ {
+ return m_location;
+ }
+
+ void setLocation(const QString &newLocation)
+ {
+ if (m_location == newLocation)
+ return;
+ m_location = newLocation;
+ emit locationChanged();
+ }
+
+signals:
+ void locationChanged();
+
+private:
+ QString m_location;
+};
+
+struct Foreign1
+{
+ Q_GADGET
+ QML_FOREIGN(Autochthon)
+ QML_ELEMENT
+};
+
+struct Foreign2
+{
+ Q_GADGET
+ QML_FOREIGN(Autochthon)
+ QML_ELEMENT
+};
+
+
+#endif // MULTIFOREIGN_H
diff --git a/tests/auto/qml/qmlcppcodegen/data/multiforeign.qml b/tests/auto/qml/qmlcppcodegen/data/multiforeign.qml
new file mode 100644
index 0000000000..0db62fe875
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/multiforeign.qml
@@ -0,0 +1,10 @@
+pragma Strict
+import TestTypes
+import QtQml
+
+QtObject {
+ objectName: f1.location + " and " + f2.location
+ property Foreign1 f1: Foreign1 { location: "not here" }
+ property Foreign2 f2: Foreign2 { location: "not there" }
+
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index 4b4cc6042a..1dd4c0fcf0 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -147,6 +147,7 @@ private slots:
void callWithSpread();
void nullComparison();
void consoleObject();
+ void multiForeign();
};
void tst_QmlCppCodegen::initTestCase()
@@ -2859,6 +2860,16 @@ void tst_QmlCppCodegen::consoleObject()
QVERIFY(!o.isNull());
}
+void tst_QmlCppCodegen::multiForeign()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/multiforeign.qml"_s));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+ QCOMPARE(o->objectName(), u"not here and not there"_s);
+}
+
QTEST_MAIN(tst_QmlCppCodegen)
#include "tst_qmlcppcodegen.moc"