QmlDesigner: Inject QtQuick.Controls into possible imports if necessary

In Qt6, QtQuick.Controls module itself doesn't contain any versioned
types, so it will only appear as unversioned module in the QmlJS
snaphot. It is still valid import, as behind the scenes it will import
QtQuick.Controls.impl, which has the versioned types. However, QmlJS
can't handle this case, so we work around it by including
QtQuick.Controls as a possible import if corresponding .impl is
a possible import.

Fixes: QDS-5182
Change-Id: I6cc73ccaee0c16f0bcd09e4279cba411a76b45f2
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2021-10-25 13:58:41 +03:00
parent 6ef7010a95
commit ea1cf9125e

View File

@@ -931,17 +931,44 @@ static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &pat
static QList<QmlDesigner::Import> generatePossibleLibraryImports(const QHash<QString, ImportKey> &filteredPossibleImportKeys) static QList<QmlDesigner::Import> generatePossibleLibraryImports(const QHash<QString, ImportKey> &filteredPossibleImportKeys)
{ {
QList<QmlDesigner::Import> possibleImports; QList<QmlDesigner::Import> possibleImports;
QSet<QString> controlsImplVersions;
bool hasVersionedControls = false;
bool hasVersionlessControls = false;
const QString controlsName = "QtQuick.Controls";
const QString controlsImplName = "QtQuick.Controls.impl";
foreach (const ImportKey &importKey, filteredPossibleImportKeys) { for (const ImportKey &importKey : filteredPossibleImportKeys) {
QString libraryName = importKey.splitPath.join(QLatin1Char('.')); QString libraryName = importKey.splitPath.join(QLatin1Char('.'));
int majorVersion = importKey.majorVersion; int majorVersion = importKey.majorVersion;
if (majorVersion >= 0) { if (majorVersion >= 0) {
int minorVersion = (importKey.minorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 0 : importKey.minorVersion; int minorVersion = (importKey.minorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 0 : importKey.minorVersion;
QString version = QStringLiteral("%1.%2").arg(majorVersion).arg(minorVersion); QString version = QStringLiteral("%1.%2").arg(majorVersion).arg(minorVersion);
possibleImports.append(QmlDesigner::Import::createLibraryImport(libraryName, version)); possibleImports.append(QmlDesigner::Import::createLibraryImport(libraryName, version));
// In Qt6, QtQuick.Controls itself doesn't have any version as it has no types,
// so it never gets added normally to possible imports.
// We work around this by injecting corresponding QtQuick.Controls version for each
// found impl version, if no valid QtQuick.Controls versions are found.
if (!hasVersionedControls) {
if (libraryName == controlsImplName)
controlsImplVersions.insert(version);
else if (libraryName == controlsName)
hasVersionedControls = true;
}
} else if (!hasVersionlessControls && libraryName == controlsName) {
// If QtQuick.Controls module is not included even in non-versioned, it means
// QtQuick.Controls is either in use or not available at all,
// so we shouldn't inject it.
hasVersionlessControls = true;
} }
} }
if (hasVersionlessControls && !hasVersionedControls && !controlsImplVersions.isEmpty()) {
for (const auto &version : std::as_const(controlsImplVersions))
possibleImports.append(QmlDesigner::Import::createLibraryImport(controlsName, version));
}
return possibleImports; return possibleImports;
} }