diff options
27 files changed, 280 insertions, 76 deletions
diff --git a/src/imports/qtqml/CMakeLists.txt b/src/imports/qtqml/CMakeLists.txt index f50f2f69f5..c33aad5cc4 100644 --- a/src/imports/qtqml/CMakeLists.txt +++ b/src/imports/qtqml/CMakeLists.txt @@ -1,12 +1,12 @@ # Generated from qtqml.pro. set(module_dynamic_qml_imports - QtQml.Models + QtQml.Models/auto ) if (QT_FEATURE_qml_worker_script) list(APPEND module_dynamic_qml_imports - QtQml.WorkerScript + QtQml.WorkerScript/auto ) endif() diff --git a/src/imports/qtqml/qtqml.pro b/src/imports/qtqml/qtqml.pro index eac19954b6..ca162e65a9 100644 --- a/src/imports/qtqml/qtqml.pro +++ b/src/imports/qtqml/qtqml.pro @@ -15,9 +15,9 @@ DYNAMIC_QMLDIR = \ "classname QtQmlPlugin" \ "typeinfo plugins.qmltypes" \ "designersupported" \ - "import QtQml.Models" + "import QtQml.Models auto" qtConfig(qml-worker-script): DYNAMIC_QMLDIR += \ - "import QtQml.WorkerScript" + "import QtQml.WorkerScript auto" load(qml_plugin) diff --git a/src/imports/qtquick2/CMakeLists.txt b/src/imports/qtquick2/CMakeLists.txt index e007c476f8..1da9bad480 100644 --- a/src/imports/qtquick2/CMakeLists.txt +++ b/src/imports/qtquick2/CMakeLists.txt @@ -11,7 +11,7 @@ qt_add_qml_module(qtquick2plugin CLASSNAME QtQuick2Plugin SKIP_TYPE_REGISTRATION IMPORTS - QtQml + QtQml/auto SOURCES plugin.cpp PUBLIC_LIBRARIES diff --git a/src/imports/qtquick2/qmldir b/src/imports/qtquick2/qmldir index d74aabd9e9..b5c754a36f 100644 --- a/src/imports/qtquick2/qmldir +++ b/src/imports/qtquick2/qmldir @@ -3,4 +3,4 @@ plugin qtquick2plugin classname QtQuick2Plugin typeinfo plugins.qmltypes designersupported -import QtQml +import QtQml auto diff --git a/src/imports/window/qmldir b/src/imports/window/qmldir index 859cd341a1..c1cc5d89b7 100644 --- a/src/imports/window/qmldir +++ b/src/imports/window/qmldir @@ -1,2 +1,2 @@ module QtQuick.Window -import QtQuick +import QtQuick auto diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index d04d663656..4405db694a 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -57,7 +57,11 @@ # that can be read by QML tools such as Qt Creator to access information about # the types defined by the module's plugins. (OPTIONAL) # -# IMPORTS: List of other Qml Modules that this module imports. (OPTIONAL) +# IMPORTS: List of other Qml Modules that this module imports. A version can be +# specified by appending it after a slash(/), e.g QtQuick/2.0. The minor +# version may be omitted, e.g. QtQuick/2. Alternatively "auto" may be given +# as version to forward the version the current module is being imported with, +# e.g. QtQuick/auto. (OPTIONAL) # # RESOURCE_EXPORT: In static builds, when Qml files are processed via the Qt # Quick Compiler generate a separate static library that will be linked in @@ -254,7 +258,21 @@ function(qt6_add_qml_module target) string(APPEND qmldir_file_contents "typeinfo plugins.qmltypes\n") endif() foreach(import IN LISTS arg_IMPORTS) - string(APPEND qmldir_file_contents "import ${import}\n") + string(FIND ${import} "/" slash_position REVERSE) + if (slash_position EQUAL -1) + string(APPEND qmldir_file_contents "import ${import}\n") + else() + string(SUBSTRING ${import} 0 ${slash_position} import_module) + math(EXPR slash_position "${slash_position} + 1") + string(SUBSTRING ${import} ${slash_position} -1 import_version) + if (import_version MATCHES "[0-9]+\\.[0-9]+" OR import_version MATCHES "[0-9]+") + string(APPEND qmldir_file_contents "import ${import_module} ${import_version}\n") + elseif (import_version MATCHES "auto") + string(APPEND qmldir_file_contents "import ${import_module} auto\n") + else() + message(FATAL_ERROR "Invalid module import version number. Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'.") + endif() + endif() endforeach() foreach(dependency IN LISTS arg_DEPENDENCIES) diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index e9dc5a043a..0be46f30d2 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -246,6 +246,23 @@ depends MyOtherModule 1.0 load QML (perhaps conditionally) which then depends on other modules. In such cases, the \c depends declaration is necessary to include the other modules in application packages. + \row + \li + \code +import <ModuleIdentifier> [<Version>] + \endcode + \li Declares that this module imports another. + + Example: + \code +import MyOtherModule 1.0 + \endcode + + The types from the other module are made available in the same type + namespace as this module is imported into. Omitting the version + imports the latest version available of the other module, specifying + \c auto as version imports the same version as the version of this + module specified in the QML \c import statement. \row \li diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 183818aca8..9d58fa7d9b 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -72,35 +72,107 @@ void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor) QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor)); } +static QQmlDirParser::Import resolveImport(const QString &uri, int importMajor, int importMinor) +{ + if (importMajor == QQmlModuleImportAuto) + return QQmlDirParser::Import(uri, QTypeRevision(), true); + else if (importMajor == QQmlModuleImportLatest) + return QQmlDirParser::Import(uri, QTypeRevision(), false); + else if (importMinor == QQmlModuleImportLatest) + return QQmlDirParser::Import(uri, QTypeRevision::fromMajorVersion(importMajor), false); + return QQmlDirParser::Import(uri, QTypeRevision::fromVersion(importMajor, importMinor), false); +} + +static QTypeRevision resolveModuleVersion(int moduleMajor) +{ + return moduleMajor == QQmlModuleImportModuleAny + ? QTypeRevision() + : QTypeRevision::fromMajorVersion(moduleMajor); +} + +/*! + * \enum QQmlModuleImportSpecialVersions + * + * Defines some special values that can be passed to the version arguments of + * qmlRegisterModuleImport() and qmlUnregisterModuleImport(). + * + * \value QQmlModuleImportModuleAny When passed as majorVersion of the base + * module, signifies that the import is to be + * applied to any version of the module. + * \value QQmlModuleImportLatest When passed as major or minor version of + * the imported module, signifies that the + * latest overall, or latest minor version + * of a specified major version shall be + * imported. + * \value QQmlModuleImportAuto When passed as major version of the imported + * module, signifies that the version of the + * base module shall be forwarded. + */ + /*! * Registers an implicit import for module \a uri of major version \a majorVersion * * This has the same effect as an \c import statement in a qmldir file: Whenever - * \a uri version \a majorVersion is imported, \a import is automatically - * imported, too, with the same version. + * \a uri of version \a moduleMajor is imported, \a import of version + * \a importMajor.\a importMinor is automatically imported, too. If + * \a importMajor is \l QmlModuleImportLatest the latest version + * available of that module is imported, and \a importMinor does not matter. If + * \a importMinor is \l QmlModuleImportLatest the latest minor version of a + * \a importMajor is chosen. If \a importMajor is \l QmlModuleImportAuto the + * version of \a import is version of \a uri being imported, and \a importMinor + * does not matter. If \a moduleMajor is \a QmlModuleImportModuleAny the module + * import is applied for any major version of \a uri. For example, you may + * specify that whenever any version of MyModule is imported, the latest version + * of MyOtherModule should be imported. Then, the following call would be + * appropriate: + * + * \code + * qmlRegisterModuleImport("MyModule", QmlModuleImportModuleAny, + * "MyOtherModule", QmlModuleImportLatest); + * \endcode + * + * Or, you may specify that whenever major version 5 of "MyModule" is imported, + * then version 3.14 of "MyOtherModule" should be imported: + * + * \code + * qmlRegisterModuleImport("MyModule", 5, "MyOtherModule", 3, 14); + * \endcode + * + * Finally, if you always want the same version of "MyOtherModule" to be + * imported whenever "MyModule" is imported, specify the following: + * + * \code + * qmlRegisterModuleImport("MyModule", QmlModuleImportModuleAny, + * "MyOtherModule", QmlModuleImportAuto); + * \endcode * * \sa qmlUnregisterModuleImport() */ -void qmlRegisterModuleImport(const char *uri, int majorVersion, const char *import) +void qmlRegisterModuleImport(const char *uri, int moduleMajor, + const char *import, int importMajor, int importMinor) { QQmlMetaType::registerModuleImport( - QString::fromUtf8(uri), QTypeRevision::fromMajorVersion(majorVersion), - QString::fromUtf8(import)); + QString::fromUtf8(uri), resolveModuleVersion(moduleMajor), + resolveImport(QString::fromUtf8(import), importMajor, importMinor)); } + /*! * Removes a module import previously registered with qmlRegisterModuleImport() * - * Calling this function makes sure that \a import is not automatically imported - * anymore when \a uri of version \a majorVersion is. + * Calling this function makes sure that \a import of version + * \a{importMajor}.\a{importMinor} is not automatically imported anymore when + * \a uri of version \a moduleMajor is. The version resolution works the same + * way as with \l qmlRegisterModuleImport(). * * \sa qmlRegisterModuleImport() */ -void qmlUnregisterModuleImport(const char *uri, int majorVersion, const char *import) +void qmlUnregisterModuleImport(const char *uri, int moduleMajor, + const char *import, int importMajor, int importMinor) { QQmlMetaType::unregisterModuleImport( - QString::fromUtf8(uri), QTypeRevision::fromMajorVersion(majorVersion), - QString::fromUtf8(import)); + QString::fromUtf8(uri), resolveModuleVersion(moduleMajor), + resolveImport(QString::fromUtf8(import), importMajor, importMinor)); } //From qqml.h diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index ee3afa768a..ae72d90875 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -675,8 +675,20 @@ QT_WARNING_POP Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion); Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor); -Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int majorVersion, const char *import); -Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int majorVersion, const char *import); +enum QQmlModuleImportSpecialVersions: int { + QQmlModuleImportModuleAny = -1, + QQmlModuleImportLatest = -1, + QQmlModuleImportAuto = -2 +}; + +Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int moduleMajor, + const char *import, + int importMajor = QQmlModuleImportLatest, + int importMinor = QQmlModuleImportLatest); +Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int moduleMajor, + const char *import, + int importMajor = QQmlModuleImportLatest, + int importMinor = QQmlModuleImportLatest); template<typename T> QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 78f1d984e5..77d3571a05 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -628,22 +628,53 @@ bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version, bool return range.first != range.second; } -void QQmlMetaType::registerModuleImport(const QString &uri, QTypeRevision version, const QString &import) +void QQmlMetaType::registerModuleImport(const QString &uri, QTypeRevision moduleVersion, + const QQmlDirParser::Import &import) { QQmlMetaTypeDataPtr data; - QQmlTypeModule *module = getTypeModule(uri, version, data); - Q_ASSERT(module); - module->addImport(import); + data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import); +} + +static bool operator==(const QQmlDirParser::Import &a, const QQmlDirParser::Import &b) +{ + return a.module == b.module && a.version == b.version && a.isAutoImport == b.isAutoImport; } -void QQmlMetaType::unregisterModuleImport(const QString &uri, QTypeRevision version, const QString &import) +void QQmlMetaType::unregisterModuleImport(const QString &uri, QTypeRevision moduleVersion, + const QQmlDirParser::Import &import) { QQmlMetaTypeDataPtr data; + data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import); +} - QQmlTypeModule *module = getTypeModule(uri, version, data); - Q_ASSERT(module); - module->removeImport(import); +QList<QQmlDirParser::Import> QQmlMetaType::moduleImports( + const QString &uri, QTypeRevision version) +{ + QQmlMetaTypeDataPtr data; + + const auto unrevisioned = data->moduleImports.equal_range( + QQmlMetaTypeData::VersionedUri(uri, QTypeRevision())); + + QList<QQmlDirParser::Import> result(unrevisioned.first, unrevisioned.second); + if (version.hasMajorVersion()) + return result + data->moduleImports.values(QQmlMetaTypeData::VersionedUri(uri, version)); + + // Use latest module available with that URI. + const auto begin = data->moduleImports.begin(); + auto it = unrevisioned.first; + if (it == begin) + return result; + + const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key(); + if (latestVersion.uri != uri) + return result; + + do { + result += *it; + } while (it != begin && (--it).key() == latestVersion); + + return result; } void QQmlMetaType::registerModule(const char *uri, QTypeRevision version) diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 1c00d65b75..7b142dd07f 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -54,6 +54,7 @@ #include <private/qtqmlglobal_p.h> #include <private/qqmltype_p.h> #include <private/qqmlproxymetaobject_p.h> +#include <private/qqmldirparser_p.h> QT_BEGIN_NAMESPACE @@ -98,8 +99,12 @@ public: static void registerModule(const char *uri, QTypeRevision version); static bool protectModule(const QString &uri, QTypeRevision version, bool protectAllVersions = false); - static void registerModuleImport(const QString &uri, QTypeRevision version, const QString &import); - static void unregisterModuleImport(const QString &uri, QTypeRevision version, const QString &import); + + static void registerModuleImport(const QString &uri, QTypeRevision version, + const QQmlDirParser::Import &import); + static void unregisterModuleImport(const QString &uri, QTypeRevision version, + const QQmlDirParser::Import &import); + static QList<QQmlDirParser::Import> moduleImports(const QString &uri, QTypeRevision version); static int typeId(const char *uri, QTypeRevision version, const char *qmlName); diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index b2ecbf2cea..a5d919e471 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -116,6 +116,9 @@ struct QQmlMetaTypeData QQmlTypeModule *findTypeModule(const QString &module, QTypeRevision version); QQmlTypeModule *addTypeModule(std::unique_ptr<QQmlTypeModule> module); + using ModuleImports = QMultiMap<VersionedUri, QQmlDirParser::Import>; + ModuleImports moduleImports; + QHash<QString, void (*)()> moduleTypeRegistrationFunctions; bool registerModuleTypes(const QString &uri); diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index ff0633a475..8e90388258 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -714,15 +714,15 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob) bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport, const QString &qmldirUri, QList<QQmlError> *errors) { const QQmlTypeLoaderQmldirContent qmldir = typeLoader()->qmldirContent(qmldirUri); - const QQmlTypeModule *module = QQmlMetaType::typeModule(currentImport->uri, - currentImport->version); - const QStringList implicitImports = module ? (module->imports() + qmldir.imports()) - : qmldir.imports(); - for (const QString &implicitImport : implicitImports) { + const QList<QQmlDirParser::Import> implicitImports + = QQmlMetaType::moduleImports(currentImport->uri, currentImport->version) + + qmldir.imports(); + for (const auto &implicitImport : implicitImports) { auto dependencyImport = std::make_shared<PendingImport>(); - dependencyImport->uri = implicitImport; + dependencyImport->uri = implicitImport.module; dependencyImport->qualifier = currentImport->qualifier; - dependencyImport->version = currentImport->version; + dependencyImport->version = implicitImport.isAutoImport ? currentImport->version + : implicitImport.version; if (!addImport(dependencyImport, QQmlImports::ImportLowPrecedence, errors)) { QQmlError error; error.setDescription( diff --git a/src/qml/qml/qqmltypeloaderqmldircontent.cpp b/src/qml/qml/qqmltypeloaderqmldircontent.cpp index 714ea79e67..2175c115e6 100644 --- a/src/qml/qml/qqmltypeloaderqmldircontent.cpp +++ b/src/qml/qml/qqmltypeloaderqmldircontent.cpp @@ -105,7 +105,7 @@ QQmlDirPlugins QQmlTypeLoaderQmldirContent::plugins() const return m_parser.plugins(); } -QStringList QQmlTypeLoaderQmldirContent::imports() const +QQmlDirImports QQmlTypeLoaderQmldirContent::imports() const { return m_parser.imports(); } diff --git a/src/qml/qml/qqmltypeloaderqmldircontent_p.h b/src/qml/qml/qqmltypeloaderqmldircontent_p.h index 698643c7ec..677d06891e 100644 --- a/src/qml/qml/qqmltypeloaderqmldircontent_p.h +++ b/src/qml/qml/qqmltypeloaderqmldircontent_p.h @@ -78,7 +78,7 @@ public: QQmlDirComponents components() const; QQmlDirScripts scripts() const; QQmlDirPlugins plugins() const; - QStringList imports() const; + QQmlDirImports imports() const; QString pluginLocation() const; diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp index f700f4c01a..01de024deb 100644 --- a/src/qml/qml/qqmltypemodule.cpp +++ b/src/qml/qml/qqmltypemodule.cpp @@ -123,22 +123,4 @@ void QQmlTypeModule::walkCompositeSingletons(const std::function<void(const QQml } } -QStringList QQmlTypeModule::imports() const -{ - QMutexLocker lock(&m_mutex); - return m_imports; -} - -void QQmlTypeModule::addImport(const QString &import) -{ - QMutexLocker lock(&m_mutex); - m_imports.append(import); -} - -void QQmlTypeModule::removeImport(const QString &import) -{ - QMutexLocker lock(&m_mutex); - m_imports.removeAll(import); -} - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h index 28cf070a95..0ba6245cbb 100644 --- a/src/qml/qml/qqmltypemodule_p.h +++ b/src/qml/qml/qqmltypemodule_p.h @@ -104,16 +104,10 @@ public: void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const; - void addImport(const QString &import); - void removeImport(const QString &import); - QStringList imports() const; - private: const QString m_module; const quint8 m_majorVersion = 0; - QStringList m_imports; - // Can only ever decrease QAtomicInt m_minMinorVersion = std::numeric_limits<quint8>::max(); diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index e4d916a10f..c8589431b8 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -276,12 +276,28 @@ bool QQmlDirParser::parse(const QString &source) reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2])); } } else if (sections[0] == QLatin1String("import")) { - if (sectionCount != 2) { + if (sectionCount == 2) { + _imports << Import(sections[1], QTypeRevision(), false); + } else if (sectionCount == 3) { + if (sections[2] == QLatin1String("auto")) { + _imports << Import(sections[1], QTypeRevision(), true); + } else { + const auto version = parseVersion(sections[2]); + if (version.isValid()) { + _imports << Import(sections[1], version, false); + } else { + reportError(lineNumber, 0, + QStringLiteral("invalid version %1, expected <major>.<minor>") + .arg(sections[2])); + continue; + } + } + } else { reportError(lineNumber, 0, - QStringLiteral("import requires 2 arguments, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("import requires 1 or 2 arguments, but %1 were provided") + .arg(sectionCount - 1)); continue; } - _imports << sections[1]; } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], QTypeRevision()); @@ -374,7 +390,7 @@ QHash<QString, QQmlDirParser::Component> QQmlDirParser::dependencies() const return _dependencies; } -QStringList QQmlDirParser::imports() const +QList<QQmlDirParser::Import> QQmlDirParser::imports() const { return _imports; } diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index a5a548daca..68a0d6d5e2 100644 --- a/src/qml/qmldirparser/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -132,9 +132,20 @@ public: QTypeRevision version = QTypeRevision::zero(); }; + struct Import + { + Import() = default; + Import(QString module, QTypeRevision version, bool isAutoImport) + : module(module), version(version), isAutoImport(isAutoImport) {} + + QString module; + QTypeRevision version; // default: lastest version + bool isAutoImport = false; // if set: forward the version of the importing module + }; + QMultiHash<QString,Component> components() const; QHash<QString,Component> dependencies() const; - QStringList imports() const; + QList<Import> imports() const; QList<Script> scripts() const; QList<Plugin> plugins() const; bool designerSupported() const; @@ -161,7 +172,7 @@ private: QString _typeNamespace; QMultiHash<QString,Component> _components; QHash<QString,Component> _dependencies; - QStringList _imports; + QList<Import> _imports; QList<Script> _scripts; QList<Plugin> _plugins; bool _designerSupported = false; @@ -172,6 +183,7 @@ private: using QQmlDirComponents = QMultiHash<QString,QQmlDirParser::Component>; using QQmlDirScripts = QList<QQmlDirParser::Script>; using QQmlDirPlugins = QList<QQmlDirParser::Plugin>; +using QQmlDirImports = QList<QQmlDirParser::Import>; QDebug &operator<< (QDebug &, const QQmlDirParser::Component &); QDebug &operator<< (QDebug &, const QQmlDirParser::Script &); diff --git a/tests/auto/qml/qqmltypeloader/data/implicitautoimporttest.qml b/tests/auto/qml/qqmltypeloader/data/implicitautoimporttest.qml new file mode 100644 index 0000000000..e32bac3c89 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/implicitautoimporttest.qml @@ -0,0 +1,8 @@ +import modulewithimplicitautoimport 2.11 as MyNS +MyNS.Test { + MyNS.Item { // Implicitly imported from QtQuick + // containmentMask added in 2.11. Version is forwarded. + objectName: containmentMask.objectName + } + MyNS.ListModel {} +} diff --git a/tests/auto/qml/qqmltypeloader/data/implicitversionedimporttest.qml b/tests/auto/qml/qqmltypeloader/data/implicitversionedimporttest.qml new file mode 100644 index 0000000000..ae09eba4e0 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/implicitversionedimporttest.qml @@ -0,0 +1,8 @@ +import modulewithimplicitversionedimport 2.0 as MyNS +MyNS.Test { + MyNS.Item { // Implicitly imported from QtQuick + // containmentMask added in 2.11. Despite version 2.0 above, the module imports 2.15. + objectName: containmentMask.objectName + } + MyNS.ListModel {} +} diff --git a/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/Test.qml b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/Test.qml new file mode 100644 index 0000000000..2f78302506 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/Test.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 +Item { +} diff --git a/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/qmldir b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/qmldir new file mode 100644 index 0000000000..468eb296f7 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitautoimport/qmldir @@ -0,0 +1,3 @@ +import QtQuick auto +Test 2.0 Test.qml +Dummy 2.22 Test.qml diff --git a/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/Test.qml b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/Test.qml new file mode 100644 index 0000000000..2f78302506 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/Test.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 +Item { +} diff --git a/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/qmldir b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/qmldir new file mode 100644 index 0000000000..71bbbb99d0 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/imports/modulewithimplicitversionedimport/qmldir @@ -0,0 +1,2 @@ +import QtQuick 2.15 +Test 2.0 Test.qml diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 3843d9a720..e1fdb0e221 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -579,10 +579,25 @@ void tst_QQMLTypeLoader::implicitImport() { QQmlEngine engine; engine.addImportPath(testFile("imports")); - QQmlComponent component(&engine, testFileUrl("implicitimporttest.qml")); - QVERIFY2(component.isReady(), qPrintable(component.errorString())); - QScopedPointer<QObject> obj(component.create()); - QVERIFY(!obj.isNull()); + { + QQmlComponent component(&engine, testFileUrl("implicitimporttest.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + } + { + QQmlComponent component(&engine, testFileUrl("implicitautoimporttest.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + } + { + QQmlComponent component(&engine, testFileUrl("implicitversionedimporttest.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + } + } void tst_QQMLTypeLoader::compositeSingletonCycle() diff --git a/tools/qmllint/findwarnings.cpp b/tools/qmllint/findwarnings.cpp index cc8a323112..50123d8957 100644 --- a/tools/qmllint/findwarnings.cpp +++ b/tools/qmllint/findwarnings.cpp @@ -141,8 +141,8 @@ FindWarningVisitor::Import FindWarningVisitor::readQmldir(const QString &path) Import result; auto reader = createQmldirParserForFile(path + SlashQmldir); const auto imports = reader.imports(); - for (const QString &import : imports) - result.dependencies.append(import); + for (const auto &import : imports) + result.dependencies.append(import.module); // TODO: version QHash<QString, ScopeTree::Ptr> qmlComponents; const auto components = reader.components(); |