diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-25 16:34:14 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-02-01 15:14:27 +0100 |
commit | c3474688f68607ffff301c01450f71c4920b501d (patch) | |
tree | 53bfbe31e1351cb0ee88a44b8f5f336fc388f3a8 | |
parent | d8901aa0f6a61b08637039813068c84a5946e0e9 (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.cpp | 56 | ||||
-rw-r--r-- | tests/auto/qml/qqmlimport/tst_qqmlimport.cpp | 19 |
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 ¤tImport, 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() |