diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-06 15:45:05 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-08 18:54:29 +0200 |
commit | 04bc9d83f22a7266fb0caf53c2c3da0d9b06fef4 (patch) | |
tree | 883b9e3eba194efa05dbab3592fca8f1273b844b /src/qml/qmldirparser | |
parent | e8007671d4ec6d791cb337b297f2beb7e5300929 (diff) |
Allow optional imports in qmldir files
This is useful for modules that select their imports at runtime using
qmlRegisterModuleImport(). We can list all possible variants as optional
imports so that tools can see what types might be available.
Task-number: QTBUG-87130
Change-Id: I8a37bdde79aef3619fd1f05e5ea6781d521afa88
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qmldirparser')
-rw-r--r-- | src/qml/qmldirparser/qqmldirparser.cpp | 105 | ||||
-rw-r--r-- | src/qml/qmldirparser/qqmldirparser_p.h | 17 |
2 files changed, 71 insertions, 51 deletions
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; |