aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-03-03 12:05:18 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-03-05 07:20:08 +0100
commit464abaec05e0aa0ab699243412c50a5d5ac30742 (patch)
treee5866679c5ef631c141b1bc63db1c2dc73285cb2
parent3d37b0baf5bb40fd97b62ad6bd8f3c2b5eb5f016 (diff)
QML: Unify treatment of invalid revisions on registration
Revisions before QML_ADDED_IN_VERSION and revisions after QML_REMOVED_IN_VERSION should both result in anonymous types. This way, you can then derive from the type in question and expose the derived type in a different set of versions. Pick-to: 6.3 Change-Id: Ia59258047fc242c809c27525bb75fd2797fe5aab Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqml.cpp22
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp40
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h25
3 files changed, 77 insertions, 10 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index ff19bc4165..43cb973691 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -528,21 +528,23 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
uniqueRevisions(&revisions, type.version, added);
for (QTypeRevision revision : revisions) {
- if (revision < added)
- continue;
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
break;
- // When removed, we still add revisions, but anonymous ones
- if (removed.isValid() && !(revision < removed)) {
+
+ assignVersions(&typeRevision, revision, type.version);
+
+ // When removed or before added, we still add revisions, but anonymous ones
+ if (typeRevision.version < added
+ || (removed.isValid() && !(typeRevision.version < removed))) {
typeRevision.elementName = nullptr;
typeRevision.create = nullptr;
+ typeRevision.userdata = nullptr;
} else {
typeRevision.elementName = elementName;
typeRevision.create = creatable ? type.create : nullptr;
typeRevision.userdata = type.userdata;
}
- assignVersions(&typeRevision, revision, type.version);
typeRevision.customParser = type.customParserFactory();
const int id = qmlregister(TypeRegistration, &typeRevision);
if (type.qmlTypeIds)
@@ -589,13 +591,14 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
uniqueRevisions(&revisions, type.version, added);
for (QTypeRevision revision : qAsConst(revisions)) {
- if (revision < added)
- continue;
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
break;
- // When removed, we still add revisions, but anonymous ones
- if (removed.isValid() && !(revision < removed)) {
+ assignVersions(&revisionRegistration, revision, type.version);
+
+ // When removed or before added, we still add revisions, but anonymous ones
+ if (revisionRegistration.version < added
+ || (removed.isValid() && !(revisionRegistration.version < removed))) {
revisionRegistration.typeName = nullptr;
revisionRegistration.qObjectApi = nullptr;
} else {
@@ -603,7 +606,6 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
revisionRegistration.qObjectApi = type.qObjectApi;
}
- assignVersions(&revisionRegistration, revision, type.version);
const int id = qmlregister(SingletonRegistration, &revisionRegistration);
if (type.qmlTypeIds)
type.qmlTypeIds->append(id);
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
index 5619c2aa0f..3fc746552e 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
@@ -339,6 +339,46 @@ void tst_qmltyperegistrar::methodReturnType()
QVERIFY(qmltypesData.contains("type: \"QQmlComponent\""));
}
+void tst_qmltyperegistrar::addRemoveVersion_data()
+{
+ QTest::addColumn<QTypeRevision>("importVersion");
+ for (int i = 0; i < 20; ++i)
+ QTest::addRow("v1.%d.qml", i) << QTypeRevision::fromVersion(1, i);
+}
+
+void tst_qmltyperegistrar::addRemoveVersion()
+{
+ QFETCH(QTypeRevision, importVersion);
+
+ const bool creatable
+ = importVersion > QTypeRevision::fromVersion(1, 2)
+ && importVersion < QTypeRevision::fromVersion(1, 18);
+ const bool thingAccessible = importVersion > QTypeRevision::fromVersion(1, 3);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(QStringLiteral("import QmlTypeRegistrarTest %1.%2\n"
+ "Versioned {\n"
+ " property int thing: revisioned\n"
+ "}")
+ .arg(importVersion.majorVersion()).arg(importVersion.minorVersion()).toUtf8(),
+ QUrl(QTest::currentDataTag()));
+ if (!creatable) {
+ QVERIFY(c.isError());
+ return;
+ }
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ if (!thingAccessible) {
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(QStringLiteral("%1:3: ReferenceError: revisioned is not defined")
+ .arg(QTest::currentDataTag())));
+ }
+ QScopedPointer o(c.create());
+ QVERIFY(!o.isNull());
+ QCOMPARE(o->property("thing").toInt(), thingAccessible ? 24 : 0);
+}
+
#ifdef QT_QUICK_LIB
void tst_qmltyperegistrar::foreignRevisionedProperty()
{
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
index d57053a051..385d3b6666 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
@@ -469,6 +469,28 @@ public:
};
#endif
+class AddedInLateVersion : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Versioned)
+ QML_ADDED_IN_VERSION(1, 8)
+ Q_PROPERTY(int revisioned READ revisioned CONSTANT REVISION(1, 4))
+ Q_PROPERTY(int insane READ revisioned CONSTANT REVISION 17)
+public:
+ AddedInLateVersion(QObject *parent = nullptr) : QObject(parent) {}
+ int revisioned() const { return 24; }
+};
+
+class RemovedInEarlyVersion : public AddedInLateVersion
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Versioned)
+ QML_ADDED_IN_VERSION(1, 3)
+ QML_REMOVED_IN_VERSION(1, 8)
+public:
+ RemovedInEarlyVersion(QObject *parent = nullptr) : AddedInLateVersion(parent) {}
+};
+
class tst_qmltyperegistrar : public QObject
{
Q_OBJECT
@@ -508,6 +530,9 @@ private slots:
void foreignRevisionedProperty();
#endif
+ void addRemoveVersion_data();
+ void addRemoveVersion();
+
private:
QByteArray qmltypesData;
};