aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-01-25 16:34:14 +0100
committerUlf Hermann <ulf.hermann@qt.io>2024-02-01 15:14:27 +0100
commitc3474688f68607ffff301c01450f71c4920b501d (patch)
tree53bfbe31e1351cb0ee88a44b8f5f336fc388f3a8
parentd8901aa0f6a61b08637039813068c84a5946e0e9 (diff)
QQmlTypeLoader: Honor import dependencies even without qmldir
If we register a module purely from C++, we still want to load the import dependencies. Change-Id: I3aa2d0e0b16a5f1c7c81d5fe7a130ec9d12d5c65 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/qml/qml/qqmltypeloader.cpp56
-rw-r--r--tests/auto/qml/qqmlimport/tst_qqmlimport.cpp19
2 files changed, 53 insertions, 22 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 8e27faf26b..838bec8824 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -602,6 +602,28 @@ bool QQmlTypeLoader::Blob::addFileImport(const QQmlTypeLoader::Blob::PendingImpo
return true;
}
+static void addDependencyImportError(
+ const QQmlTypeLoader::Blob::PendingImportPtr &import, QList<QQmlError> *errors)
+{
+ QQmlError error;
+ QString reason = errors->front().description();
+ if (reason.size() > 512)
+ reason = reason.first(252) + QLatin1String("... ...") + reason.last(252);
+ if (import->version.hasMajorVersion()) {
+ error.setDescription(QQmlImportDatabase::tr(
+ "module \"%1\" version %2.%3 cannot be imported because:\n%4")
+ .arg(import->uri).arg(import->version.majorVersion())
+ .arg(import->version.hasMinorVersion()
+ ? QString::number(import->version.minorVersion())
+ : QLatin1String("x"))
+ .arg(reason));
+ } else {
+ error.setDescription(QQmlImportDatabase::tr("module \"%1\" cannot be imported because:\n%2")
+ .arg(import->uri, reason));
+ }
+ errors->prepend(error);
+}
+
bool QQmlTypeLoader::Blob::addLibraryImport(const QQmlTypeLoader::Blob::PendingImportPtr &import, QList<QQmlError> *errors)
{
QQmlImportDatabase *importDatabase = typeLoader()->importDatabase();
@@ -627,23 +649,7 @@ bool QQmlTypeLoader::Blob::addLibraryImport(const QQmlTypeLoader::Blob::PendingI
import->version = actualVersion;
if (!loadImportDependencies(import, qmldirFilePath, import->flags, errors)) {
- QQmlError error;
- QString reason = errors->front().description();
- if (reason.size() > 512)
- reason = reason.first(252) + QLatin1String("... ...") + reason.last(252);
- if (import->version.hasMajorVersion()) {
- error.setDescription(QQmlImportDatabase::tr(
- "module \"%1\" version %2.%3 cannot be imported because:\n%4")
- .arg(import->uri).arg(import->version.majorVersion())
- .arg(import->version.hasMinorVersion()
- ? QString::number(import->version.minorVersion())
- : QLatin1String("x"))
- .arg(reason));
- } else {
- error.setDescription(QQmlImportDatabase::tr("module \"%1\" cannot be imported because:\n%2")
- .arg(import->uri, reason));
- }
- errors->prepend(error);
+ addDependencyImportError(import, errors);
return false;
}
@@ -654,7 +660,13 @@ bool QQmlTypeLoader::Blob::addLibraryImport(const QQmlTypeLoader::Blob::PendingI
switch (qmldirResult) {
case QQmlImportDatabase::QmldirFound:
return true;
- case QQmlImportDatabase::QmldirNotFound:
+ case QQmlImportDatabase::QmldirNotFound: {
+ if (!loadImportDependencies(import, QString(), import->flags, errors)) {
+ addDependencyImportError(import, errors);
+ return false;
+ }
+ break;
+ }
case QQmlImportDatabase::QmldirInterceptedToRemote:
break;
case QQmlImportDatabase::QmldirRejected:
@@ -815,10 +827,10 @@ bool QQmlTypeLoader::Blob::loadImportDependencies(
const QQmlTypeLoader::Blob::PendingImportPtr &currentImport, const QString &qmldirUri,
QQmlImports::ImportFlags flags, QList<QQmlError> *errors)
{
- const QQmlTypeLoaderQmldirContent qmldir = typeLoader()->qmldirContent(qmldirUri);
- const QList<QQmlDirParser::Import> implicitImports
- = QQmlMetaType::moduleImports(currentImport->uri, currentImport->version)
- + qmldir.imports();
+ QList<QQmlDirParser::Import> implicitImports
+ = QQmlMetaType::moduleImports(currentImport->uri, currentImport->version);
+ if (!qmldirUri.isEmpty())
+ implicitImports += typeLoader()->qmldirContent(qmldirUri).imports();
// Prevent overflow from one category of import into the other.
switch (currentImport->precedence) {
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index 692548ee5b..f08a8d423a 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -525,6 +525,25 @@ void tst_QQmlImport::registerModuleImport()
qmlUnregisterModuleImport("MyPluginSupported", 2, "QtQuick", 2);
qmlUnregisterModuleImport("MyPluginSupported", 2, "ShadowQuick", 1);
+
+ qmlRegisterTypesAndRevisions<NotItem>("NoQmldir", 2);
+ qmlRegisterModuleImport("NoQmldir", QQmlModuleImportModuleAny, "QtQml", QQmlModuleImportAuto);
+
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(R"(
+ import NoQmldir 2.0
+ QtObject {
+ property Item item: Item {}
+ }
+ )", QUrl::fromLocalFile(""));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ std::unique_ptr<QObject> object { component.create() };
+ QVERIFY(object);
+ NotItem *item = object->property("item").value<NotItem *>();
+ QVERIFY(item);
+ }
}
void tst_QQmlImport::importDependenciesPrecedence()