diff options
10 files changed, 143 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 5a1364473e..ba8dce4b6e 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -465,9 +465,18 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports:: const QQmlDirComponents &components = import->qmlDirComponents; + const int importMajorVersion = import->majversion; + const int importMinorVersion = import->minversion; + auto shouldSkipSingleton = [importMajorVersion, importMinorVersion](int singletonMajorVersion, int singletonMinorVersion) -> bool { + return importMajorVersion != -1 && + (singletonMajorVersion > importMajorVersion || (singletonMajorVersion == importMajorVersion && singletonMinorVersion > importMinorVersion)); + }; + ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { if (cit->singleton && excludeBaseUrl(import->url, cit->fileName, baseUrl.toString())) { + if (shouldSkipSingleton(cit->majorVersion, cit->minorVersion)) + continue; QQmlImports::CompositeSingletonReference ref; ref.typeName = cit->typeName; ref.prefix = set.prefix; @@ -478,7 +487,9 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports:: } if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) { - module->walkCompositeSingletons([&resultList, &set](const QQmlType &singleton) { + module->walkCompositeSingletons([&resultList, &set, &shouldSkipSingleton](const QQmlType &singleton) { + if (shouldSkipSingleton(singleton.majorVersion(), singleton.minorVersion())) + return; QQmlImports::CompositeSingletonReference ref; ref.typeName = singleton.elementName(); ref.prefix = set.prefix; diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_0_9.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_0_9.qml new file mode 100644 index 0000000000..a63e2d121c --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_0_9.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 50 + height: 50 + + color: "yellow" + + Text { + anchors.centerIn: parent + text: "0.9" + + } +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_1_0.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_1_0.qml new file mode 100644 index 0000000000..d9cff582bb --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MyComponent_1_0.qml @@ -0,0 +1,15 @@ + +import QtQuick 2.0 + +Rectangle { + width: 50 + height: 50 + + color: "orange" + + Text { + anchors.centerIn: parent + text: "1.0" + + } +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MySettings_1_0.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MySettings_1_0.qml new file mode 100644 index 0000000000..63ad6ba1a5 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/MySettings_1_0.qml @@ -0,0 +1,7 @@ +pragma Singleton + +import QtQuick 2.0 + +Item { + property int baseWidth: 50 +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/qmldir b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/qmldir new file mode 100644 index 0000000000..57b8c55f81 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/imports/MyPlugin/qmldir @@ -0,0 +1,6 @@ +module MyPlugin + +MyComponent 0.9 MyComponent_0_9.qml + +MyComponent 1.0 MyComponent_1_0.qml +singleton MySettings 1.0 MySettings_1_0.qml diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.fail.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.fail.qml new file mode 100644 index 0000000000..0fbcec607a --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.fail.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 +import MyPlugin 0.9 + +Item { + width: MySettings.baseWidth + height: 100 + + MyComponent { + anchors.centerIn: parent + } +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.qml new file mode 100644 index 0000000000..53fc25699c --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.0.9.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 +import MyPlugin 0.9 + +Item { + width: 100 + height: 100 + + MyComponent { + anchors.centerIn: parent + } +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.1.0.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.1.0.qml new file mode 100644 index 0000000000..1f6244068b --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.1.0.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 +import MyPlugin 1.0 + +Item { + width: MySettings.baseWidth + height: 100 + + MyComponent { + anchors.centerIn: parent + } +} diff --git a/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.nonumber.qml b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.nonumber.qml new file mode 100644 index 0000000000..dea00c0163 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/QTBUG-77102/main.nonumber.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 +import "imports/MyPlugin" + +Item { + width: MySettings.baseWidth + height: 100 + + MyComponent { + anchors.centerIn: parent + } +} diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index a3cb68fdcb..a9657eba1d 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -45,6 +45,7 @@ private slots: void completeQmldirPaths_data(); void completeQmldirPaths(); void interceptQmldir(); + void singletonVersionResolution(); void cleanup(); }; @@ -212,6 +213,50 @@ void tst_QQmlImport::interceptQmldir() QVERIFY(!obj.isNull()); } +// QTBUG-77102 +void tst_QQmlImport::singletonVersionResolution() +{ + QQmlEngine engine; + engine.addImportPath(testFile("QTBUG-77102/imports")); + { + // Singleton with higher version is simply ignored when importing lower version of plugin + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.qml")); + QVERIFY(component.isReady()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + } + { + // but the singleton is not accessible + QQmlComponent component(&engine); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression {".*ReferenceError: MySettings is not defined$"} ); + component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.fail.qml")); + QVERIFY(component.isReady()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + } + { + // unless a version which is high enough is imported + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("QTBUG-77102/main.1.0.qml")); + QVERIFY(component.isReady()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + auto item = qobject_cast<QQuickItem*>(obj.get()); + QCOMPARE(item->width(), 50); + } + { + // or when there is no number because we are importing from a path + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("QTBUG-77102/main.nonumber.qml")); + QVERIFY(component.isReady()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + auto item = qobject_cast<QQuickItem*>(obj.get()); + QCOMPARE(item->width(), 50); + } +} + QTEST_MAIN(tst_QQmlImport) |