From ea1cf9125e53e32ef778cf238daaa7e3216d2bf6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 25 Oct 2021 13:58:41 +0300 Subject: [PATCH] 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 Reviewed-by: Thomas Hartmann --- .../designercore/model/texttomodelmerger.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index c678f3b06d7..44fcf91774d 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -931,17 +931,44 @@ static QList generatePossibleFileImports(const QString &pat static QList generatePossibleLibraryImports(const QHash &filteredPossibleImportKeys) { QList possibleImports; + QSet 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('.')); int majorVersion = importKey.majorVersion; if (majorVersion >= 0) { int minorVersion = (importKey.minorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 0 : importKey.minorVersion; QString version = QStringLiteral("%1.%2").arg(majorVersion).arg(minorVersion); 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; }