aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qmljs/qmljsplugindumper.cpp
diff options
context:
space:
mode:
authorChristian Kamm <mail@ckamm.de>2020-05-10 16:06:57 +0200
committerChristian Kamm <mail@ckamm.de>2020-05-21 07:54:08 +0000
commit40dd6fc1859bf0b5345d368e9cb3d4eddadf7fc5 (patch)
tree25b3610fe94fc18b7173564761c5e6fee9156090 /src/libs/qmljs/qmljsplugindumper.cpp
parentf64146741df05d7da7429f66af079b24c11cc3ca (diff)
QmlJS: Add workaround for missing imports in Qt >=5.15.0
The QtQuick module plugins.qmltypes in Qt 5.15.0 do not contain QML types like QtObject. Instead, they are found in the QtQml module. Something similar applies to QtQml and QtQml.Models and QtQml.WorkerScript. As Qt 5.15 can't use the "import" command in the qmldir file, this code instead detects the 5.15 QtQuick and QtQml modules and adds the dependent imports manually, as a workaround. Change-Id: I982e349298eb7200372390dfc384fb43a762b253 Task-number: QTCREATORBUG-23986 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/libs/qmljs/qmljsplugindumper.cpp')
-rw-r--r--src/libs/qmljs/qmljsplugindumper.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp
index de26d7435a..8b7604809b 100644
--- a/src/libs/qmljs/qmljsplugindumper.cpp
+++ b/src/libs/qmljs/qmljsplugindumper.cpp
@@ -494,6 +494,78 @@ QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const QStri
return iface->future();
}
+// Fills \a highestVersion with the largest export version for \a package
+// and sets \a hasExportName to true if a type called \a exportName is found.
+static void getHighestExportVersion(
+ const QList<LanguageUtils::FakeMetaObject::ConstPtr> &objects,
+ const QString &package,
+ const QString &exportName,
+ bool *hasExportName,
+ ComponentVersion *highestVersion)
+{
+ *highestVersion = ComponentVersion();
+ *hasExportName = false;
+ for (const auto &object : objects) {
+ for (const auto &e : object->exports()) {
+ if (e.package == package) {
+ if (e.version > *highestVersion)
+ *highestVersion = e.version;
+ if (e.type == exportName)
+ *hasExportName = true;
+ }
+ }
+ }
+
+}
+
+/*** Workaround for implicit dependencies in >= 5.15.0.
+ *
+ * When "QtQuick" is imported, "QtQml" is implicitly loaded as well.
+ * When "QtQml" is imported, "QtQml.Models" and "QtQml.WorkerScript" are implicitly loaded.
+ * Add these imports as if they were "import" commands in the qmldir file.
+ *
+ * Qt 6 is planned to have these included in the qmldir file.
+ */
+static void applyQt515MissingImportWorkaround(const QString &path, LibraryInfo &info)
+{
+ if (!info.imports().isEmpty())
+ return;
+
+ const bool isQtQuick = path.endsWith(QStringLiteral("/QtQuick"))
+ || path.endsWith(QStringLiteral("/QtQuick.2"));
+ const bool isQtQml = path.endsWith(QStringLiteral("/QtQml"))
+ || path.endsWith(QStringLiteral("/QtQml.2"));
+ if (!isQtQuick && !isQtQml)
+ return;
+
+ ComponentVersion highestVersion;
+ const auto package = isQtQuick ? QStringLiteral("QtQuick") : QStringLiteral("QtQml");
+ const auto missingTypeName = isQtQuick ? QStringLiteral("QtObject") : QStringLiteral("ListElement");
+ bool hasMissingType = false;
+ getHighestExportVersion(
+ info.metaObjects(),
+ package,
+ missingTypeName,
+ &hasMissingType,
+ &highestVersion);
+
+ // If the highest export version is < 2.15, we expect Qt <5.15
+ if (highestVersion.majorVersion() != 2 || highestVersion.minorVersion() < 15)
+ return;
+ // As an extra sanity check: if the type from the dependent module already exists,
+ // don't proceeed either.
+ if (hasMissingType)
+ return;
+
+ if (isQtQuick) {
+ info.setImports(QStringList(QStringLiteral("QtQml")));
+ } else if (isQtQml) {
+ info.setImports(QStringList(
+ { QStringLiteral("QtQml.Models"),
+ QStringLiteral("QtQml.WorkerScript") }));
+ }
+}
+
void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
const QString &libraryPath,
const QStringList &deps,
@@ -519,6 +591,8 @@ void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
if (!warnings.isEmpty())
printParseWarnings(libraryPath, warnings.join(QLatin1String("\n")));
+ applyQt515MissingImportWorkaround(libraryPath, libInfo);
+
libInfo.updateFingerprint();
}