diff options
21 files changed, 232 insertions, 150 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 3f327e4821..c732818bd9 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -144,6 +144,54 @@ static QVector<QTypeRevision> availableRevisions(const QMetaObject *metaObject) return revisions; } +template<typename Registration> +void assignVersions(Registration *registration, QTypeRevision revision, + QTypeRevision defaultVersion) +{ + const quint8 majorVersion = revision.hasMajorVersion() ? revision.majorVersion() + : defaultVersion.majorVersion(); + registration->version = revision.hasMinorVersion() + ? QTypeRevision::fromVersion(majorVersion, revision.minorVersion()) + : QTypeRevision::fromMajorVersion(majorVersion); + registration->revision = revision; +} + +static QVector<QTypeRevision> prepareRevisions(const QMetaObject *metaObject, QTypeRevision added) +{ + auto revisions = availableRevisions(metaObject); + revisions.append(added); + return revisions; +} + +static void uniqueRevisions(QVector<QTypeRevision> *revisions, QTypeRevision defaultVersion, + QTypeRevision added) +{ + bool revisionsHaveMajorVersions = false; + for (QTypeRevision revision : QVector<QTypeRevision>(*revisions)) { // yes, copy + // allow any minor version for each explicitly specified past major one + if (revision.hasMajorVersion()) { + revisionsHaveMajorVersions = true; + if (revision.majorVersion() < defaultVersion.majorVersion()) + revisions->append(QTypeRevision::fromVersion(revision.majorVersion(), 254)); + } + } + + if (revisionsHaveMajorVersions) { + if (!added.hasMajorVersion()) { + // If added in unspecified major version, assume default one. + revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), + added.minorVersion())); + } else if (added.majorVersion() < defaultVersion.majorVersion()) { + // If added in past major version, add .0 of default version. + revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), 0)); + } + } + + std::sort(revisions->begin(), revisions->end()); + const auto it = std::unique(revisions->begin(), revisions->end()); + revisions->erase(it, revisions->end()); +} + /* This method is "over generalized" to allow us to (potentially) register more types of things in the future without adding exported symbols. @@ -191,18 +239,14 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) const QTypeRevision added = revisionClassInfo( type.classInfoMetaObject, "QML.AddedInVersion", - QTypeRevision::zero()); + QTypeRevision::fromMinorVersion(0)); const QTypeRevision removed = revisionClassInfo( type.classInfoMetaObject, "QML.RemovedInVersion"); - auto revisions = availableRevisions(type.metaObject); - revisions.append(qMax(added, QTypeRevision::zero())); + auto revisions = prepareRevisions(type.metaObject, added); if (type.attachedPropertiesMetaObject) revisions += availableRevisions(type.attachedPropertiesMetaObject); - - std::sort(revisions.begin(), revisions.end()); - const auto it = std::unique(revisions.begin(), revisions.end()); - revisions.erase(it, revisions.end()); + uniqueRevisions(&revisions, type.version, added); for (QTypeRevision revision : revisions) { if (revision < added) @@ -217,12 +261,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) revisionRegistration.create = creatable ? type.create : nullptr; } - // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.version = QTypeRevision::fromVersion(type.version.majorVersion(), - revision.minorVersion()); - revisionRegistration.revision = revision; + assignVersions(&revisionRegistration, revision, type.version); revisionRegistration.customParser = type.customParserFactory(); - qmlregister(TypeRegistration, &revisionRegistration); } break; @@ -248,16 +288,12 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) const QTypeRevision added = revisionClassInfo( type.classInfoMetaObject, "QML.AddedInVersion", - QTypeRevision::zero()); + QTypeRevision::fromMinorVersion(0)); const QTypeRevision removed = revisionClassInfo( type.classInfoMetaObject, "QML.RemovedInVersion"); - auto revisions = availableRevisions(type.instanceMetaObject); - revisions.append(qMax(added, QTypeRevision::zero())); - - std::sort(revisions.begin(), revisions.end()); - const auto it = std::unique(revisions.begin(), revisions.end()); - revisions.erase(it, revisions.end()); + auto revisions = prepareRevisions(type.instanceMetaObject, added); + uniqueRevisions(&revisions, type.version, added); for (QTypeRevision revision : qAsConst(revisions)) { if (revision < added) @@ -274,11 +310,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) revisionRegistration.generalizedQobjectApi = type.generalizedQobjectApi; } - // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.version = QTypeRevision::fromVersion(type.version.majorVersion(), - revision.minorVersion()); - revisionRegistration.revision = revision; - + assignVersions(&revisionRegistration, revision, type.version); qmlregister(SingletonRegistration, &revisionRegistration); } break; diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 2711d184aa..096bef7e4b 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -44,6 +44,7 @@ #include <QtCore/qbytearray.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qversionnumber.h> #define QML_VERSION 0x020000 #define QML_VERSION_STR "2.0" @@ -88,10 +89,16 @@ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor); #define QML_ADDED_IN_MINOR_VERSION(VERSION) \ - Q_CLASSINFO("QML.AddedInMinorVersion", #VERSION) + Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION)) + +#define QML_ADDED_IN_VERSION(MAJOR, MINOR) \ + Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(MAJOR, MINOR)) #define QML_REMOVED_IN_MINOR_VERSION(VERSION) \ - Q_CLASSINFO("QML.RemovedInMinorVersion", #VERSION) + Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(VERSION)) + +#define QML_REMOVED_IN_VERSION(MAJOR, MINOR) \ + Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(MAJOR, MINOR)) #define QML_ATTACHED(ATTACHED_TYPE) \ Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \ @@ -236,7 +243,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - QTypeRevision::fromEncodedVersion(metaObjectRevision) + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -314,7 +321,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - QTypeRevision::fromEncodedVersion(metaObjectRevision) + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -378,7 +385,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - QTypeRevision::fromEncodedVersion(metaObjectRevision) + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -409,7 +416,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) nullptr, nullptr, nullptr, - QTypeRevision::fromEncodedVersion(metaObjectRevision) + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -565,7 +572,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - QTypeRevision::fromEncodedVersion(metaObjectRevision) + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index c67e091518..7f30c4d713 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -2354,58 +2354,91 @@ static QQmlPropertyCache *propertyCacheForPotentialInlineComponentType(int t, co return (*iter)->rootPropertyCache().data(); } +/*! + * \internal + * + * Look up by type's baseMetaObject. + */ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - return QQmlMetaObject(type.baseMetaObject()); - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return QQmlMetaObject(composite); + + QQmlType type = QQmlMetaType::qmlType(t); + return QQmlMetaObject(type.baseMetaObject()); } +/*! + * \internal + * + * Look up by type's metaObject. + */ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - return QQmlMetaObject(type.metaObject()); - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return QQmlMetaObject(composite); + + QQmlType type = QQmlMetaType::qmlType(t); + return QQmlMetaObject(type.metaObject()); } +/*! + * \internal + * + * Look up by type's metaObject and version. + */ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - locker.unlock(); - return type.isValid() ? cache(type.metaObject()) : nullptr; - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + return type.isValid() ? cache(type.metaObject(), type.version()) : nullptr; +} + +/*! + * \internal + * + * Look up by type's baseMetaObject and unspecified/any version. + * TODO: Is this correct? Passing a plain QTypeRevision() rather than QTypeRevision::zero() or + * the actual type's version seems strange. The behavior has been in place for a while. + */ +QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) +{ + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + return type.isValid() ? cache(type.baseMetaObject(), QTypeRevision()) : nullptr; } +/*! + * \internal + * + * Look up by QQmlType and version. We only fall back to lookup by metaobject if the type + * has no revisiononed attributes here. Unspecified versions are interpreted as "any". + */ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, QTypeRevision version) { + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + if (!type.isValid()) + return nullptr; + + return type.containsRevisionedAttributes() + ? QQmlMetaType::propertyCache(type, version) + : cache(type.metaObject(), version); +} + +QQmlPropertyCache *QQmlEnginePrivate::findPropertyCacheInCompositeTypes(int t) const +{ Locker locker(this); auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - locker.unlock(); - - if (version.hasMinorVersion()) - return type.isValid() ? cache(type, version) : nullptr; - else - return type.isValid() ? cache(type.baseMetaObject()) : nullptr; - } + return (iter == m_compositeTypes.constEnd()) + ? nullptr + : propertyCacheForPotentialInlineComponentType(t, iter); } void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 23c8d9e07a..2c702367a4 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -228,7 +228,8 @@ public: QQmlMetaObject rawMetaObjectForType(int) const; QQmlMetaObject metaObjectForType(int) const; QQmlPropertyCache *propertyCacheForType(int); - QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version = QTypeRevision()); + QQmlPropertyCache *rawPropertyCacheForType(int); + QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version); void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId); @@ -282,6 +283,7 @@ private: void doDeleteInEngineThread(); void cleanupScarceResources(); + QQmlPropertyCache *findPropertyCacheInCompositeTypes(int t) const; }; /* diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index c053b14237..5ee27d4457 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1174,13 +1174,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, if (qmldirPluginCount == 0) return true; - if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { - if ((version.hasMajorVersion() && version.hasMinorVersion()) - ? !QQmlMetaType::isModule(uri, version) - : !QQmlMetaType::isAnyModule(uri)) { - QQmlMetaType::qmlRegisterModuleTypes(uri, version); - } - } else { + if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { // First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue // searching static plugins that has correct metadata uri. Note that since we only know the uri // for a static plugin, and not the filename, we cannot know which static plugin belongs to which diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 429f9c5b09..c5c767df43 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -265,35 +265,32 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo, } } -void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, QTypeRevision version, - void (*registerFunction)()) +void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)()) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, version); QQmlMetaTypeDataPtr data; - if (data->moduleTypeRegistrationFunctions.contains(versionedUri)) - qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), version.majorVersion()); + if (data->moduleTypeRegistrationFunctions.contains(uri)) + qFatal("Cannot add multiple registrations for %s", qPrintable(uri)); else - data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction); + data->moduleTypeRegistrationFunctions.insert(uri, registerFunction); } -void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, QTypeRevision version) +void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, version); QQmlMetaTypeDataPtr data; if (!data.isValid()) return; // shutdown/deletion race. Not a problem. - if (!data->moduleTypeRegistrationFunctions.contains(versionedUri)) - qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), version.majorVersion()); + if (!data->moduleTypeRegistrationFunctions.contains(uri)) + qFatal("Cannot remove multiple registrations for %s", qPrintable(uri)); else - data->moduleTypeRegistrationFunctions.remove(versionedUri); + data->moduleTypeRegistrationFunctions.remove(uri); } -bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, QTypeRevision version) +bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri) { QQmlMetaTypeDataPtr data; - return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, version)); + return data->registerModuleTypes(uri); } void QQmlMetaType::clearTypeRegistrations() @@ -713,7 +710,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat iface->registerTypes(moduleId); } - data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, version)); + data->registerModuleTypes(uri); if (!failures.isEmpty()) { if (errors) { diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index e98a87e6a9..c68bf0c551 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -198,11 +198,10 @@ public: static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd); - static void qmlInsertModuleRegistration(const QString &uri, QTypeRevision version, - void (*registerFunction)()); - static void qmlRemoveModuleRegistration(const QString &uri, QTypeRevision version); + static void qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)()); + static void qmlRemoveModuleRegistration(const QString &uri); - static bool qmlRegisterModuleTypes(const QString &uri, QTypeRevision version); + static bool qmlRegisterModuleTypes(const QString &uri); }; Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE); diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index 51d944e771..a34a0c1ae4 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -78,9 +78,9 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv) priv->release(); } -bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri &versionedUri) +bool QQmlMetaTypeData::registerModuleTypes(const QString &uri) { - auto function = moduleTypeRegistrationFunctions.constFind(versionedUri); + auto function = moduleTypeRegistrationFunctions.constFind(uri); if (function != moduleTypeRegistrationFunctions.constEnd()) { (*function)(); return true; @@ -138,10 +138,15 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe const QMetaObject *metaObject = type.metaObject(); + const QTypeRevision combinedVersion = version.hasMajorVersion() + ? version + : (version.hasMinorVersion() + ? QTypeRevision::fromVersion(type.version().majorVersion(), + version.minorVersion()) + : type.version()); + while (metaObject) { - QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), - QTypeRevision::fromVersion(type.version().majorVersion(), - version.minorVersion())); + QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), combinedVersion); if (t.isValid()) { maxMinorVersion = qMax(maxMinorVersion, t.version().minorVersion()); types << t; @@ -152,13 +157,14 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe metaObject = metaObject->superClass(); } - const QTypeRevision maxVersion = QTypeRevision::fromVersion(version.majorVersion(), maxMinorVersion); + const QTypeRevision maxVersion = QTypeRevision::fromVersion(combinedVersion.majorVersion(), + maxMinorVersion); if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), maxVersion)) { setPropertyCacheForVersion(type.index(), maxVersion, pc); return pc; } - QQmlPropertyCache *raw = propertyCache(type.metaObject(), version); + QQmlPropertyCache *raw = propertyCache(type.metaObject(), combinedVersion); bool hasCopied = false; @@ -230,7 +236,7 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe if (hasCopied) raw->release(); - if (version.minorVersion() != maxMinorVersion) + if (version != maxVersion) setPropertyCacheForVersion(type.index(), maxVersion, raw); return raw; diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index 7392b8573d..26fc566653 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -99,8 +99,8 @@ struct QQmlMetaTypeData typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules; TypeModules uriToModule; - QHash<VersionedUri, void (*)()> moduleTypeRegistrationFunctions; - bool registerModuleTypes(const VersionedUri &versionedUri); + QHash<QString, void (*)()> moduleTypeRegistrationFunctions; + bool registerModuleTypes(const QString &uri); QBitArray objects; QBitArray interfaces; diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp index 01f93b85fe..422a5c0551 100644 --- a/src/qml/qml/qqmlmoduleregistration.cpp +++ b/src/qml/qml/qqmlmoduleregistration.cpp @@ -46,23 +46,26 @@ QT_BEGIN_NAMESPACE struct QQmlModuleRegistrationPrivate { const QString uri; - const QTypeRevision version; }; +QQmlModuleRegistration::QQmlModuleRegistration(const char *uri, void (*registerFunction)()) : + d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri) }) +{ + QQmlMetaType::qmlInsertModuleRegistration(d->uri, registerFunction); +} + +#if QT_DEPRECATED_SINCE(6, 0) QQmlModuleRegistration::QQmlModuleRegistration( - const char *uri, int majorVersion, - void (*registerFunction)()) : - d(new QQmlModuleRegistrationPrivate { - QString::fromUtf8(uri), - QTypeRevision::fromMajorVersion(majorVersion) - }) + const char *uri, int majorVersion, void (*registerFunction)()) : + QQmlModuleRegistration(uri, registerFunction) { - QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->version, registerFunction); + Q_UNUSED(majorVersion); } +#endif QQmlModuleRegistration::~QQmlModuleRegistration() { - QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->version); + QQmlMetaType::qmlRemoveModuleRegistration(d->uri); delete d; } diff --git a/src/qml/qml/qqmlmoduleregistration.h b/src/qml/qml/qqmlmoduleregistration.h index 6f553a2823..3db535faa0 100644 --- a/src/qml/qml/qqmlmoduleregistration.h +++ b/src/qml/qml/qqmlmoduleregistration.h @@ -49,9 +49,14 @@ class Q_QML_EXPORT QQmlModuleRegistration { Q_DISABLE_COPY_MOVE(QQmlModuleRegistration) public: - QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)()); + QQmlModuleRegistration(const char *uri, void (*registerFunction)()); ~QQmlModuleRegistration(); +#if QT_DEPRECATED_SINCE(6, 0) + QT_DEPRECATED_X("Use registration without major version") + QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)()); +#endif + private: QQmlModuleRegistrationPrivate *d = nullptr; }; diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index 5e83deff18..f132fb2d78 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -119,13 +119,10 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating { if (instantiatingProperty) { if (instantiatingProperty->isQObject()) { - // If the typeVersion is invalid here, we want to match any version we can find. - // 254.254 is the largest version QTypeRevision can hold. - return enginePrivate->rawPropertyCacheForType( - instantiatingProperty->propType(), - instantiatingProperty->typeVersion().isValid() - ? instantiatingProperty->typeVersion() - : QTypeRevision::fromVersion(254, 254)); + // rawPropertyCacheForType assumes a given unspecified version means "any version". + // There is another overload that takes no version, which we shall not use here. + return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), + instantiatingProperty->typeVersion()); } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) { return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); } diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 01bf1bede7..001b19a8e5 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -747,9 +747,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope // We want to use the raw metaObject here as the raw metaobject is the // actual property type before we applied any extensions that might // effect the properties on the type, but don't effect assignability - // Using -1 for the minor version ensures that we get the raw metaObject. - QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType, - QTypeRevision()); + // Not passing a version ensures that we get the raw metaObject. + QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType); if (propertyMetaObject) { // Will be true if the assigned type inherits propertyMetaObject diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 06d5c47b53..d7a549e380 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -818,8 +818,12 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (!pd || !pd->isQObject()) continue; - QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType( - pd->propType(), pd->typeVersion()); + // If the version is given, use it and look up by QQmlType. + // Otherwise, make sure we look up by metaobject. + // TODO: Is this correct? + QQmlPropertyCache *pc = pd->typeVersion().hasMinorVersion() + ? enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeVersion()) + : enginePrivate->rawPropertyCacheForType(pd->propType()); const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr; while (mo) { if (mo == &QQmlComponent::staticMetaObject) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 01f70b1703..afad15331c 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -606,7 +606,7 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo // Is this a module? if (QQmlMetaType::isAnyModule(import->uri) || (qmldirResult != QQmlImports::QmldirInterceptedToRemote - && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->version))) { + && QQmlMetaType::qmlRegisterModuleTypes(import->uri))) { if (!m_importCache.addLibraryImport( importDatabase, import->uri, import->qualifier, import->version, QString(), QString(), false, errors)) diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index c22f349ea0..697f96959f 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -368,8 +368,8 @@ int main(int argc, char **argv) qPrintable(module), qPrintable(majorVersion), qPrintable(parser.value(minorVersionOption))); fprintf(output, "\n}\n"); - fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s, %s);\n", - qPrintable(module), qPrintable(majorVersion), qPrintable(functionName)); + fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s);\n", + qPrintable(module), qPrintable(functionName)); if (!parser.isSet(pluginTypesOption)) return EXIT_SUCCESS; diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index aceab7c2b1..f1ec700c50 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -61,7 +61,7 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject> void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, - bool topLevel) + bool topLevel, QTypeRevision defaultRevision) { const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { @@ -72,7 +72,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, if (name == QLatin1String("DefaultProperty")) { if (defaultProp.isEmpty()) defaultProp = value; - } else if (name == QLatin1String("QML.AddedInMinorVersion")) { + } else if (name == QLatin1String("QML.AddedInVersion")) { const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt()); if (topLevel) { addedInRevision = revision; @@ -91,16 +91,16 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, elementName = classDef->value(QLatin1String("className")).toString(); else if (value != QLatin1String("anonymous")) elementName = value; - } else if (name == QLatin1String("QML.RemovedInMinorVersion")) { + } else if (name == QLatin1String("QML.RemovedInVersion")) { removedInRevision = QTypeRevision::fromEncodedVersion(value.toInt()); } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { attachedType = value; if (const QJsonObject *other = findType(types, attachedType)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); else if (const QJsonObject *other = findType(foreign, attachedType)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); } else if (name == QLatin1String("QML.Singleton")) { if (value == QLatin1String("true")) isSingleton = true; @@ -143,15 +143,17 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, superClass = superName; if (const QJsonObject *other = findType(types, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); else if (const QJsonObject *other = findType(foreign, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); } } if (!addedInRevision.isValid()) { - revisions.append(QTypeRevision::zero()); - addedInRevision = QTypeRevision::zero(); + revisions.append(defaultRevision); + addedInRevision = defaultRevision; + } else if (addedInRevision < defaultRevision) { + revisions.append(defaultRevision); } std::sort(revisions.begin(), revisions.end()); diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 8222016faf..6f391ba45c 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -51,7 +51,7 @@ struct QmlTypesClassDescription bool isBuiltin = false; void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, - const QVector<QJsonObject> &foreign, bool topLevel); + const QVector<QJsonObject> &foreign, bool topLevel, QTypeRevision defaultRevision); static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name); }; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 8991ee42b6..d34740eaa0 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -63,6 +63,11 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle QStringList exports; QStringList metaObjects; + if (collector.isBuiltin) { + exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); + metaObjects.append(QString::number(QTypeRevision::fromVersion(1, 0).toEncodedVersion<quint16>())); + } + for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) { const QTypeRevision revision = *it; if (revision < collector.addedInRevision) @@ -70,14 +75,11 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle if (collector.removedInRevision.isValid() && !(revision < collector.removedInRevision)) break; - if (collector.isBuiltin) { - exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); - metaObjects.append(QLatin1String("0")); - } - exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4") - .arg(m_module).arg(collector.elementName) - .arg(m_version.majorVersion()).arg(revision.minorVersion()))); + .arg(m_module).arg(collector.elementName) + .arg(revision.hasMajorVersion() ? revision.majorVersion() + : m_version.majorVersion()) + .arg(revision.minorVersion()))); metaObjects.append(QString::number(revision.toEncodedVersion<quint16>())); } @@ -244,7 +246,7 @@ void QmlTypesCreator::writeComponents() m_qml.writeStartObject(componentElement); QmlTypesClassDescription collector; - collector.collect(&component, m_ownTypes, m_foreignTypes, true); + collector.collect(&component, m_ownTypes, m_foreignTypes, true, m_version); writeClassProperties(collector); diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes index 3a33590139..ce003fc535 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes @@ -15,9 +15,9 @@ Module { "dumper.Versions/Versions 1.0", "dumper.Versions/Versions 1.1" ] - exportMetaObjectRevisions: [0, 1] + exportMetaObjectRevisions: [0, 65281] Property { name: "foo"; type: "int" } - Property { name: "bar"; revision: 1; type: "int" } - Property { name: "baz"; revision: 2; type: "int" } + Property { name: "bar"; revision: 65281; type: "int" } + Property { name: "baz"; revision: 65282; type: "int" } } } diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index 25a448a97f..2e040eec18 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -168,7 +168,7 @@ void tst_qqmlpropertycache::revisionedProperties() QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion(new QQmlPropertyCache(metaObject), QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlRefPointer<QQmlPropertyCache> cacheWithVersion( - new QQmlPropertyCache(metaObject, QTypeRevision::fromEncodedVersion(1)), + new QQmlPropertyCache(metaObject, QTypeRevision::fromMinorVersion(1)), QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; |