QQmlDirParser: Treat dependencies like imports

In particular, allow auto and latest versions.

Change-Id: I4a6b26112950d066ae2d8a37dc0e9fa1dec24724
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2020-09-25 13:29:50 +02:00
parent 5458f379ac
commit 0cc0c8535b
6 changed files with 38 additions and 28 deletions

View File

@ -260,31 +260,18 @@ bool QQmlDirParser::parse(const QString &source)
reportError(lineNumber, 0, QStringLiteral("designersupported does not expect any argument"));
else
_designerSupported = true;
} else if (sections[0] == QLatin1String("depends")) {
if (sectionCount != 3) {
reportError(lineNumber, 0,
QStringLiteral("depends requires 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
const QTypeRevision version = parseVersion(sections[2]);
if (version.isValid()) {
Component entry(sections[1], QString(), version);
entry.internal = true;
_dependencies.insert(entry.typeName, entry);
} else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2]));
}
} else if (sections[0] == QLatin1String("import")) {
} else if (sections[0] == QLatin1String("import")
|| sections[0] == QLatin1String("depends")) {
Import import;
if (sectionCount == 2) {
_imports << Import(sections[1], QTypeRevision(), false);
import = Import(sections[1], QTypeRevision(), false);
} else if (sectionCount == 3) {
if (sections[2] == QLatin1String("auto")) {
_imports << Import(sections[1], QTypeRevision(), true);
import = Import(sections[1], QTypeRevision(), true);
} else {
const auto version = parseVersion(sections[2]);
if (version.isValid()) {
_imports << Import(sections[1], version, false);
import = Import(sections[1], version, false);
} else {
reportError(lineNumber, 0,
QStringLiteral("invalid version %1, expected <major>.<minor>")
@ -294,10 +281,14 @@ bool QQmlDirParser::parse(const QString &source)
}
} else {
reportError(lineNumber, 0,
QStringLiteral("import requires 1 or 2 arguments, but %1 were provided")
.arg(sectionCount - 1));
QStringLiteral("%1 requires 1 or 2 arguments, but %2 were provided")
.arg(sections[0]).arg(sectionCount - 1));
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());
@ -385,7 +376,7 @@ QMultiHash<QString, QQmlDirParser::Component> QQmlDirParser::components() const
return _components;
}
QHash<QString, QQmlDirParser::Component> QQmlDirParser::dependencies() const
QList<QQmlDirParser::Import> QQmlDirParser::dependencies() const
{
return _dependencies;
}

View File

@ -144,7 +144,7 @@ public:
};
QMultiHash<QString,Component> components() const;
QHash<QString,Component> dependencies() const;
QList<Import> dependencies() const;
QList<Import> imports() const;
QList<Script> scripts() const;
QList<Plugin> plugins() const;
@ -171,7 +171,7 @@ private:
QList<QQmlJS::DiagnosticMessage> _errors;
QString _typeNamespace;
QMultiHash<QString,Component> _components;
QHash<QString,Component> _dependencies;
QList<Import> _dependencies;
QList<Import> _imports;
QList<Script> _scripts;
QList<Plugin> _plugins;

View File

@ -99,6 +99,14 @@ namespace {
+ QLatin1Char('|') + (c.internal ? "true" : "false");
}
QString toString(const QQmlDirParser::Import &i)
{
return i.module + QLatin1String("||")
+ QString::number(i.version.majorVersion()) + QLatin1Char('|')
+ QString::number(i.version.minorVersion())
+ QLatin1String("|true");
}
QStringList toStringList(const QQmlDirComponents &components)
{
QStringList rv;
@ -110,6 +118,17 @@ namespace {
return rv;
}
QStringList toStringList(const QQmlDirImports &components)
{
QStringList rv;
foreach (const QQmlDirParser::Import &c, components)
rv.append(toString(c));
std::sort(rv.begin(), rv.end());
return rv;
}
QString toString(const QQmlDirParser::Script &s)
{
return s.nameSpace + QLatin1Char('|') + s.fileName + QLatin1Char('|')

View File

@ -188,7 +188,7 @@ QVariantMap pluginsForModulePath(const QString &modulePath, const QString &versi
QStringList importsAndDependencies;
const auto dependencies = parser.dependencies();
for (const auto &dependency : dependencies)
importsAndDependencies.append(dependency.typeName + versionSuffix(dependency.version));
importsAndDependencies.append(dependency.module + versionSuffix(dependency.version));
const auto imports = parser.imports();
for (const auto &import : imports) {

View File

@ -100,7 +100,7 @@ FindWarningVisitor::Importer::Import FindWarningVisitor::Importer::readQmldir(co
Import result;
auto reader = createQmldirParserForFile(path + SlashQmldir);
result.imports.append(reader.imports());
result.dependencies.append(reader.dependencies().values());
result.dependencies.append(reader.dependencies());
QHash<QString, ScopeTree::Ptr> qmlComponents;
const auto components = reader.components();
@ -143,7 +143,7 @@ void FindWarningVisitor::Importer::processImport(
// QML code but the C++ types will be visible.
const QString invalidPrefix = QString::fromLatin1("$dependency$");
for (auto const &dependency : qAsConst(import.dependencies))
importHelper(dependency.typeName, invalidPrefix, dependency.version);
importHelper(dependency.module, invalidPrefix, dependency.version);
for (auto const &import : qAsConst(import.imports)) {
importHelper(import.module, prefix,

View File

@ -84,7 +84,7 @@ private:
struct Import {
QHash<QString, ScopeTree::Ptr> objects;
QList<QQmlDirParser::Import> imports;
QList<QQmlDirParser::Component> dependencies;
QList<QQmlDirParser::Import> dependencies;
QList<QPair<QString, ScopeTree::Ptr>> scripts;
};