diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/Qt6QmlBuildInternals.cmake | 2 | ||||
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 42 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 6 | ||||
-rw-r--r-- | src/qml/qmldirparser/qqmldirparser.cpp | 105 | ||||
-rw-r--r-- | src/qml/qmldirparser/qqmldirparser_p.h | 17 |
7 files changed, 109 insertions, 73 deletions
diff --git a/src/qml/Qt6QmlBuildInternals.cmake b/src/qml/Qt6QmlBuildInternals.cmake index d74b1d55fe..0e702feea2 100644 --- a/src/qml/Qt6QmlBuildInternals.cmake +++ b/src/qml/Qt6QmlBuildInternals.cmake @@ -39,6 +39,7 @@ function(qt_internal_add_qml_module target) set(qml_module_multi_args IMPORTS + OPTIONAL_IMPORTS TYPEINFO DEPENDENCIES ) @@ -134,6 +135,7 @@ function(qt_internal_add_qml_module target) VERSION ${arg_VERSION} QML_FILES ${arg_QML_FILES} IMPORTS "${arg_IMPORTS}" + OPTIONAL_IMPORTS "${arg_OPTIONAL_IMPORTS}" TYPEINFO "${arg_TYPEINFO}" DO_NOT_INSTALL_METADATA DO_NOT_CREATE_TARGET diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 4bd457311a..0afd365948 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -63,6 +63,11 @@ # as version to forward the version the current module is being imported with, # e.g. QtQuick/auto. (OPTIONAL) # +# OPTIONAL_IMPORTS: List of other Qml Modules that this module may import at +# run-time. Those are not automatically imported by the QML engine when +# importing the current module, but rather serve as hints to tools like +# qmllint. Versions can be specified in the same as for IMPORT. (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 # as an Interface. Supply an output variable to perform any custom actions @@ -109,6 +114,7 @@ function(qt6_add_qml_module target) SOURCES QML_FILES IMPORTS + OPTIONAL_IMPORTS DEPENDENCIES ) @@ -283,23 +289,29 @@ function(qt6_add_qml_module target) # plugins.qmltypes is actually generated. string(APPEND qmldir_file_contents "typeinfo plugins.qmltypes\n") endif() - foreach(import IN LISTS arg_IMPORTS) - 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") + + macro(_add_imports imports import_string) + foreach(import IN LISTS ${imports}) + string(FIND ${import} "/" slash_position REVERSE) + if (slash_position EQUAL -1) + string(APPEND qmldir_file_contents "${import_string} ${import}\n") else() - message(FATAL_ERROR "Invalid module import version number. Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'.") + 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_string} ${import_module} ${import_version}\n") + elseif (import_version MATCHES "auto") + string(APPEND qmldir_file_contents "${import_string} ${import_module} auto\n") + else() + message(FATAL_ERROR "Invalid module ${import_string} version number. Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'.") + endif() endif() - endif() - endforeach() + endforeach() + endmacro() + + _add_imports(arg_IMPORTS "import") + _add_imports(arg_OPTIONAL_IMPORTS "optional import") foreach(dependency IN LISTS arg_DEPENDENCIES) string(FIND ${dependency} "/" slash_position REVERSE) diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index d26a09b081..e61cf417e3 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -75,12 +75,12 @@ void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor) static QQmlDirParser::Import resolveImport(const QString &uri, int importMajor, int importMinor) { if (importMajor == QQmlModuleImportAuto) - return QQmlDirParser::Import(uri, QTypeRevision(), true); + return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Auto); else if (importMajor == QQmlModuleImportLatest) - return QQmlDirParser::Import(uri, QTypeRevision(), false); + return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Default); else if (importMinor == QQmlModuleImportLatest) - return QQmlDirParser::Import(uri, QTypeRevision::fromMajorVersion(importMajor), false); - return QQmlDirParser::Import(uri, QTypeRevision::fromVersion(importMajor, importMinor), false); + return QQmlDirParser::Import(uri, QTypeRevision::fromMajorVersion(importMajor), QQmlDirParser::Import::Default); + return QQmlDirParser::Import(uri, QTypeRevision::fromVersion(importMajor, importMinor), QQmlDirParser::Import::Default); } static QTypeRevision resolveModuleVersion(int moduleMajor) diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 16b05898d1..71fc753c3b 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -724,7 +724,7 @@ void QQmlMetaType::registerModuleImport(const QString &uri, QTypeRevision module static bool operator==(const QQmlDirParser::Import &a, const QQmlDirParser::Import &b) { - return a.module == b.module && a.version == b.version && a.isAutoImport == b.isAutoImport; + return a.module == b.module && a.version == b.version && a.flags == b.flags; } void QQmlMetaType::unregisterModuleImport(const QString &uri, QTypeRevision moduleVersion, diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 6b4ce26c97..1b14467266 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -742,11 +742,13 @@ bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport = QQmlMetaType::moduleImports(currentImport->uri, currentImport->version) + qmldir.imports(); for (const auto &implicitImport : implicitImports) { + if (implicitImport.flags & QQmlDirParser::Import::Optional) + continue; auto dependencyImport = std::make_shared<PendingImport>(); dependencyImport->uri = implicitImport.module; dependencyImport->qualifier = currentImport->qualifier; - dependencyImport->version = implicitImport.isAutoImport ? currentImport->version - : implicitImport.version; + dependencyImport->version = (implicitImport.flags & QQmlDirParser::Import::Auto) + ? currentImport->version : implicitImport.version; if (!addImport(dependencyImport, QQmlImports::ImportLowPrecedence, errors)) { QQmlError error; error.setDescription( diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index 0588e5bca7..403c04b1e1 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -110,6 +110,50 @@ bool QQmlDirParser::parse(const QString &source) quint16 lineNumber = 0; bool firstLine = true; + auto readImport = [&](const QString *sections, int sectionCount, Import::Flags flags) { + Import import; + if (sectionCount == 2) { + import = Import(sections[1], QTypeRevision(), flags); + } else if (sectionCount == 3) { + if (sections[2] == QLatin1String("auto")) { + import = Import(sections[1], QTypeRevision(), flags | Import::Auto); + } else { + const auto version = parseVersion(sections[2]); + if (version.isValid()) { + import = Import(sections[1], version, flags); + } else { + reportError(lineNumber, 0, + QStringLiteral("invalid version %1, expected <major>.<minor>") + .arg(sections[2])); + return false; + } + } + } else { + reportError(lineNumber, 0, + QStringLiteral("%1 requires 1 or 2 arguments, but %2 were provided") + .arg(sections[0]).arg(sectionCount - 1)); + return false; + } + if (sections[0] == QStringLiteral("import")) + _imports.append(import); + else + _dependencies.append(import); + return true; + }; + + auto readPlugin = [&](const QString *sections, int sectionCount, bool isOptional) { + if (sectionCount < 2 || sectionCount > 3) { + reportError(lineNumber, 0, QStringLiteral("plugin directive requires one or two " + "arguments, but %1 were provided") + .arg(sectionCount - 1)); + return false; + } + + const Plugin entry(sections[1], sections[2], isOptional); + _plugins.append(entry); + return true; + }; + const QChar *ch = source.constData(); while (!ch->isNull()) { ++lineNumber; @@ -176,34 +220,26 @@ bool QQmlDirParser::parse(const QString &source) _typeNamespace = sections[1]; } else if (sections[0] == QLatin1String("plugin")) { - if (sectionCount < 2 || sectionCount > 3) { - reportError(lineNumber, 0, - QStringLiteral("plugin directive requires one or two arguments, but %1 were provided") - .arg(sectionCount - 1)); - + if (!readPlugin(sections, sectionCount, false)) continue; - } - - const Plugin entry(sections[1], sections[2], false); - - _plugins.append(entry); - } else if (sections[0] == QLatin1String("optional")) { - if (sectionCount < 2 || sections[1] != QLatin1String("plugin")) { - reportError(lineNumber, 0, QStringLiteral("only plugins can be optional")); + if (sectionCount < 2) { + reportError(lineNumber, 0, QStringLiteral("optional directive requires further " + "arguments, but none were provided.")); continue; } - if (sectionCount < 3 || sectionCount > 4) { - reportError(lineNumber, 0, - QStringLiteral("plugin directive requires one or two arguments, but %1 were provided") - .arg(sectionCount - 2)); + if (sections[1] == QStringLiteral("plugin")) { + if (!readPlugin(sections + 1, sectionCount - 1, true)) + continue; + } else if (sections[1] == QLatin1String("import")) { + if (!readImport(sections + 1, sectionCount - 1, Import::Optional)) + continue; + } else { + reportError(lineNumber, 0, QStringLiteral("only import and plugin can be optional, " + "not %1.").arg(sections[1])); continue; } - - const Plugin entry(sections[2], sections[3], true); - _plugins.append(entry); - } else if (sections[0] == QLatin1String("classname")) { if (sectionCount < 2) { reportError(lineNumber, 0, @@ -261,33 +297,8 @@ bool QQmlDirParser::parse(const QString &source) _designerSupported = true; } else if (sections[0] == QLatin1String("import") || sections[0] == QLatin1String("depends")) { - Import import; - if (sectionCount == 2) { - import = Import(sections[1], QTypeRevision(), false); - } else if (sectionCount == 3) { - if (sections[2] == QLatin1String("auto")) { - import = Import(sections[1], QTypeRevision(), true); - } else { - const auto version = parseVersion(sections[2]); - if (version.isValid()) { - import = 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("%1 requires 1 or 2 arguments, but %2 were provided") - .arg(sections[0]).arg(sectionCount - 1)); + if (!readImport(sections, sectionCount, Import::Default)) continue; - } - if (sections[0] == QStringLiteral("import")) - _imports.append(import); - else - _dependencies.append(import); } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], QTypeRevision()); diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index 48f808ff12..098b15a51b 100644 --- a/src/qml/qmldirparser/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -134,13 +134,22 @@ public: struct Import { + enum Flag { + Default = 0x0, + Auto = 0x1, // forward the version of the importing module + Optional = 0x2 // is not automatically imported but only a tooling hint + }; + Q_DECLARE_FLAGS(Flags, Flag) + Import() = default; - Import(QString module, QTypeRevision version, bool isAutoImport) - : module(module), version(version), isAutoImport(isAutoImport) {} + Import(QString module, QTypeRevision version, Flags flags) + : module(module), version(version), flags(flags) + { + } QString module; - QTypeRevision version; // default: lastest version - bool isAutoImport = false; // if set: forward the version of the importing module + QTypeRevision version; // invalid version is latest version, unless Flag::Auto + Flags flags; }; QMultiHash<QString,Component> components() const; |