diff options
73 files changed, 922 insertions, 847 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 1480df2817..b9841a76b4 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -57,6 +57,7 @@ #include <QtCore/qvector.h> #include <QtCore/qstringlist.h> #include <QtCore/qhash.h> +#include <QtCore/qversionnumber.h> #if QT_CONFIG(temporaryfile) #include <QtCore/qsavefile.h> @@ -76,7 +77,7 @@ QT_BEGIN_NAMESPACE // Also change the comment behind the number to describe the latest change. This has the added // benefit that if another patch changes the version too, it will result in a merge conflict, and // not get removed silently. -#define QV4_DATA_STRUCTURE_VERSION 0x28// support inline components +#define QV4_DATA_STRUCTURE_VERSION 0x29 // Change version format class QIODevice; class QQmlTypeNameCache; @@ -857,14 +858,16 @@ struct Import quint32_le uriIndex; quint32_le qualifierIndex; - qint32_le majorVersion; - qint32_le minorVersion; - Location location; + QTypeRevision version; + quint16_le reserved; - Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; } + Import() + { + type = 0; uriIndex = 0; qualifierIndex = 0; version = QTypeRevision::zero(); reserved = 0; + } }; -static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +static_assert(sizeof(Import) == 20, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct QmlUnit { diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 811f88cb73..be02a08f82 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -374,11 +374,7 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString & QV4::CompiledData::Import *import = engine->pool()->New<QV4::CompiledData::Import>(); import->type = QV4::CompiledData::Import::ImportLibrary; import->uriIndex = jsGenerator->registerString(uri); - int vmaj; - int vmin; - IRBuilder::extractVersion(QStringRef(&version), &vmaj, &vmin); - import->majorVersion = vmaj; - import->minorVersion = vmin; + import->version = IRBuilder::extractVersion(QStringRef(&version)); import->qualifierIndex = jsGenerator->registerString(module); import->location.line = lineNumber; import->location.column = column; @@ -715,16 +711,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiImport *node) } if (node->version) { - import->majorVersion = node->version->majorVersion; - import->minorVersion = node->version->minorVersion; + import->version = node->version->version; } else if (import->type == QV4::CompiledData::Import::ImportLibrary) { recordError(node->importIdToken, QCoreApplication::translate("QQmlParser","Library import requires a version")); return false; } else { // For backward compatibility in how the imports are loaded we - // must otherwise initialize the major and minor version to -1. - import->majorVersion = -1; - import->minorVersion = -1; + // must otherwise initialize the major and minor version to invalid. + import->version = QTypeRevision(); } import->location.line = node->importToken.startLine; @@ -1010,22 +1004,15 @@ QStringRef IRBuilder::asStringRef(QQmlJS::AST::Node *node) return textRefAt(node->firstSourceLocation(), node->lastSourceLocation()); } -void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min) +QTypeRevision IRBuilder::extractVersion(const QStringRef &string) { - *maj = -1; *min = -1; + if (string.isEmpty()) + return QTypeRevision(); - if (!string.isEmpty()) { - - int dot = string.indexOf(QLatin1Char('.')); - - if (dot < 0) { - *maj = string.toInt(); - *min = 0; - } else { - *maj = string.left(dot).toInt(); - *min = string.mid(dot + 1).toInt(); - } - } + const int dot = string.indexOf(QLatin1Char('.')); + return (dot < 0) + ? QTypeRevision::fromVersion(string.toInt(), 0) + : QTypeRevision::fromVersion(string.left(dot).toInt(), string.mid(dot + 1).toInt()); } QStringRef IRBuilder::textRefAt(const QQmlJS::AST::SourceLocation &first, const QQmlJS::AST::SourceLocation &last) const diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index d4f2eb8dd4..ea27e65f86 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -485,7 +485,7 @@ public: static QString asString(QQmlJS::AST::UiQualifiedId *node); QStringRef asStringRef(QQmlJS::AST::Node *node); - static void extractVersion(const QStringRef &string, int *maj, int *min); + static QTypeRevision extractVersion(const QStringRef &string); QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const { return QStringRef(&sourceCode, loc.offset, loc.length); } QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first, diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index 7866a5bdda..37376a1485 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -110,8 +110,8 @@ public: QString uiLanguage; // These methods may be called from the QML loader thread - inline QQmlPropertyCache *cache(QObject *obj, int minorVersion = -1); - inline QQmlPropertyCache *cache(const QMetaObject *, int minorVersion = -1); + inline QQmlPropertyCache *cache(QObject *obj, QTypeRevision version = QTypeRevision()); + inline QQmlPropertyCache *cache(const QMetaObject *obj, QTypeRevision version = QTypeRevision()); }; QJSEnginePrivate::Locker::Locker(const QJSEngine *e) @@ -161,14 +161,14 @@ and deleted before the loader thread has a chance to use or reference it. This can't currently happen as the cache holds a reference to the QQmlPropertyCache until the QQmlEngine is destroyed. */ -QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, int minorVersion) +QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, QTypeRevision version) { if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) return nullptr; Locker locker(this); const QMetaObject *mo = obj->metaObject(); - return QQmlMetaType::propertyCache(mo, minorVersion); + return QQmlMetaType::propertyCache(mo, version); } /*! @@ -180,12 +180,12 @@ exist for the lifetime of the QQmlEngine. The returned cache is not referenced, so if it is to be stored, call addref(). */ -QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, QTypeRevision version) { Q_ASSERT(metaObject); Locker locker(this); - return QQmlMetaType::propertyCache(metaObject, minorVersion); + return QQmlMetaType::propertyCache(metaObject, version); } diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index fa4a1f1ce4..962b23fad6 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -817,7 +817,7 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQm if (typePropertyCache) { return typePropertyCache; } else if (type.isValid()) { - typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), minorVersion); + typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), version); return typePropertyCache; } else { Q_ASSERT(compilationUnit); diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 8cad18a3dc..c080978a87 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -326,17 +326,15 @@ private: struct ResolvedTypeReference { ResolvedTypeReference() - : majorVersion(0) - , minorVersion(0) - , isFullyDynamicType(false) + : version(QTypeRevision::zero()) + , isFullyDynamicType(false) {} QQmlType type; QQmlRefPointer<QQmlPropertyCache> typePropertyCache; QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; - int majorVersion; - int minorVersion; + QTypeRevision version; // Types such as QQmlPropertyMap can add properties dynamically at run-time and // therefore cannot have a property cache installed when instantiated. bool isFullyDynamicType; diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 48a994cd33..a7c95eee2d 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -57,6 +57,7 @@ #include <private/qqmljsmemorypool_p.h> #include <QtCore/qstring.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -643,7 +644,10 @@ class QML_PARSER_EXPORT UiVersionSpecifier : public Node public: QQMLJS_DECLARE_AST_NODE(UiVersionSpecifier) - UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum) { kind = K; } + UiVersionSpecifier(int majorum, int minorum) : version(QTypeRevision::fromVersion(majorum, minorum)) + { + kind = K; + } void accept0(Visitor *visitor) override; @@ -655,8 +659,7 @@ public: } // attributes: - int majorVersion; - int minorVersion; + QTypeRevision version; SourceLocation majorToken; SourceLocation minorToken; }; diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index a33936647f..3f327e4821 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -61,19 +61,20 @@ void qmlClearTypeRegistrations() // Declared in qqml.h //From qqml.h bool qmlProtectModule(const char *uri, int majVersion) { - return QQmlMetaType::protectModule(QString::fromUtf8(uri), majVersion); + return QQmlMetaType::protectModule(QString::fromUtf8(uri), + QTypeRevision::fromMajorVersion(majVersion)); } //From qqml.h void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor) { - QQmlMetaType::registerModule(uri, versionMajor, versionMinor); + QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor)); } //From qqml.h int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - return QQmlMetaType::typeId(uri, versionMajor, versionMinor, qmlName); + return QQmlMetaType::typeId(uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName); } // From qqmlprivate.h @@ -103,9 +104,20 @@ QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJS return m_object; }; -static QVector<int> availableRevisions(const QMetaObject *metaObject) +// We cannot generally assume that the unspecified version is smaller than any specified one. +// Therefore, this operator< should not move to QtCore. +static bool operator<(QTypeRevision lhs, QTypeRevision rhs) { - QVector<int> revisions; + return lhs.hasMajorVersion() + ? (rhs.hasMajorVersion() + && lhs.toEncodedVersion<quint16>() < rhs.toEncodedVersion<quint16>()) + : (rhs.hasMajorVersion() + || lhs.minorVersion() < rhs.minorVersion()); +} + +static QVector<QTypeRevision> availableRevisions(const QMetaObject *metaObject) +{ + QVector<QTypeRevision> revisions; if (!metaObject) return revisions; const int propertyOffset = metaObject->propertyOffset(); @@ -114,7 +126,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject) propertyIndex < propertyEnd; ++propertyIndex) { const QMetaProperty property = metaObject->property(propertyIndex); if (int revision = property.revision()) - revisions.append(revision); + revisions.append(QTypeRevision::fromEncodedVersion(revision)); } const int methodOffset = metaObject->methodOffset(); const int methodCount = metaObject->methodCount(); @@ -122,7 +134,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject) methodIndex < methodEnd; ++methodIndex) { const QMetaMethod method = metaObject->method(methodIndex); if (int revision = method.revision()) - revisions.append(revision); + revisions.append(QTypeRevision::fromEncodedVersion(revision)); } // Need to also check parent meta objects, as their revisions are inherited. @@ -163,8 +175,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) nullptr, noCreateReason, type.uri, - type.versionMajor, - -1, + type.version, nullptr, type.metaObject, type.attachedPropertiesFunction, @@ -175,14 +186,17 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) type.extensionObjectCreate, type.extensionMetaObject, nullptr, - -1 + QTypeRevision() }; - const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0); - const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1); + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::zero()); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); auto revisions = availableRevisions(type.metaObject); - revisions.append(qMax(added, 0)); + revisions.append(qMax(added, QTypeRevision::zero())); if (type.attachedPropertiesMetaObject) revisions += availableRevisions(type.attachedPropertiesMetaObject); @@ -190,13 +204,12 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) const auto it = std::unique(revisions.begin(), revisions.end()); revisions.erase(it, revisions.end()); - const bool typeWasRemoved = removed >= added; - for (int revision : revisions) { + for (QTypeRevision revision : revisions) { if (revision < added) continue; // When removed, we still add revisions, but anonymous ones - if (typeWasRemoved && revision >= removed) { + if (removed.isValid() && !(revision < removed)) { revisionRegistration.elementName = nullptr; revisionRegistration.create = nullptr; } else { @@ -205,7 +218,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) } // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.versionMinor = revision; + revisionRegistration.version = QTypeRevision::fromVersion(type.version.majorVersion(), + revision.minorVersion()); revisionRegistration.revision = revision; revisionRegistration.customParser = type.customParserFactory(); @@ -220,36 +234,37 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) RegisterSingletonType revisionRegistration = { QmlCurrentSingletonTypeRegistrationVersion, type.uri, - type.versionMajor, - -1, + type.version, elementName, type.scriptApi, nullptr, type.instanceMetaObject, type.typeId, - -1, + QTypeRevision(), type.generalizedQobjectApi }; - const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0); - const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1); + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::zero()); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); auto revisions = availableRevisions(type.instanceMetaObject); - revisions.append(qMax(added, 0)); + 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()); - const bool typeWasRemoved = removed >= added; - for (int revision : qAsConst(revisions)) { + for (QTypeRevision revision : qAsConst(revisions)) { if (revision < added) continue; // When removed, we still add revisions, but anonymous ones - if (typeWasRemoved && revision >= removed) { + if (removed.isValid() && !(revision < removed)) { revisionRegistration.typeName = nullptr; revisionRegistration.scriptApi = nullptr; revisionRegistration.generalizedQobjectApi = nullptr; @@ -260,7 +275,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) } // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.versionMinor = revision; + revisionRegistration.version = QTypeRevision::fromVersion(type.version.majorVersion(), + revision.minorVersion()); revisionRegistration.revision = revision; qmlregister(SingletonRegistration, &revisionRegistration); diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index ae3893dd73..2711d184aa 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -150,7 +150,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor) nullptr, QString(), - uri, versionMajor, 0, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -162,7 +162,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor) nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -192,7 +192,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -204,7 +204,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -224,7 +224,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -236,7 +236,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromEncodedVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -263,7 +263,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -275,7 +275,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -302,7 +302,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -314,7 +314,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - metaObjectRevision + QTypeRevision::fromEncodedVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -335,7 +335,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -347,7 +347,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -366,7 +366,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -378,7 +378,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromEncodedVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -397,7 +397,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -409,7 +409,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromEncodedVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -430,7 +430,7 @@ int qmlRegisterExtendedType() nullptr, QString(), - nullptr, 0, 0, nullptr, &T::staticMetaObject, + nullptr, QTypeRevision::zero(), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -442,7 +442,7 @@ int qmlRegisterExtendedType() QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -469,7 +469,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -481,7 +481,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -521,7 +521,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -533,7 +533,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -553,7 +553,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -565,7 +565,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - metaObjectRevision + QTypeRevision::fromEncodedVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -592,7 +592,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -604,7 +604,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version QQmlPrivate::createParent<E>, &E::staticMetaObject, parser, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -667,9 +667,9 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { 0, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - callback, nullptr, nullptr, 0, 0, {} + callback, nullptr, nullptr, 0, QTypeRevision::zero(), {} }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -685,9 +685,10 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { QmlCurrentSingletonTypeRegistrationVersion, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), + QTypeRevision::zero(), callback }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -704,9 +705,10 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { QmlCurrentSingletonTypeRegistrationVersion, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), + QTypeRevision::zero(), callback }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -732,8 +734,7 @@ inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versio QQmlPrivate::RegisterCompositeSingletonType type = { url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; @@ -751,8 +752,7 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i QQmlPrivate::RegisterCompositeType type = { url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 915dc5b242..b16bc929c9 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -118,7 +118,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject, QQmlAttachedPropertiesFunc(), nullptr, @@ -130,7 +130,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -2244,7 +2244,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths) bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors) { Q_D(QQmlEngine); - return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), -1, errors); + return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), QTypeRevision(), errors); } #endif @@ -2402,7 +2402,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) } } -QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion) +QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, QTypeRevision version) { Locker locker(this); auto iter = m_compositeTypes.constFind(t); @@ -2412,8 +2412,8 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVe QQmlType type = QQmlMetaType::qmlType(t); locker.unlock(); - if (minorVersion >= 0) - return type.isValid() ? cache(type, minorVersion) : nullptr; + if (version.hasMinorVersion()) + return type.isValid() ? cache(type, version) : nullptr; else return type.isValid() ? cache(type.baseMetaObject()) : nullptr; } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 33fa800ff4..23c8d9e07a 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -216,7 +216,7 @@ public: QString offlineStorageDatabaseDirectory() const; // These methods may be called from the loader thread - inline QQmlPropertyCache *cache(const QQmlType &, int); + inline QQmlPropertyCache *cache(const QQmlType &, QTypeRevision version); using QJSEnginePrivate::cache; // These methods may be called from the loader thread @@ -228,7 +228,7 @@ public: QQmlMetaObject rawMetaObjectForType(int) const; QQmlMetaObject metaObjectForType(int) const; QQmlPropertyCache *propertyCacheForType(int); - QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1); + QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version = QTypeRevision()); void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId); @@ -380,15 +380,15 @@ Returns a QQmlPropertyCache for \a type with \a minorVersion. The returned cache is not referenced, so if it is to be stored, call addref(). */ -QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, QTypeRevision version) { Q_ASSERT(type.isValid()); - if (minorVersion == -1 || !type.containsRevisionedAttributes()) - return cache(type.metaObject(), minorVersion); + if (!version.hasMinorVersion() || !type.containsRevisionedAttributes()) + return cache(type.metaObject(), version); Locker locker(this); - return QQmlMetaType::propertyCache(type, minorVersion); + return QQmlMetaType::propertyCache(type, version); } QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 80eafdf146..c053b14237 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -213,12 +213,12 @@ public: QQmlImportNamespace *importNamespace(const QString &prefix) const; bool addLibraryImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, + QTypeRevision version, const QString &qmldirIdentifier, + const QString &qmldirUrl, bool incomplete, QQmlImportDatabase *database, QList<QQmlError> *errors); - bool addFileImport(const QString &uri, const QString &prefix, - int vmaj, int vmin, + bool addFileImport(const QString &uri, const QString &prefix, QTypeRevision version, bool isImplicitImport, bool incomplete, QQmlImportDatabase *database, QList<QQmlError> *errors); @@ -227,7 +227,7 @@ public: QQmlImportDatabase *database, QList<QQmlError> *errors); - bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor, + bool resolveType(const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected = nullptr); @@ -247,14 +247,13 @@ public: QQmlTypeLoader *typeLoader; static QQmlImports::LocalQmldirResult locateLocalQmldir( - const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, QString *outQmldirFilePath, QString *outUrl); - static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin, - QList<QQmlError> *errors); + static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, + QTypeRevision version, QList<QQmlError> *errors); - bool importExtension(const QString &absoluteFilePath, const QString &uri, - int vmaj, int vmin, + bool importExtension(const QString &absoluteFilePath, const QString &uri, QTypeRevision version, QQmlImportDatabase *database, const QQmlTypeLoaderQmldirContent &qmldir, QList<QQmlError> *errors); @@ -264,10 +263,10 @@ public: QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database); - QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, - const QString &uri, const QString &url, - int vmaj, int vmin, QV4::CompiledData::Import::ImportType type, - QList<QQmlError> *errors, bool lowPrecedence = false); + QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri, + const QString &url, QTypeRevision version, + QV4::CompiledData::Import::ImportType type, + QList<QQmlError> *errors, bool lowPrecedence = false); bool populatePluginPairVector(QVector<StaticPluginPair> &result, const QString &uri, const QStringList &versionUris, const QString &qmldirPath, QList<QQmlError> *errors); @@ -344,9 +343,9 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); - QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion); + QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version); if (module) { - cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->minversion)); + cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->version)); } } @@ -360,10 +359,10 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); - QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion); + QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version); if (module) { QQmlImportRef &typeimport = cache->m_namedImports[set.prefix]; - typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion)); + typeimport.modules.append(QQmlTypeModuleVersion(module, import->version)); } } } @@ -395,36 +394,35 @@ 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)); + const QTypeRevision importVersion = import->version; + auto shouldSkipSingleton = [importVersion](QTypeRevision singletonVersion) -> bool { + return importVersion.hasMajorVersion() && + (singletonVersion.majorVersion() > importVersion.majorVersion() + || (singletonVersion.majorVersion() == importVersion.majorVersion() + && singletonVersion.minorVersion() > importVersion.minorVersion())); }; 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)) + if (shouldSkipSingleton(cit->version)) continue; QQmlImports::CompositeSingletonReference ref; ref.typeName = cit->typeName; ref.prefix = set.prefix; - ref.majorVersion = cit->majorVersion; - ref.minorVersion = cit->minorVersion; + ref.version = cit->version; resultList.append(ref); } } - if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) { + if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version)) { module->walkCompositeSingletons([&resultList, &set, &shouldSkipSingleton](const QQmlType &singleton) { - if (shouldSkipSingleton(singleton.majorVersion(), singleton.minorVersion())) + if (shouldSkipSingleton(singleton.version())) return; QQmlImports::CompositeSingletonReference ref; ref.typeName = singleton.elementName(); ref.prefix = set.prefix; - ref.majorVersion = singleton.majorVersion(); - ref.minorVersion = singleton.minorVersion(); + ref.version = singleton.version(); resultList.append(ref); }); } @@ -461,9 +459,9 @@ QList<QQmlImports::CompositeSingletonReference> QQmlImports::resolvedCompositeSi if (lhs.typeName != rhs.typeName) return lhs.typeName < rhs.typeName; - return lhs.majorVersion != rhs.majorVersion - ? lhs.majorVersion < rhs.majorVersion - : lhs.minorVersion < rhs.minorVersion; + return lhs.version.majorVersion() != rhs.version.majorVersion() + ? lhs.version.majorVersion() < rhs.version.majorVersion() + : lhs.version.minorVersion() < rhs.version.minorVersion(); }); return compositeSingletons; @@ -532,7 +530,8 @@ static QString joinStringRefs(const QVector<QStringRef> &refs, const QChar &sep) - base/QtQml.2/Models/qmldir - base/QtQml/Models/qmldir */ -QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin) +QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, + QTypeRevision version) { const QVector<QStringRef> parts = uri.splitRef(Dot, QString::SkipEmptyParts); @@ -540,8 +539,8 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi // fully & partially versioned parts + 1 unversioned for each base path qmlDirPathsPaths.reserve(basePaths.count() * (2 * parts.count() + 1)); - for (int version = FullyVersioned; version <= Unversioned; ++version) { - const QString ver = versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version)); + for (int versionMode = FullyVersioned; versionMode <= Unversioned; ++versionMode) { + const QString ver = versionString(version, QQmlImports::ImportVersion(versionMode)); for (const QString &path : basePaths) { QString dir = path; @@ -551,7 +550,7 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi // append to the end qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver + Slash_qmldir; - if (version != Unversioned) { + if (versionMode != Unversioned) { // insert in the middle for (int index = parts.count() - 2; index >= 0; --index) { qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash) @@ -565,14 +564,14 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi return qmlDirPathsPaths; } -QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) +QString QQmlImports::versionString(QTypeRevision version, ImportVersion versionMode) { - if (version == QQmlImports::FullyVersioned) { + if (versionMode == QQmlImports::FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString::asprintf(".%d.%d", vmaj, vmin); - } else if (version == QQmlImports::PartiallyVersioned) { + return QString::asprintf(".%d.%d", version.majorVersion(), version.minorVersion()); + } else if (versionMode == QQmlImports::PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString::asprintf(".%d", vmaj); + return QString::asprintf(".%d", version.majorVersion()); } // else extension without version number (eg. MyModule) return QString(); } @@ -591,7 +590,7 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) \sa addFileImport(), addLibraryImport */ bool QQmlImports::resolveType(const QHashedStringRef &type, - QQmlType *type_return, int *vmaj, int *vmin, + QQmlType *type_return, QTypeRevision *version_return, QQmlImportNamespace** ns_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) const @@ -603,7 +602,7 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, return true; } if (type_return) { - if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType, + if (d->resolveType(type, version_return, type_return, errors, registrationType, typeRecursionDetected)) { if (qmlImportTrace()) { #define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \ @@ -627,7 +626,9 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, return false; } -bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) +bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, + const QQmlTypeLoaderQmldirContent &qmldir, + QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) { Q_ASSERT(resolvedUrl.endsWith(Slash)); url = resolvedUrl; @@ -648,24 +649,27 @@ bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQml } } - qmlDirScripts = getVersionedScripts(scripts, majversion, minversion); + qmlDirScripts = getVersionedScripts(scripts, version); } return true; } -QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin) +QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts, + QTypeRevision version) { QMap<QString, QQmlDirParser::Script> versioned; for (QList<QQmlDirParser::Script>::const_iterator sit = qmldirscripts.constBegin(); sit != qmldirscripts.constEnd(); ++sit) { // Only include scripts that match our requested version - if (((vmaj == -1) || (sit->majorVersion == vmaj)) && - ((vmin == -1) || (sit->minorVersion <= vmin))) { + if ((!version.hasMajorVersion() || (sit->version.majorVersion() == version.majorVersion())) + && (!version.hasMinorVersion() + || (sit->version.minorVersion() <= version.minorVersion()))) { // Load the highest version that matches QMap<QString, QQmlDirParser::Script>::iterator vit = versioned.find(sit->nameSpace); - if (vit == versioned.end() || (vit->minorVersion < sit->minorVersion)) { + if (vit == versioned.end() + || (vit->version.minorVersion() < sit->version.minorVersion())) { versioned.insert(sit->nameSpace, *sit); } } @@ -685,26 +689,25 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml If the return pointer is 0, the corresponding search is not done. */ bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type, - QQmlType *type_return, int *vmaj, int *vmin, + QQmlType *type_return, QTypeRevision *version_return, QQmlType::RegistrationType registrationType) const { - return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return, nullptr, nullptr, registrationType); + return ns->resolveType(d->typeLoader, type, version_return, type_return, nullptr, nullptr, + registrationType); } bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, QQmlType *type_return, QString *base, - bool *typeRecursionDetected, + QTypeRevision *version_return, QQmlType *type_return, + QString *base, bool *typeRecursionDetected, QQmlType::RegistrationType registrationType, QQmlImport::RecursionRestriction recursionRestriction, QList<QQmlError> *errors) const { - if (majversion >= 0 && minversion >= 0) { - QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion); + if (version.hasMajorVersion() && version.hasMinorVersion()) { + QQmlType t = QQmlMetaType::qmlType(type, uri, version); if (t.isValid()) { - if (vmajor) - *vmajor = majversion; - if (vminor) - *vminor = minversion; + if (version_return) + *version_return = version; if (type_return) *type_return = t; return true; @@ -763,14 +766,16 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt break; } - // importing version -1 means import ALL versions - if ((majversion == -1) || - (implicitlyImported && c.internal) || // allow the implicit import of internal types - (c.majorVersion == majversion && c.minorVersion <= minversion)) { + // importing invalid version means import ALL versions + if (!version.hasMajorVersion() || (implicitlyImported && c.internal) + // allow the implicit import of internal types + || (c.version.majorVersion() == version.majorVersion() + && c.version.minorVersion() <= version.minorVersion())) { // Is this better than the previous candidate? - if ((candidate == end) || - (c.majorVersion > candidate->majorVersion) || - ((c.majorVersion == candidate->majorVersion) && (c.minorVersion > candidate->minorVersion))) { + if ((candidate == end) + || (c.version.majorVersion() > candidate->version.majorVersion()) + || ((c.version.majorVersion() == candidate->version.majorVersion()) + && (c.version.minorVersion() > candidate->version.minorVersion()))) { if (base) { componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName); if (c.internal) { @@ -798,12 +803,9 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt if (!base) // ensure we have a componentUrl componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName); QQmlType returnType = QQmlMetaType::typeForUrl(componentUrl, type, isCompositeSingleton, - nullptr, candidate->majorVersion, - candidate->minorVersion); - if (vmajor) - *vmajor = candidate->majorVersion; - if (vminor) - *vminor = candidate->minorVersion; + nullptr, candidate->version); + if (version_return) + *version_return = candidate->version; if (type_return) *type_return = returnType; return returnType.isValid(); @@ -855,14 +857,14 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt return false; } -bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor, +bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision *version_return, QQmlType *type_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) { const QVector<QHashedStringRef> splitName = type.split(Dot); auto resolveTypeInNamespace = [&](QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) -> bool { - if (nameSpace->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors, + if (nameSpace->resolveType(typeLoader, unqualifiedtype, version_return, type_return, &base, errors, registrationType, typeRecursionDetected)) return true; if (nameSpace->imports.count() == 1 && !nameSpace->imports.at(0)->isLibrary && type_return && nameSpace != &unqualifiedset) { @@ -973,7 +975,7 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const } bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, - int *vmajor, int *vminor, QQmlType *type_return, + QTypeRevision *version_return, QQmlType *type_return, QString *base, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) @@ -987,13 +989,13 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS for (int i=0; i<imports.count(); ++i) { const QQmlImportInstance *import = imports.at(i); - if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base, + if (import->resolveType(typeLoader, type, version_return, type_return, base, typeRecursionDetected, registrationType, recursionRestriction, errors)) { if (qmlCheckTypes()) { // check for type clashes for (int j = i+1; j<imports.count(); ++j) { const QQmlImportInstance *import2 = imports.at(j); - if (import2->resolveType(typeLoader, type, vmajor, vminor, nullptr, base, + if (import2->resolveType(typeLoader, type, version_return, nullptr, base, nullptr, registrationType)) { if (errors) { QString u1 = import->url; @@ -1020,9 +1022,11 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2)); } else { error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5") - .arg(u1) - .arg(import->majversion).arg(import->minversion) - .arg(import2->majversion).arg(import2->minversion)); + .arg(u1) + .arg(import->version.majorVersion()) + .arg(import->version.minorVersion()) + .arg(import2->version.majorVersion()) + .arg(import2->version.minorVersion())); } errors->prepend(error); } @@ -1068,18 +1072,19 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following: [QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models] */ -static QStringList versionUriList(const QString &uri, int vmaj, int vmin) +static QStringList versionUriList(const QString &uri, QTypeRevision version) { QStringList result; - for (int version = QQmlImports::FullyVersioned; version <= QQmlImports::Unversioned; ++version) { + for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) { int index = uri.length(); do { QString versionUri = uri; - versionUri.insert(index, QQmlImports::versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version))); + versionUri.insert(index, QQmlImports::versionString( + version, QQmlImports::ImportVersion(mode))); result += versionUri; index = uri.lastIndexOf(Dot, index - 1); - } while (index > 0 && version != QQmlImports::Unversioned); + } while (index > 0 && mode != QQmlImports::Unversioned); } return result; } @@ -1144,8 +1149,7 @@ Import an extension defined by a qmldir file. \a qmldirFilePath is a raw file path. */ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, - const QString &uri, - int vmaj, int vmin, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, const QQmlTypeLoaderQmldirContent &qmldir, QList<QQmlError> *errors) @@ -1171,10 +1175,10 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, return true; if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { - if ((vmaj >= 0 && vmin >= 0) - ? !QQmlMetaType::isModule(uri, vmaj, vmin) + if ((version.hasMajorVersion() && version.hasMinorVersion()) + ? !QQmlMetaType::isModule(uri, version) : !QQmlMetaType::isAnyModule(uri)) { - QQmlMetaType::qmlRegisterModuleTypes(uri, vmaj); + QQmlMetaType::qmlRegisterModuleTypes(uri, version); } } else { // First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue @@ -1198,7 +1202,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name); if (!resolvedFilePath.isEmpty()) { dynamicPluginsFound++; - if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, vmaj, errors)) { + if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, version, errors)) { if (errors) { // XXX TODO: should we leave the import plugin error alone? // Here, we pop it off the top and coalesce it into this error's message. @@ -1223,7 +1227,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, // versioned to unversioned, we need to compare with differnt version strings. If a module // has several plugins, they must all have the same version. Start by populating pluginPairs // with relevant plugins to cut the list short early on: - const QStringList versionUris = versionUriList(uri, vmaj, vmin); + const QStringList versionUris = versionUriList(uri, version); QVector<StaticPluginPair> pluginPairs; if (!populatePluginPairVector(pluginPairs, uri, versionUris, qmldirFilePath, errors)) return false; @@ -1235,7 +1239,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, if (versionUri == metaTagUri.toString()) { staticPluginsFound++; QObject *instance = pair.first.instance(); - if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, vmaj, errors)) { + if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, version, errors)) { if (errors) { QQmlError poppedError = errors->takeFirst(); QQmlError error; @@ -1338,10 +1342,11 @@ and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise return false. */ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( - const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, QString *outQmldirFilePath, QString *outQmldirPathUrl) { - Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries + // Versions are always specified for libraries + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); // Check cache first @@ -1352,7 +1357,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( cacheHead = *cachePtr; QQmlImportDatabase::QmldirCache *cache = cacheHead; while (cache) { - if (cache->versionMajor == vmaj && cache->versionMinor == vmin) { + if (cache->version == version) { *outQmldirFilePath = cache->qmldirFilePath; *outQmldirPathUrl = cache->qmldirPathUrl; return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound @@ -1372,7 +1377,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( // Search local import paths for a matching version const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( - uri, localImportPaths, vmaj, vmin); + uri, localImportPaths, version); bool pathTurnedRemote = false; for (QString qmldirPath : qmlDirPaths) { if (interceptor) { @@ -1394,8 +1399,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( url = QUrl::fromLocalFile(absolutePath.toString()).toString(); QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->versionMajor = vmaj; - cache->versionMinor = vmin; + cache->version = version; cache->qmldirFilePath = absoluteFilePath; cache->qmldirPathUrl = url; cache->next = cacheHead; @@ -1409,19 +1413,19 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( } QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->versionMajor = vmaj; - cache->versionMinor = vmin; + cache->version = version; cache->next = cacheHead; database->qmldirCache.insert(uri, cache); return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound; } -bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin, +bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, + const QString &uri, QTypeRevision version, QList<QQmlError> *errors) { - int lowest_min = INT_MAX; - int highest_min = INT_MIN; + quint8 lowest_min = std::numeric_limits<quint8>::max(); + quint8 highest_min = 0; typedef QQmlDirComponents::const_iterator ConstIterator; const QQmlDirComponents &components = qmldir.components(); @@ -1429,21 +1433,20 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) { - if ((cit2->typeName == cit->typeName) && - (cit2->majorVersion == cit->majorVersion) && - (cit2->minorVersion == cit->minorVersion)) { + if (cit2->typeName == cit->typeName && cit2->version == cit->version) { // This entry clashes with a predecessor QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") - .arg(cit->typeName).arg(cit->majorVersion).arg(cit->minorVersion).arg(uri)); + .arg(cit->typeName).arg(cit->version.majorVersion()) + .arg(cit->version.minorVersion()).arg(uri)); errors->prepend(error); return false; } } - if (cit->majorVersion == vmaj) { - lowest_min = qMin(lowest_min, cit->minorVersion); - highest_min = qMax(highest_min, cit->minorVersion); + if (cit->version.majorVersion() == version.majorVersion()) { + lowest_min = qMin(lowest_min, cit->version.minorVersion()); + highest_min = qMax(highest_min, cit->version.minorVersion()); } } @@ -1453,27 +1456,27 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent SConstIterator send = scripts.constEnd(); for (SConstIterator sit = scripts.constBegin(); sit != send; ++sit) { for (SConstIterator sit2 = scripts.constBegin(); sit2 != sit; ++sit2) { - if ((sit2->nameSpace == sit->nameSpace) && - (sit2->majorVersion == sit->majorVersion) && - (sit2->minorVersion == sit->minorVersion)) { + if (sit2->nameSpace == sit->nameSpace && sit2->version == sit->version) { // This entry clashes with a predecessor QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") - .arg(sit->nameSpace).arg(sit->majorVersion).arg(sit->minorVersion).arg(uri)); + .arg(sit->nameSpace).arg(sit->version.majorVersion()) + .arg(sit->version.minorVersion()).arg(uri)); errors->prepend(error); return false; } } - if (sit->majorVersion == vmaj) { - lowest_min = qMin(lowest_min, sit->minorVersion); - highest_min = qMax(highest_min, sit->minorVersion); + if (sit->version.majorVersion() == version.majorVersion()) { + lowest_min = qMin(lowest_min, sit->version.minorVersion()); + highest_min = qMax(highest_min, sit->version.minorVersion()); } } - if (lowest_min > vmin || highest_min < vmin) { + if (lowest_min > version.minorVersion() || highest_min < version.minorVersion()) { QQmlError error; - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); errors->prepend(error); return false; } @@ -1500,10 +1503,9 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix) return nameSpace; } -QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace, - const QString &uri, const QString &url, int vmaj, int vmin, - QV4::CompiledData::Import::ImportType type, - QList<QQmlError> *errors, bool lowPrecedence) +QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace( + QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, QTypeRevision version, + QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, bool lowPrecedence) { Q_ASSERT(nameSpace); Q_ASSERT(errors); @@ -1514,8 +1516,7 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace import->uri = uri; import->url = url; import->localDirectoryPath = QQmlFile::urlToLocalFileOrQrc(url); - import->majversion = vmaj; - import->minversion = vmin; + import->version = version; import->isLibrary = (type == QV4::CompiledData::Import::ImportLibrary); if (lowPrecedence) @@ -1526,10 +1527,10 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace return import; } -bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, - QQmlImportDatabase *database, - QList<QQmlError> *errors) +bool QQmlImportsPrivate::addLibraryImport( + const QString& uri, const QString &prefix, QTypeRevision version, + const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, + QQmlImportDatabase *database, QList<QQmlError> *errors) { Q_ASSERT(database); Q_ASSERT(errors); @@ -1537,7 +1538,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre QQmlImportNamespace *nameSpace = importNamespace(prefix); Q_ASSERT(nameSpace); - QQmlImportInstance *inserted = addImportToNamespace(nameSpace, uri, qmldirUrl, vmaj, vmin, QV4::CompiledData::Import::ImportLibrary, errors); + QQmlImportInstance *inserted = addImportToNamespace( + nameSpace, uri, qmldirUrl, version, + QV4::CompiledData::Import::ImportLibrary, errors); Q_ASSERT(inserted); if (!incomplete) { @@ -1548,7 +1551,7 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre return false; if (qmldir.hasContent()) { - if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors)) + if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors)) return false; if (!inserted->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) @@ -1557,18 +1560,22 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre } // Ensure that we are actually providing something - if ((vmaj < 0) || (vmin < 0) || !QQmlMetaType::isModule(uri, vmaj, vmin)) { + if (!version.hasMajorVersion() || !version.hasMinorVersion() + || !QQmlMetaType::isModule(uri, version)) { if (inserted->qmlDirComponents.isEmpty() && inserted->qmlDirScripts.isEmpty()) { QQmlError error; - if (QQmlMetaType::isAnyModule(uri)) - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); - else + if (QQmlMetaType::isAnyModule(uri)) { + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); + } else { error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri)); + } errors->prepend(error); return false; - } else if ((vmaj >= 0) && (vmin >= 0) && qmldir.hasContent()) { + } else if (version.hasMajorVersion() && version.hasMinorVersion() + && qmldir.hasContent()) { // Verify that the qmldir content is valid for this version - if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors)) + if (!validateQmldirVersion(qmldir, uri, version, errors)) return false; } } @@ -1577,10 +1584,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre return true; } -bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, - bool isImplicitImport, bool incomplete, QQmlImportDatabase *database, - QList<QQmlError> *errors) +bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix, QTypeRevision version, + bool isImplicitImport, bool incomplete, + QQmlImportDatabase *database, QList<QQmlError> *errors) { Q_ASSERT(errors); @@ -1656,7 +1662,9 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix } } - QQmlImportInstance *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport); + QQmlImportInstance *inserted = addImportToNamespace( + nameSpace, importUri, url, version, QV4::CompiledData::Import::ImportFile, + errors, isImplicitImport); Q_ASSERT(inserted); if (!incomplete && !qmldirIdentifier.isEmpty()) { @@ -1665,7 +1673,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix return false; if (qmldir.hasContent()) { - if (!importExtension(qmldir.pluginLocation(), importUri, vmaj, vmin, database, qmldir, errors)) + if (!importExtension(qmldir.pluginLocation(), importUri, version, database, qmldir, errors)) return false; if (!inserted->setQmldirContent(url, qmldir, nameSpace, errors)) @@ -1689,26 +1697,27 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString & return false; if (qmldir.hasContent()) { - int vmaj = import->majversion; - int vmin = import->minversion; - if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors)) + QTypeRevision version = import->version; + if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors)) return false; if (import->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) { if (import->qmlDirComponents.isEmpty() && import->qmlDirScripts.isEmpty()) { // The implicit import qmldir can be empty, and plugins have no extra versions - if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, vmaj, vmin)) { + if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, version)) { QQmlError error; - if (QQmlMetaType::isAnyModule(uri)) - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); - else + if (QQmlMetaType::isAnyModule(uri)) { + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); + } else { error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri)); + } errors->prepend(error); return false; } - } else if ((vmaj >= 0) && (vmin >= 0)) { + } else if (version.hasMajorVersion() && version.hasMinorVersion()) { // Verify that the qmldir content is valid for this version - if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors)) + if (!validateQmldirVersion(qmldir, uri, version, errors)) return false; } return true; @@ -1742,7 +1751,8 @@ bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlErro << ")::addImplicitImport"; bool incomplete = !isLocal(baseUrl()); - return d->addFileImport(QLatin1String("."), QString(), -1, -1, true, incomplete, importDb, errors); + return d->addFileImport(QLatin1String("."), QString(), QTypeRevision(), true, incomplete, + importDb, errors); } /*! @@ -1753,8 +1763,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta importInstance->url = importUrl.toString(); importInstance->uri = name; importInstance->isInlineComponent = true; - importInstance->majversion = 0; - importInstance->minversion = 0; + importInstance->version = QTypeRevision::zero(); importInstance->containingType = containingType; d->unqualifiedset.imports.push_back(importInstance); return true; @@ -1782,7 +1791,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta filled appropriately. */ bool QQmlImports::addFileImport(QQmlImportDatabase *importDb, - const QString& uri, const QString& prefix, int vmaj, int vmin, + const QString& uri, const QString& prefix, QTypeRevision version, bool incomplete, QList<QQmlError> *errors) { Q_ASSERT(importDb); @@ -1790,13 +1799,13 @@ bool QQmlImports::addFileImport(QQmlImportDatabase *importDb, if (qmlImportTrace()) qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addFileImport: " - << uri << ' ' << vmaj << '.' << vmin << " as " << prefix; + << uri << ' ' << version << " as " << prefix; - return d->addFileImport(uri, prefix, vmaj, vmin, false, incomplete, importDb, errors); + return d->addFileImport(uri, prefix, version, false, incomplete, importDb, errors); } bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb, - const QString &uri, const QString &prefix, int vmaj, int vmin, + const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString& qmldirUrl, bool incomplete, QList<QQmlError> *errors) { Q_ASSERT(importDb); @@ -1804,9 +1813,9 @@ bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb, if (qmlImportTrace()) qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addLibraryImport: " - << uri << ' ' << vmaj << '.' << vmin << " as " << prefix; + << uri << ' ' << version << " as " << prefix; - return d->addLibraryImport(uri, prefix, vmaj, vmin, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors); + return d->addLibraryImport(uri, prefix, version, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors); } bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb, @@ -1824,10 +1833,10 @@ bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb, } QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir( - QQmlImportDatabase *importDb, const QString &uri, int vmaj, int vmin, + QQmlImportDatabase *importDb, const QString &uri, QTypeRevision version, QString *qmldirFilePath, QString *url) { - return d->locateLocalQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url); + return d->locateLocalQmldir(uri, version, importDb, qmldirFilePath, url); } bool QQmlImports::isLocal(const QString &url) @@ -2133,19 +2142,21 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths) \internal */ static bool registerPluginTypes(QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) + const QString &typeNamespace, QTypeRevision version, + QList<QQmlError> *errors) { if (qmlImportTrace()) qDebug().nospace() << "QQmlImportDatabase::registerPluginTypes: " << uri << " from " << basePath; - if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors)) + if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors)) return false; - if (vmaj >= 0 && !typeNamespace.isEmpty() && !QQmlMetaType::protectModule(uri, vmaj)) { + if (version.hasMajorVersion() && !typeNamespace.isEmpty() + && !QQmlMetaType::protectModule(uri, version)) { QQmlError error; error.setDescription( QString::fromLatin1("Cannot protect module %1 %2 as it was never registered") - .arg(uri).arg(vmaj)); + .arg(uri).arg(version.majorVersion())); errors->append(error); return false; } @@ -2156,8 +2167,9 @@ static bool registerPluginTypes(QObject *instance, const QString &basePath, cons /*! \internal */ -bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) +bool QQmlImportDatabase::importStaticPlugin( + QObject *instance, const QString &basePath, const QString &uri, + const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors) { // Dynamic plugins are differentiated by their filepath. For static plugins we // don't have that information so we use their address as key instead. @@ -2180,7 +2192,7 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba plugin.loader = nullptr; plugins->insert(uniquePluginID, plugin); - if (!registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors)) + if (!registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors)) return false; } @@ -2200,8 +2212,9 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba /*! \internal */ -bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) +bool QQmlImportDatabase::importDynamicPlugin( + const QString &filePath, const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors) { QFileInfo fileInfo(filePath); const QString absoluteFilePath = fileInfo.absoluteFilePath(); @@ -2255,7 +2268,7 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr plugins->insert(absoluteFilePath, plugin); // Continue with shared code path for dynamic and static plugins: - if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, vmaj, errors)) + if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, version, errors)) return false; } } diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index 2e994fd27f..7416bb7a4c 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -81,8 +81,7 @@ struct QQmlImportInstance QString url; // the base path of the import QString localDirectoryPath; // the base path of the import if it's a local file QQmlType containingType; // points to the containing type for inline components - int majversion; // the major version imported - int minversion; // the minor version imported + QTypeRevision version; // the version imported bool isLibrary; // true means that this is not a file import bool implicitlyImported = false; bool isInlineComponent = false; @@ -92,10 +91,11 @@ struct QQmlImportInstance bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors); - static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin); + static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, + QTypeRevision version); bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, - int *vmajor, int *vminor, QQmlType* type_return, + QTypeRevision *version_return, QQmlType* type_return, QString *base = nullptr, bool *typeRecursionDetected = nullptr, QQmlType::RegistrationType = QQmlType::AnyRegistrationType, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion, @@ -113,7 +113,7 @@ public: QQmlImportInstance *findImport(const QString &uri) const; bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, QQmlType* type_return, + QTypeRevision *version_return, QQmlType* type_return, QString *base = nullptr, QList<QQmlError> *errors = nullptr, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, bool *typeRecursionDeteced = nullptr); @@ -140,14 +140,14 @@ public: bool resolveType(const QHashedStringRef &type, QQmlType *type_return, - int *version_major, int *version_minor, + QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList<QQmlError> *errors = nullptr, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, bool *typeRecursionDetected = nullptr) const; bool resolveType(QQmlImportNamespace *, const QHashedStringRef& type, - QQmlType *type_return, int *version_major, int *version_minor, + QQmlType *type_return, QTypeRevision *version_return, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType) const; @@ -156,11 +156,11 @@ public: bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType); bool addFileImport(QQmlImportDatabase *, - const QString& uri, const QString& prefix, int vmaj, int vmin, bool incomplete, - QList<QQmlError> *errors); + const QString& uri, const QString& prefix, QTypeRevision version, + bool incomplete, QList<QQmlError> *errors); bool addLibraryImport(QQmlImportDatabase *importDb, - const QString &uri, const QString &prefix, int vmaj, int vmin, + const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, QList<QQmlError> *errors); bool updateQmldirContent(QQmlImportDatabase *importDb, @@ -174,7 +174,7 @@ public: }; LocalQmldirResult locateLocalQmldir( - QQmlImportDatabase *, const QString &uri, int vmaj, int vmin, + QQmlImportDatabase *, const QString &uri, QTypeRevision version, QString *qmldirFilePath, QString *url); void populateCache(QQmlTypeNameCache *cache) const; @@ -192,14 +192,14 @@ public: { QString typeName; QString prefix; - int majorVersion; - int minorVersion; + QTypeRevision version; }; QList<CompositeSingletonReference> resolvedCompositeSingletons() const; - static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin); - static QString versionString(int vmaj, int vmin, ImportVersion version); + static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, + QTypeRevision version); + static QString versionString(QTypeRevision version, ImportVersion importVersion); static bool isLocal(const QString &url); static bool isLocal(const QUrl &url); @@ -222,7 +222,9 @@ public: ~QQmlImportDatabase(); #if QT_CONFIG(library) - bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors); + bool importDynamicPlugin(const QString &filePath, const QString &uri, + const QString &importNamespace, QTypeRevision version, + QList<QQmlError> *errors); bool removeDynamicPlugin(const QString &filePath); QStringList dynamicPlugins() const; #endif @@ -245,13 +247,13 @@ private: const QString &qmldirPath, const QString &qmldirPluginPath, const QString &baseName); bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors); + const QString &typeNamespace, QTypeRevision version, + QList<QQmlError> *errors); void clearDirCache(); void finalizePlugin(QObject *instance, const QString &path, const QString &uri); struct QmldirCache { - int versionMajor; - int versionMinor; + QTypeRevision version; QString qmldirFilePath; QString qmldirPathUrl; QmldirCache *next; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 76816618ac..429f9c5b09 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -92,8 +92,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, d->typeId = type.typeId; d->listId = type.listId; d->isSetup = true; - d->version_maj = 0; - d->version_min = 0; + d->version = QTypeRevision::zero(); data->registerType(d); return d; } @@ -105,28 +104,30 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; - if (type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi)) { - if (type.version >= 1) // static metaobject added in version 1 + if (type.qobjectApi || (type.structVersion >= 3 && type.generalizedQobjectApi)) { + if (type.structVersion >= 1) // static metaobject added in version 1 d->baseMetaObject = type.instanceMetaObject; - if (type.version >= 2) // typeId added in version 2 + if (type.structVersion >= 2) // typeId added in version 2 d->typeId = type.typeId; - if (type.version >= 2) // revisions added in version 2 + if (type.structVersion >= 2) // revisions added in version 2 d->revision = type.revision; } d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi; - if (type.version >= 3) { + if (type.structVersion >= 3) { d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.generalizedQobjectApi; } else { d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi; } d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); d->extraData.sd->singletonInstanceInfo->instanceMetaObject - = ((type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi) ) && type.version >= 1) ? type.instanceMetaObject : nullptr; + = ((type.qobjectApi || (type.structVersion >= 3 && type.generalizedQobjectApi) ) + && type.structVersion >= 1) + ? type.instanceMetaObject + : nullptr; return d; } @@ -138,9 +139,8 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; - if (type.version >= 1) // revisions added in version 1 + d->version = type.version; + if (type.structVersion >= 1) // revisions added in version 1 d->revision = type.revision; d->typeId = type.typeId; d->listId = type.listId; @@ -176,8 +176,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el auto *d = new QQmlTypePrivate(QQmlType::CompositeType); data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; d->extraData.fd->url = QQmlTypeLoader::normalize(type.url); return d; @@ -190,8 +189,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url); @@ -267,35 +265,35 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo, } } -void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, int majorVersion, +void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, QTypeRevision version, void (*registerFunction)()) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); + const QQmlMetaTypeData::VersionedUri versionedUri(uri, version); QQmlMetaTypeDataPtr data; if (data->moduleTypeRegistrationFunctions.contains(versionedUri)) - qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), majorVersion); + qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), version.majorVersion()); else data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction); } -void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, int majorVersion) +void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, QTypeRevision version) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); + 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), majorVersion); + qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), version.majorVersion()); else data->moduleTypeRegistrationFunctions.remove(versionedUri); } -bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, int majorVersion) +bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, majorVersion)); + return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, version)); } void QQmlMetaType::clearTypeRegistrations() @@ -334,7 +332,7 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type) { - if (type.version > 0) + if (type.structVersion > 0) qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); QQmlMetaTypeDataPtr data; @@ -372,7 +370,7 @@ QString registrationTypeString(QQmlType::RegistrationType typeType) // NOTE: caller must hold a QMutexLocker on "data" bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, - const char *uri, const QString &typeName, int majorVersion) + const char *uri, const QString &typeName, QTypeRevision version) { if (!typeName.isEmpty()) { if (typeName.at(0).isLower()) { @@ -393,14 +391,14 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (uri && !typeName.isEmpty()) { QString nameSpace = QString::fromUtf8(uri); - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = nameSpace; - versionedUri.majorVersion = majorVersion; + QQmlMetaTypeData::VersionedUri versionedUri(nameSpace, version); if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){ if (qqtm->isLocked()){ QString failure(QCoreApplication::translate("qmlRegisterType", "Cannot install %1 '%2' into protected module '%3' version '%4'")); - data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)) + .arg(typeName).arg(nameSpace) + .arg(version.majorVersion())); return false; } } @@ -410,9 +408,9 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da } // NOTE: caller must hold a QMutexLocker on "data" -QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data) +QQmlTypeModule *getTypeModule(const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data) { - QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); + QQmlMetaTypeData::VersionedUri versionedUri(uri, version); QQmlTypeModule *module = data->uriToModule.value(versionedUri); if (!module) { module = new QQmlTypeModule(versionedUri.uri, versionedUri.majorVersion); @@ -449,7 +447,7 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data) if (!type->module.isEmpty()) { const QHashedString &mod = type->module; - QQmlTypeModule *module = getTypeModule(mod, type->version_maj, data); + QQmlTypeModule *module = getTypeModule(mod, type->version, data); Q_ASSERT(module); module->add(type); } @@ -460,7 +458,7 @@ QQmlType QQmlMetaType::registerType(const QQmlPrivate::RegisterType &type) QQmlMetaTypeDataPtr data; QString elementName = QString::fromUtf8(type.elementName); - if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor)) + if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, elementName, type); @@ -477,7 +475,7 @@ QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingleto QQmlMetaTypeDataPtr data; QString typeName = QString::fromUtf8(type.typeName); - if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor)) + if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, typeName, type); @@ -497,7 +495,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe if (*(type.uri) == '\0') fileImport = true; if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri, - typeName, type.versionMajor)) { + typeName, type.version)) { return QQmlType(); } @@ -519,7 +517,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit bool fileImport = false; if (*(type.uri) == '\0') fileImport = true; - if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.versionMajor)) + if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, typeName, type); @@ -567,7 +565,7 @@ void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &t int QQmlMetaType::registerUnitCacheHook( const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration) { - if (hookRegistration.version > 0) + if (hookRegistration.structVersion > 0) qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); QQmlMetaTypeDataPtr data; @@ -575,40 +573,37 @@ int QQmlMetaType::registerUnitCacheHook( return 0; } -bool QQmlMetaType::protectModule(const QString &uri, int majVersion) +bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = uri; - versionedUri.majorVersion = majVersion; - - if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) { + if (QQmlTypeModule* qqtm = data->uriToModule.value( + QQmlMetaTypeData::VersionedUri(uri, version), nullptr)) { qqtm->lock(); return true; } return false; } -void QQmlMetaType::registerModule(const char *uri, int versionMajor, int versionMinor) +void QQmlMetaType::registerModule(const char *uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data); + QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data); Q_ASSERT(module); - module->addMinorVersion(versionMinor); + module->addMinorVersion(version.minorVersion()); } -int QQmlMetaType::typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName) +int QQmlMetaType::typeId(const char *uri, QTypeRevision version, const char *qmlName) { QQmlMetaTypeDataPtr data; - QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data); + QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data); if (!module) return -1; - QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), versionMinor); + QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version); if (!type.isValid()) return -1; @@ -622,12 +617,12 @@ void QQmlMetaType::registerUndeletableType(const QQmlType &dtype) } static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const QString &uri, - int majorVersion) + QTypeRevision version) { // Has any type previously been installed to this namespace? QHashedString nameSpace(uri); for (const QQmlType &type : data->types) { - if (type.module() == nameSpace && type.majorVersion() == majorVersion) + if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion()) return true; } @@ -654,8 +649,8 @@ public: bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, - QList<QQmlError> *errors) + const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors) { if (!typeNamespace.isEmpty() && typeNamespace != uri) { // This is an 'identified' module @@ -676,7 +671,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures); if (!typeNamespace.isEmpty()) { // This is an 'identified' module - if (namespaceContainsRegistrations(data, typeNamespace, vmaj)) { + if (namespaceContainsRegistrations(data, typeNamespace, version)) { // Other modules have already installed to this namespace if (errors) { QQmlError error; @@ -718,7 +713,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat iface->registerTypes(moduleId); } - data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, vmaj)); + data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, version)); if (!failures.isEmpty()) { if (errors) { @@ -749,7 +744,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat QQmlType QQmlMetaType::typeForUrl(const QString &urlString, const QHashedStringRef &qualifiedType, bool isCompositeSingleton, QList<QQmlError> *errors, - int majorVersion, int minorVersion) + QTypeRevision version) { // ### unfortunate (costly) conversion const QUrl url = QQmlTypeLoader::normalize(QUrl(urlString)); @@ -794,11 +789,10 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString, const QQmlType::RegistrationType registrationType = isCompositeSingleton ? QQmlType::CompositeSingletonType : QQmlType::CompositeType; - if (checkRegistration(registrationType, data, nullptr, typeName, majorVersion)) { + if (checkRegistration(registrationType, data, nullptr, typeName, version)) { auto *priv = new QQmlTypePrivate(registrationType); priv->setName(QString(), typeName); - priv->version_maj = majorVersion; - priv->version_min = minorVersion; + priv->version = version; if (isCompositeSingleton) { priv->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; @@ -851,14 +845,12 @@ bool QQmlMetaType::isAnyModule(const QString &uri) /* Returns true if a module \a uri of this version is installed and locked; */ -bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion) +bool QQmlMetaType::isLockedModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = uri; - versionedUri.majorVersion = majVersion; - if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) + if (QQmlTypeModule* qqtm = data->uriToModule.value( + QQmlMetaTypeData::VersionedUri(uri, version), nullptr)) return qqtm->isLocked(); return false; } @@ -870,24 +862,24 @@ bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion) So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10. */ -bool QQmlMetaType::isModule(const QString &module, int versionMajor, int versionMinor) +bool QQmlMetaType::isModule(const QString &module, QTypeRevision version) { - Q_ASSERT(versionMajor >= 0 && versionMinor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); QQmlMetaTypeDataPtr data; // first, check Types QQmlTypeModule *tm = - data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, versionMajor)); - if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor) + data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, version)); + if (tm && tm->minimumMinorVersion() <= version.minorVersion() && tm->maximumMinorVersion() >= version.minorVersion()) return true; return false; } -QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, int majorVersion) +QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, majorVersion)); + return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, version)); } QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions() @@ -1106,7 +1098,7 @@ QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type) Returns the type (if any) of URI-qualified named \a qualifiedName and version specified by \a version_major and \a version_minor. */ -QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, QTypeRevision version) { int slash = qualifiedName.indexOf(QLatin1Char('/')); if (slash <= 0) @@ -1115,23 +1107,23 @@ QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, QHashedStringRef module(qualifiedName.constData(), slash); QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1); - return qmlType(name, module, version_major, version_minor); + return qmlType(name, module, version); } /*! Returns the type (if any) of \a name in \a module and version specified by \a version_major and \a version_minor. */ -QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, + QTypeRevision version) { - Q_ASSERT(version_major >= 0 && version_minor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); const QQmlMetaTypeDataPtr data; QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name); while (it != data->nameToType.cend() && it.key() == name) { QQmlType t(*it); - // XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty - if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor)) + if (module.isEmpty() || t.availableInVersion(module, version)) return t; ++it; } @@ -1154,15 +1146,16 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject) by \a version_major and \a version_minor in module specified by \a uri. Returns null if no type is registered. */ -QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, + QTypeRevision version) { - Q_ASSERT(version_major >= 0 && version_minor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); const QQmlMetaTypeDataPtr data; QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject); while (it != data->metaObjectToType.cend() && it.key() == metaObject) { QQmlType t(*it); - if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor)) + if (module.isEmpty() || t.availableInVersion(module, version)) return t; ++it; } @@ -1212,16 +1205,16 @@ QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileI return QQmlType(); } -QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, QTypeRevision version) { QQmlMetaTypeDataPtr data; // not const: the cache is created on demand - return data->propertyCache(metaObject, minorVersion); + return data->propertyCache(metaObject, version); } -QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, QTypeRevision version) { QQmlMetaTypeDataPtr data; // not const: the cache is created on demand - return data->propertyCache(type, minorVersion); + return data->propertyCache(type, version); } void QQmlMetaType::unregisterType(int typeIndex) @@ -1236,7 +1229,7 @@ void QQmlMetaType::unregisterType(int typeIndex) removeQQmlTypePrivate(data->metaObjectToType, d); for (auto & module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForMinorVersion(typeIndex); + data->clearPropertyCachesForVersion(typeIndex); data->types[typeIndex] = QQmlType(); data->undeletableTypes.remove(type); } @@ -1268,7 +1261,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches() for (auto &module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForMinorVersion(d->index); + data->clearPropertyCachesForVersion(d->index); *it = QQmlType(); } else { ++it; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 037cf89beb..e98a87e6a9 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -81,20 +81,20 @@ public: static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type); static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type); static bool registerPluginTypes(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, - QList<QQmlError> *errors); + const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors); static QQmlType typeForUrl(const QString &urlString, const QHashedStringRef& typeName, bool isCompositeSingleton, QList<QQmlError> *errors, - int majorVersion = -1, int minorVersion = -1); + QTypeRevision version = QTypeRevision()); static void unregisterType(int type); static CompositeMetaTypeIds registerInternalCompositeType(const QByteArray &className); static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds); - static void registerModule(const char *uri, int versionMajor, int versionMinor); - static bool protectModule(const QString &uri, int majVersion); + static void registerModule(const char *uri, QTypeRevision version); + static bool protectModule(const QString &uri, QTypeRevision version); - static int typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName); + static int typeId(const char *uri, QTypeRevision version, const char *qmlName); static void registerUndeletableType(const QQmlType &dtype); @@ -108,15 +108,16 @@ public: QmlType }; - static QQmlType qmlType(const QString &qualifiedName, int, int); - static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int); + static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version); + static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(const QMetaObject *); - static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); + static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(int typeId, TypeIdCategory category = TypeIdCategory::MetaType); static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); - static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion = -1); - static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, + QTypeRevision version = QTypeRevision()); + static QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version); static void freeUnusedTypesAndCaches(); @@ -150,9 +151,9 @@ public: static StringConverter customStringConverter(int); static bool isAnyModule(const QString &uri); - static bool isLockedModule(const QString &uri, int majorVersion); - static bool isModule(const QString &module, int versionMajor, int versionMinor); - static QQmlTypeModule *typeModule(const QString &uri, int majorVersion); + static bool isLockedModule(const QString &uri, QTypeRevision version); + static bool isModule(const QString &module, QTypeRevision version); + static QQmlTypeModule *typeModule(const QString &uri, QTypeRevision version); static QList<QQmlPrivate::AutoParentFunction> parentFunctions(); @@ -197,11 +198,11 @@ public: static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd); - static void qmlInsertModuleRegistration(const QString &uri, int majorVersion, + static void qmlInsertModuleRegistration(const QString &uri, QTypeRevision version, void (*registerFunction)()); - static void qmlRemoveModuleRegistration(const QString &uri, int majorVersion); + static void qmlRemoveModuleRegistration(const QString &uri, QTypeRevision version); - static bool qmlRegisterModuleTypes(const QString &uri, int majorVersion); + static bool qmlRegisterModuleTypes(const QString &uri, QTypeRevision version); }; Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE); diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index ed885eaa97..51d944e771 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -88,28 +88,28 @@ bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri return false; } -QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForMinorVersion(int index, int minorVersion) const +QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForVersion(int index, QTypeRevision version) const { return (index < typePropertyCaches.length()) - ? typePropertyCaches.at(index).value(minorVersion).data() + ? typePropertyCaches.at(index).value(version).data() : nullptr; } -void QQmlMetaTypeData::setPropertyCacheForMinorVersion(int index, int minorVersion, - QQmlPropertyCache *cache) +void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version, + QQmlPropertyCache *cache) { if (index >= typePropertyCaches.length()) typePropertyCaches.resize(index + 1); - typePropertyCaches[index][minorVersion] = cache; + typePropertyCaches[index][version] = cache; } -void QQmlMetaTypeData::clearPropertyCachesForMinorVersion(int index) +void QQmlMetaTypeData::clearPropertyCachesForVersion(int index) { if (index < typePropertyCaches.length()) typePropertyCaches[index].clear(); } -QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, QTypeRevision version) { if (QQmlPropertyCache *rv = propertyCaches.value(metaObject)) return rv; @@ -119,29 +119,31 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject propertyCaches.insert(metaObject, rv); return rv; } - QQmlPropertyCache *super = propertyCache(metaObject->superClass(), minorVersion); - QQmlPropertyCache *rv = super->copyAndAppend(metaObject, minorVersion); + QQmlPropertyCache *super = propertyCache(metaObject->superClass(), version); + QQmlPropertyCache *rv = super->copyAndAppend(metaObject, version); propertyCaches.insert(metaObject, rv); return rv; } -QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRevision version) { Q_ASSERT(type.isValid()); - if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), minorVersion)) + if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), version)) return pc; QVector<QQmlType> types; - int maxMinorVersion = 0; + quint8 maxMinorVersion = 0; const QMetaObject *metaObject = type.metaObject(); while (metaObject) { - QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), type.majorVersion(), minorVersion); + QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), + QTypeRevision::fromVersion(type.version().majorVersion(), + version.minorVersion())); if (t.isValid()) { - maxMinorVersion = qMax(maxMinorVersion, t.minorVersion()); + maxMinorVersion = qMax(maxMinorVersion, t.version().minorVersion()); types << t; } else { types << QQmlType(); @@ -150,12 +152,13 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min metaObject = metaObject->superClass(); } - if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), maxMinorVersion)) { - setPropertyCacheForMinorVersion(type.index(), minorVersion, pc); + const QTypeRevision maxVersion = QTypeRevision::fromVersion(version.majorVersion(), maxMinorVersion); + if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), maxVersion)) { + setPropertyCacheForVersion(type.index(), maxVersion, pc); return pc; } - QQmlPropertyCache *raw = propertyCache(type.metaObject(), minorVersion); + QQmlPropertyCache *raw = propertyCache(type.metaObject(), version); bool hasCopied = false; @@ -164,7 +167,7 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min if (!currentType.isValid()) continue; - int rev = currentType.metaObjectRevision(); + QTypeRevision rev = currentType.metaObjectRevision(); int moIndex = types.count() - 1 - ii; if (raw->allowedRevision(moIndex) != rev) { @@ -222,13 +225,13 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min } #endif - setPropertyCacheForMinorVersion(type.index(), minorVersion, raw); + setPropertyCacheForVersion(type.index(), version, raw); if (hasCopied) raw->release(); - if (minorVersion != maxMinorVersion) - setPropertyCacheForMinorVersion(type.index(), maxMinorVersion, raw); + if (version.minorVersion() != maxMinorVersion) + setPropertyCacheForVersion(type.index(), maxVersion, raw); return raw; } diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index e51d4ca1a4..7392b8573d 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -83,18 +83,17 @@ struct QQmlMetaTypeData MetaObjects metaObjectToType; typedef QHash<int, QQmlMetaType::StringConverter> StringConverters; StringConverters stringConverters; - QVector<QHash<int, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches; + QVector<QHash<QTypeRevision, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches; struct VersionedUri { - VersionedUri() - : majorVersion(0) {} - VersionedUri(const QHashedString &uri, int majorVersion) - : uri(uri), majorVersion(majorVersion) {} + VersionedUri() : majorVersion(0) {} + VersionedUri(const QHashedString &uri, QTypeRevision version) + : uri(uri), majorVersion(version.majorVersion()) {} bool operator==(const VersionedUri &other) const { return other.majorVersion == majorVersion && other.uri == uri; } QHashedString uri; - int majorVersion; + quint8 majorVersion; }; typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules; @@ -114,12 +113,12 @@ struct QQmlMetaTypeData QHash<const QMetaObject *, QQmlPropertyCache *> propertyCaches; - QQmlPropertyCache *propertyCacheForMinorVersion(int index, int minorVersion) const; - void setPropertyCacheForMinorVersion(int index, int minorVersion, QQmlPropertyCache *cache); - void clearPropertyCachesForMinorVersion(int index); + QQmlPropertyCache *propertyCacheForVersion(int index, QTypeRevision version) const; + void setPropertyCacheForVersion(int index, QTypeRevision version, QQmlPropertyCache *cache); + void clearPropertyCachesForVersion(int index); - QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion); - QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, QTypeRevision version); + QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version); void setTypeRegistrationFailures(QStringList *failures) { diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp index b7bc3555a6..01f93b85fe 100644 --- a/src/qml/qml/qqmlmoduleregistration.cpp +++ b/src/qml/qml/qqmlmoduleregistration.cpp @@ -39,27 +39,30 @@ #include <QtQml/private/qqmlmetatype_p.h> #include <QtQml/qqmlmoduleregistration.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE struct QQmlModuleRegistrationPrivate { const QString uri; - const int majorVersion; + const QTypeRevision version; }; QQmlModuleRegistration::QQmlModuleRegistration( const char *uri, int majorVersion, void (*registerFunction)()) : - d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri), majorVersion }) + d(new QQmlModuleRegistrationPrivate { + QString::fromUtf8(uri), + QTypeRevision::fromMajorVersion(majorVersion) + }) { - QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->majorVersion, - registerFunction); + QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->version, registerFunction); } QQmlModuleRegistration::~QQmlModuleRegistration() { - QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->majorVersion); + QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->version); delete d; } diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 9504fc37dc..527c5ee603 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -63,6 +63,7 @@ #include <QtCore/qvariant.h> #include <QtCore/qurl.h> #include <QtCore/qpointer.h> +#include <QtCore/qversionnumber.h> #include <QtCore/qmetaobject.h> #include <QtCore/qdebug.h> @@ -342,7 +343,7 @@ namespace QQmlPrivate typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); struct RegisterType { - int version; + int structVersion; int typeId; int listId; @@ -351,8 +352,7 @@ namespace QQmlPrivate QString noCreationReason; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *elementName; const QMetaObject *metaObject; @@ -368,12 +368,12 @@ namespace QQmlPrivate QQmlCustomParser *customParser; - int revision; + QTypeRevision revision; // If this is extended ensure "version" is bumped!!! }; struct RegisterTypeAndRevisions { - int version; + int structVersion; int typeId; int listId; @@ -381,7 +381,7 @@ namespace QQmlPrivate void (*create)(void *); const char *uri; - int versionMajor; + QTypeRevision version; const QMetaObject *metaObject; const QMetaObject *classInfoMetaObject; @@ -400,7 +400,7 @@ namespace QQmlPrivate }; struct RegisterInterface { - int version; + int structVersion; int typeId; int listId; @@ -415,26 +415,25 @@ namespace QQmlPrivate }; struct RegisterSingletonType { - int version; + int structVersion; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *); const QMetaObject *instanceMetaObject; // new in version 1 int typeId; // new in version 2 - int revision; // new in version 2 + QTypeRevision revision; // new in version 2 std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3 // If this is extended ensure "version" is bumped!!! }; struct RegisterSingletonTypeAndRevisions { - int version; + int structVersion; const char *uri; - int versionMajor; + QTypeRevision version; QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); const QMetaObject *instanceMetaObject; @@ -447,16 +446,14 @@ namespace QQmlPrivate struct RegisterCompositeType { QUrl url; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; }; struct RegisterCompositeSingletonType { QUrl url; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; }; @@ -468,7 +465,7 @@ namespace QQmlPrivate typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url); struct RegisterQmlUnitCacheHook { - int version; + int structVersion; QmlUnitCacheLookupFunction lookupCachedQmlUnit; }; @@ -512,11 +509,13 @@ namespace QQmlPrivate return metaObject->classInfo(indexOfOwnClassInfo(metaObject, key)).value(); } - inline int intClassInfo(const QMetaObject *metaObject, const char *key, int defaultValue = 0) + inline QTypeRevision revisionClassInfo(const QMetaObject *metaObject, const char *key, + QTypeRevision defaultValue = QTypeRevision()) { const int index = indexOfOwnClassInfo(metaObject, key); return (index == -1) ? defaultValue - : QByteArray(metaObject->classInfo(index).value()).toInt(); + : QTypeRevision::fromEncodedVersion( + QByteArray(metaObject->classInfo(index).value()).toInt()); } inline bool boolClassInfo(const QMetaObject *metaObject, const char *key, @@ -589,7 +588,7 @@ namespace QQmlPrivate 0, uri, - versionMajor, + QTypeRevision::fromMajorVersion(versionMajor), nullptr, @@ -617,7 +616,7 @@ namespace QQmlPrivate Constructors<T>::createInto, uri, - versionMajor, + QTypeRevision::fromMajorVersion(versionMajor), &T::staticMetaObject, classInfoMetaObject, diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 73b68a763b..8d91fa29e4 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -127,11 +127,11 @@ QQmlPropertyData::flagsForProperty(const QMetaProperty &p) static void populate(QQmlPropertyData *data, const QMetaProperty &p) { - Q_ASSERT(p.revision() <= Q_INT16_MAX); + Q_ASSERT(p.revision() <= std::numeric_limits<quint16>::max()); data->setCoreIndex(p.propertyIndex()); data->setNotifyIndex(QMetaObjectPrivate::signalIndex(p.notifySignal())); data->setFlags(fastFlagsForProperty(p)); - data->setRevision(p.revision()); + data->setRevision(QTypeRevision::fromEncodedVersion(p.revision())); } void QQmlPropertyData::lazyLoad(const QMetaProperty &p) @@ -183,8 +183,8 @@ void QQmlPropertyData::load(const QMetaMethod &m) if (m.attributes() & QMetaMethod::Cloned) m_flags.setIsCloned(true); - Q_ASSERT(m.revision() <= Q_INT16_MAX); - setRevision(m.revision()); + Q_ASSERT(m.revision() <= std::numeric_limits<quint16>::max()); + setRevision(QTypeRevision::fromEncodedVersion(m.revision())); } void QQmlPropertyData::lazyLoad(const QMetaMethod &m) @@ -212,14 +212,14 @@ QQmlPropertyCache::QQmlPropertyCache() /*! Creates a new QQmlPropertyCache of \a metaObject. */ -QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, int metaObjectRevision) +QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, QTypeRevision metaObjectRevision) : QQmlPropertyCache() { Q_ASSERT(metaObject); update(metaObject); - if (metaObjectRevision > 0) { + if (metaObjectRevision != QTypeRevision::zero()) { // Set the revision of the meta object that this cache describes to be // 'metaObjectRevision'. This is useful when constructing a property cache // from a type that was created directly in C++, and not through QML. For such @@ -291,14 +291,15 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth This is different from QMetaMethod::methodIndex(). */ void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags, - int coreIndex, int propType, int minorVersion, int notifyIndex) + int coreIndex, int propType, QTypeRevision version, + int notifyIndex) { QQmlPropertyData data; data.setPropType(propType); data.setCoreIndex(coreIndex); data.setNotifyIndex(notifyIndex); data.setFlags(flags); - data.setTypeMinorVersion(minorVersion); + data.setTypeVersion(version); QQmlPropertyData *old = findNamedProperty(name); if (old) @@ -420,12 +421,12 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) { - return copyAndAppend(metaObject, -1, propertyFlags, methodFlags, signalFlags); + return copyAndAppend(metaObject, QTypeRevision(), propertyFlags, methodFlags, signalFlags); } QQmlPropertyCache * QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, - int typeMinorVersion, + QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) @@ -439,13 +440,13 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, QMetaObjectPrivate::get(metaObject)->signalCount + QMetaObjectPrivate::get(metaObject)->propertyCount); - rv->append(metaObject, typeMinorVersion, propertyFlags, methodFlags, signalFlags); + rv->append(metaObject, typeVersion, propertyFlags, methodFlags, signalFlags); return rv; } void QQmlPropertyCache::append(const QMetaObject *metaObject, - int typeMinorVersion, + QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) @@ -454,7 +455,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, bool dynamicMetaObject = isDynamicMetaObject(metaObject); - allowedRevisionCache.append(0); + allowedRevisionCache.append(QTypeRevision::zero()); int methodCount = metaObject->methodCount(); Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4); @@ -599,7 +600,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, data->setFlags(propertyFlags); data->lazyLoad(p); - data->setTypeMinorVersion(typeMinorVersion); + data->setTypeVersion(typeVersion); data->m_flags.setIsDirect(!dynamicMetaObject); @@ -684,7 +685,7 @@ void QQmlPropertyCache::updateRecur(const QMetaObject *metaObject) updateRecur(metaObject->superClass()); - append(metaObject, -1); + append(metaObject, QTypeRevision()); } void QQmlPropertyCache::update(const QMetaObject *metaObject) @@ -732,7 +733,7 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject) methodIndexCacheStart = parent()->methodIndexCache.count() + parent()->methodIndexCacheStart; signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.count() + parent()->signalHandlerIndexCacheStart; stringCache.linkAndReserve(parent()->stringCache, reserve); - append(metaObject, -1); + append(metaObject, QTypeRevision()); } else { propertyIndexCacheStart = 0; methodIndexCacheStart = 0; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index bfd78eef88..9c576aab39 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -60,6 +60,7 @@ #include <private/qlinkedstringhash_p.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qvector.h> +#include <QtCore/qversionnumber.h> #include <private/qv4value_p.h> #include <private/qqmlpropertydata_p.h> @@ -80,7 +81,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount { public: QQmlPropertyCache(); - QQmlPropertyCache(const QMetaObject *, int metaObjectRevision = 0); + QQmlPropertyCache(const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero()); ~QQmlPropertyCache() override; void update(const QMetaObject *); @@ -92,7 +93,8 @@ public: QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); - QQmlPropertyCache *copyAndAppend(const QMetaObject *, int typeMinorVersion, + QQmlPropertyCache *copyAndAppend( + const QMetaObject *, QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); @@ -100,7 +102,7 @@ public: QQmlPropertyCache *copyAndReserve(int propertyCount, int methodCount, int signalCount, int enumCount); void appendProperty(const QString &, QQmlPropertyData::Flags flags, int coreIndex, - int propType, int revision, int notifyIndex); + int propType, QTypeRevision revision, int notifyIndex); void appendSignal(const QString &, QQmlPropertyData::Flags, int coreIndex, const int *types = nullptr, const QList<QByteArray> &names = QList<QByteArray>()); void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex, int returnType, @@ -173,8 +175,8 @@ public: QByteArray checksum(bool *ok); - int allowedRevision(int index) const { return allowedRevisionCache[index]; } - void setAllowedRevision(int index, int allowed) { allowedRevisionCache[index] = allowed; } + QTypeRevision allowedRevision(int index) const { return allowedRevisionCache[index]; } + void setAllowedRevision(int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; } private: friend class QQmlEnginePrivate; @@ -186,7 +188,7 @@ private: inline QQmlPropertyCache *copy(int reserve); - void append(const QMetaObject *, int typeMinorVersion, + void append(const QMetaObject *, QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); @@ -195,7 +197,7 @@ private: typedef QVector<QQmlPropertyData> IndexCache; typedef QLinkedStringMultiHash<QPair<int, QQmlPropertyData *> > StringCache; - typedef QVector<int> AllowedRevisionCache; + typedef QVector<QTypeRevision> AllowedRevisionCache; QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *, QQmlContextData *) const; QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *, QQmlContextData *) const; @@ -351,8 +353,9 @@ QQmlPropertyCache::overrideData(QQmlPropertyData *data) const bool QQmlPropertyCache::isAllowedInRevision(QQmlPropertyData *data) const { - return (data->metaObjectOffset() == -1 && data->revision() == 0) || - (allowedRevisionCache[data->metaObjectOffset()] >= data->revision()); + return (data->metaObjectOffset() == -1 && data->revision() == QTypeRevision::zero()) + || (allowedRevisionCache[data->metaObjectOffset()].toEncodedVersion<quint16>() + >= data->revision().toEncodedVersion<quint16>()); } int QQmlPropertyCache::propertyCount() const diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index 36581bda4e..c85c44eab7 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -119,9 +119,11 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating { if (instantiatingProperty) { if (instantiatingProperty->isQObject()) { - return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), instantiatingProperty->typeMinorVersion()); + return enginePrivate->rawPropertyCacheForType( + instantiatingProperty->propType(), + instantiatingProperty->typeVersion()); } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) { - return enginePrivate->cache(vtmo, instantiatingProperty->typeMinorVersion()); + return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); } } return QQmlRefPointer<QQmlPropertyCache>(); diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index a050a0bf0a..a02209521a 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -537,7 +537,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea pend = obj->propertiesEnd(); for ( ; p != pend; ++p, ++propertyIdx) { int propertyType = 0; - int propertTypeMinorVersion = 0; + QTypeRevision propertyTypeVersion = QTypeRevision::zero(); QQmlPropertyData::Flags propertyFlags; const QV4::CompiledData::BuiltinType type = p->builtinType(); @@ -556,7 +556,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea QQmlType qmltype; bool selfReference = false; - if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr, + if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType, &selfReference)) { return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type")); } @@ -598,7 +598,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea propertyType = qmltype.qListTypeId(); } else { propertyType = qmltype.typeId(); - propertTypeMinorVersion = qmltype.minorVersion(); + propertyTypeVersion = qmltype.version(); } } @@ -616,7 +616,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, - propertyType, propertTypeMinorVersion, effectiveSignalIndex); + propertyType, propertyTypeVersion, effectiveSignalIndex); effectiveSignalIndex++; } @@ -640,8 +640,8 @@ inline int QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter(const *customTypeName = typeName; QQmlType qmltype; bool selfReference = false; - if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType, - &selfReference)) + if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, + QQmlType::AnyRegistrationType, &selfReference)) return QMetaType::UnknownType; if (!qmltype.isComposite()) @@ -673,7 +673,7 @@ public: private: void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv); - QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); + QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; @@ -784,7 +784,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion, +inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv) { *type = 0; @@ -817,7 +817,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: lastAlias = targetAlias; } while (lastAlias->aliasToLocalAlias); - return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags, enginePriv); + return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv); } const int targetObjectIndex = objectForId(component, alias.targetObjectId); @@ -840,7 +840,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: else *type = typeRef->compilationUnit->metaTypeId; - *minorVersion = typeRef->minorVersion; + *version = typeRef->version; propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType; } else { @@ -919,9 +919,10 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); int type = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); QQmlPropertyData::Flags propertyFlags; - QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv); + QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &version, + &propertyFlags, enginePriv); if (error.isValid()) return error; @@ -931,7 +932,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: propertyCache->_defaultPropertyName = propertyName; propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, - type, minorVersion, effectiveSignalIndex++); + type, version, effectiveSignalIndex++); } return QQmlJS::DiagnosticMessage(); diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h index 7f70c34854..f21b502b50 100644 --- a/src/qml/qml/qqmlpropertydata_p.h +++ b/src/qml/qml/qqmlpropertydata_p.h @@ -53,6 +53,7 @@ #include <private/qobject_p.h> #include <QtCore/qglobal.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -251,7 +252,7 @@ public: bool isConstructor() const { return m_flags.isConstructor; } bool hasOverride() const { return overrideIndex() >= 0; } - bool hasRevision() const { return revision() != 0; } + bool hasRevision() const { return revision() != QTypeRevision::zero(); } bool isFullyResolved() const { return !m_flags.notFullyResolved; } @@ -290,12 +291,8 @@ public: m_coreIndex = qint16(idx); } - quint8 revision() const { return m_revision; } - void setRevision(quint8 rev) - { - Q_ASSERT(rev <= std::numeric_limits<quint8>::max()); - m_revision = quint8(rev); - } + QTypeRevision revision() const { return m_revision; } + void setRevision(QTypeRevision revision) { m_revision = revision; } /* If a property is a C++ type, then we store the minor * version of this type. @@ -315,12 +312,8 @@ public: * */ - quint8 typeMinorVersion() const { return m_typeMinorVersion; } - void setTypeMinorVersion(quint8 rev) - { - Q_ASSERT(rev <= std::numeric_limits<quint8>::max()); - m_typeMinorVersion = quint8(rev); - } + QTypeRevision typeVersion() const { return m_typeVersion; } + void setTypeVersion(QTypeRevision typeVersion) { m_typeVersion = typeVersion; } QQmlPropertyCacheMethodArguments *arguments() const { return m_arguments; } void setArguments(QQmlPropertyCacheMethodArguments *args) { m_arguments = args; } @@ -412,18 +405,20 @@ private: qint16 m_notifyIndex = -1; qint16 m_overrideIndex = -1; - quint8 m_revision = 0; - quint8 m_typeMinorVersion = 0; qint16 m_metaObjectOffset = -1; + quint16 m_reserved = 0; + + QTypeRevision m_revision = QTypeRevision::zero(); + QTypeRevision m_typeVersion = QTypeRevision::zero(); QQmlPropertyCacheMethodArguments *m_arguments = nullptr; StaticMetaCallFunction m_staticMetaCallFunction = nullptr; }; #if QT_POINTER_SIZE == 4 - Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 24); + Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 28); #else // QT_POINTER_SIZE == 8 - Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 32); + Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 40); #endif bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 8762dc328d..01bf1bede7 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -192,7 +192,10 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( QString typeName = stringAt(obj->inheritedTypeNameIndex); auto *objectType = resolvedType(obj->inheritedTypeNameIndex); if (objectType && objectType->type.isValid()) { - return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type.module()).arg(objectType->majorVersion).arg(objectType->minorVersion)); + return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.") + .arg(typeName).arg(name).arg(objectType->type.module()) + .arg(objectType->version.majorVersion()) + .arg(objectType->version.minorVersion())); } else { return recordError(binding->location, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name)); } @@ -212,7 +215,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( if (name.constData()->isUpper() && !binding->isAttachedProperty()) { QQmlType type; QQmlImportNamespace *typeNamespace = nullptr; - imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, nullptr, &typeNamespace); + imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, &typeNamespace); if (typeNamespace) return recordError(binding->location, tr("Invalid use of namespace")); return recordError(binding->location, tr("Invalid attached object assignment")); @@ -745,7 +748,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope // 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, -1); + QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType, + QTypeRevision()); if (propertyMetaObject) { // Will be true if the assigned type inherits propertyMetaObject diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 28fefca239..78cf187f07 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) - : regType(type), iid(nullptr), typeId(0), listId(0), revision(0), + : regType(type), iid(nullptr), typeId(0), listId(0), revision(QTypeRevision::zero()), containsRevisionedAttributes(false), baseMetaObject(nullptr), index(-1), isSetup(false), isEnumFromCacheSetup(false), isEnumFromBaseSetup(false), haveSuperType(false) @@ -132,34 +132,29 @@ QHashedString QQmlType::module() const return d->module; } -int QQmlType::majorVersion() const +QTypeRevision QQmlType::version() const { if (!d) - return -1; - return d->version_maj; -} - -int QQmlType::minorVersion() const -{ - if (!d) - return -1; - return d->version_min; + return QTypeRevision(); + return d->version; } -bool QQmlType::availableInVersion(int vmajor, int vminor) const +bool QQmlType::availableInVersion(QTypeRevision version) const { - Q_ASSERT(vmajor >= 0 && vminor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); if (!d) return false; - return vmajor == d->version_maj && vminor >= d->version_min; + return version.majorVersion() == d->version.majorVersion() + && version.minorVersion() >= d->version.minorVersion(); } -bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const +bool QQmlType::availableInVersion(const QHashedStringRef &module, QTypeRevision version) const { - Q_ASSERT(vmajor >= 0 && vminor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); if (!d) return false; - return module == d->module && vmajor == d->version_maj && vminor >= d->version_min; + return module == d->module && version.majorVersion() == d->version.majorVersion() + && version.minorVersion() >= d->version.minorVersion(); } QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlEnginePrivate *engine) const @@ -629,9 +624,9 @@ bool QQmlType::containsRevisionedAttributes() const return d->containsRevisionedAttributes; } -int QQmlType::metaObjectRevision() const +QTypeRevision QQmlType::metaObjectRevision() const { - return d ? d->revision : -1; + return d ? d->revision : QTypeRevision(); } QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h index 387baa74bb..c33cad7c88 100644 --- a/src/qml/qml/qqmltype_p.h +++ b/src/qml/qml/qqmltype_p.h @@ -60,6 +60,7 @@ #include <QtQml/qjsvalue.h> #include <QtCore/qobject.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -98,11 +99,10 @@ public: QString elementName() const; QHashedString module() const; - int majorVersion() const; - int minorVersion() const; + QTypeRevision version() const; - bool availableInVersion(int vmajor, int vminor) const; - bool availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const; + bool availableInVersion(QTypeRevision version) const; + bool availableInVersion(const QHashedStringRef &module, QTypeRevision version) const; QObject *create() const; void create(QObject **, void **, size_t) const; @@ -129,7 +129,7 @@ public: const QMetaObject *metaObject() const; const QMetaObject *baseMetaObject() const; - int metaObjectRevision() const; + QTypeRevision metaObjectRevision() const; bool containsRevisionedAttributes() const; QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlEnginePrivate *engine) const; diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h index 43344827db..0d493c4871 100644 --- a/src/qml/qml/qqmltype_p_p.h +++ b/src/qml/qml/qqmltype_p_p.h @@ -157,11 +157,10 @@ public: QHashedString module; QString name; QString elementName; - int version_maj; - int version_min; int typeId; int listId; - int revision; + QTypeRevision version; + QTypeRevision revision; mutable bool containsRevisionedAttributes; mutable QQmlType superType; const QMetaObject *baseMetaObject; diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 842ca697e0..06d5c47b53 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -257,7 +257,7 @@ QString QQmlTypeCompiler::bindingAsString(const QmlIR::Object *object, int scrip return object->bindingAsString(document, scriptIndex); } -void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion) +void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, QTypeRevision version) { const quint32 moduleIdx = registerString(module); const quint32 qualifierIdx = registerString(qualifier); @@ -272,8 +272,7 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier auto pool = memoryPool(); QV4::CompiledData::Import *import = pool->New<QV4::CompiledData::Import>(); import->type = QV4::CompiledData::Import::ImportLibrary; - import->majorVersion = majorVersion; - import->minorVersion = minorVersion; + import->version = version; import->uriIndex = moduleIdx; import->qualifierIndex = qualifierIdx; document->imports.append(import); @@ -394,7 +393,10 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio auto *typeRef = resolvedType(obj->inheritedTypeNameIndex); const QQmlType type = typeRef ? typeRef->type : QQmlType(); if (type.isValid()) { - COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type.module()).arg(type.majorVersion()).arg(type.minorVersion())); + COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.") + .arg(typeName).arg(originalPropertyName).arg(type.module()) + .arg(type.version().majorVersion()) + .arg(type.version().minorVersion())); } else { COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName)); } @@ -816,7 +818,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (!pd || !pd->isQObject()) continue; - QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion()); + QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType( + pd->propType(), pd->typeVersion()); const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr; while (mo) { if (mo == &QQmlComponent::staticMetaObject) @@ -832,7 +835,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI Q_ASSERT(componentType.isValid()); const QString qualifier = QStringLiteral("QmlInternals"); - compiler->addImport(componentType.module(), qualifier, componentType.majorVersion(), componentType.minorVersion()); + compiler->addImport(componentType.module(), qualifier, componentType.version()); QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>(); syntheticComponent->init(pool, compiler->registerString(qualifier + QLatin1Char('.') + componentType.elementName()), compiler->registerString(QString())); @@ -842,8 +845,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (!containsResolvedType(syntheticComponent->inheritedTypeNameIndex)) { auto typeRef = new QV4::ResolvedTypeReference; typeRef->type = componentType; - typeRef->majorVersion = componentType.majorVersion(); - typeRef->minorVersion = componentType.minorVersion(); + typeRef->version = componentType.version(); insertResolvedType(syntheticComponent->inheritedTypeNameIndex, typeRef); } diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 319df8673b..050c75b30d 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -124,7 +124,7 @@ public: QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const; - void addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion); + void addImport(const QString &module, const QString &qualifier, QTypeRevision version); QV4::ResolvedTypeReference *resolvedType(int id) const { diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index f7abe67921..ec9061d04e 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -182,8 +182,8 @@ bool QQmlTypeData::tryLoadFromDiskCache() const QV4::CompiledData::Import *import = m_compiledData->importAt(i); if (m_compiledData->stringAt(import->uriIndex) == QLatin1String(".") && import->qualifierIndex == 0 - && import->majorVersion == -1 - && import->minorVersion == -1) { + && !import->version.hasMajorVersion() + && !import->version.hasMinorVersion()) { QList<QQmlError> errors; auto pendingImport = std::make_shared<PendingImport>(this, import); if (!fetchQmldir(qmldirUrl, pendingImport, 1, &errors)) { @@ -213,9 +213,9 @@ bool QQmlTypeData::tryLoadFromDiskCache() QQmlType containingType; auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - int major = -1, minor = -1; + QTypeRevision version; QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns); + m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); for (auto&& ic: ics) { QString const nameString = m_compiledData->stringAt(ic.nameIndex); QByteArray const name = nameString.toUtf8(); @@ -651,9 +651,9 @@ void QQmlTypeData::continueLoadFromIR() { QQmlType containingType; auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - int major = -1, minor = -1; + QTypeRevision version; QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns); + m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); for (auto const& object: m_document->objects) { for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) { QString const nameString = m_document->stringAt(it->nameIndex); @@ -679,8 +679,7 @@ void QQmlTypeData::continueLoadFromIR() // This qmldir is for the implicit import auto implicitImport = std::make_shared<PendingImport>(); implicitImport->uri = QLatin1String("."); - implicitImport->majorVersion = -1; - implicitImport->minorVersion = -1; + implicitImport->version = QTypeRevision(); QList<QQmlError> errors; if (!fetchQmldir(qmldirUrl, implicitImport, 1, &errors)) { @@ -824,11 +823,8 @@ void QQmlTypeData::resolveTypes() typeName = csRef.typeName; } - int majorVersion = csRef.majorVersion > -1 ? csRef.majorVersion : -1; - int minorVersion = csRef.minorVersion > -1 ? csRef.minorVersion : -1; - - if (!resolveType(typeName, majorVersion, minorVersion, ref, -1, -1, true, - QQmlType::CompositeSingletonType)) + QTypeRevision version = csRef.version; + if (!resolveType(typeName, version, ref, -1, -1, true, QQmlType::CompositeSingletonType)) return; if (ref.type.isCompositeSingleton()) { @@ -851,14 +847,13 @@ void QQmlTypeData::resolveTypes() const bool reportErrors = unresolvedRef->errorWhenNotFound; - int majorVersion = -1; - int minorVersion = -1; + QTypeRevision version; const QString name = stringAt(unresolvedRef.key()); bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference; - if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, + if (!resolveType(name, version, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors, QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors) return; @@ -878,8 +873,7 @@ void QQmlTypeData::resolveTypes() } } } - ref.majorVersion = majorVersion; - ref.minorVersion = minorVersion; + ref.version = version; ref.location.line = unresolvedRef->location.line; ref.location.column = unresolvedRef->location.column; @@ -962,13 +956,10 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( return qQmlCompileError(resolvedType->location, reason); } - if (ref->type.containsRevisionedAttributes()) { - ref->typePropertyCache = engine->cache(ref->type, - resolvedType->minorVersion); - } + if (ref->type.containsRevisionedAttributes()) + ref->typePropertyCache = engine->cache(ref->type, resolvedType->version); } - ref->majorVersion = resolvedType->majorVersion; - ref->minorVersion = resolvedType->minorVersion; + ref->version = resolvedType->version; ref->doDynamicTypeCheck(); resolvedTypeCache->insert(resolvedType.key(), ref.take()); } @@ -976,7 +967,7 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( return noError; } -bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, +bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version, TypeReference &ref, int lineNumber, int columnNumber, bool reportErrors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) @@ -984,7 +975,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; - bool typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion, + bool typeFound = m_importCache.resolveType(typeName, &ref.type, &version, &typeNamespace, &errors, registrationType, typeRecursionDetected); if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { @@ -992,7 +983,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & if (loadImplicitImport()) { // Try again to find the type errors.clear(); - typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion, + typeFound = m_importCache.resolveType(typeName, &ref.type, &version, &typeNamespace, &errors, registrationType, typeRecursionDetected); } else { diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index d894090b36..1506ee2010 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -62,12 +62,11 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob public: struct TypeReference { - TypeReference() : majorVersion(0), minorVersion(0), needsCreation(true) {} + TypeReference() : version(QTypeRevision::zero()), needsCreation(true) {} QV4::CompiledData::Location location; QQmlType type; - int majorVersion; - int minorVersion; + QTypeRevision version; QQmlRefPointer<QQmlTypeData> typeData; bool selfReference = false; QString prefix; // used by CompositeSingleton types @@ -134,7 +133,7 @@ private: const QV4::CompiledData::DependentTypesHasher &dependencyHasher); void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::ResolvedTypeReferenceMap &resolvedTypeCache); - bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, + bool resolveType(const QString &typeName, QTypeRevision &version, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index e9a38945fa..01f70b1703 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -487,8 +487,7 @@ QQmlTypeLoader::Blob::PendingImport::PendingImport(QQmlTypeLoader::Blob *blob, c type = static_cast<QV4::CompiledData::Import::ImportType>(quint32(import->type)); uri = blob->stringAt(import->uriIndex); qualifier = blob->stringAt(import->qualifierIndex); - majorVersion = import->majorVersion; - minorVersion = import->minorVersion; + version = import->version; location = import->location; } @@ -578,12 +577,13 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo QString qmldirUrl; const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir( - importDatabase, import->uri, import->majorVersion, import->minorVersion, + importDatabase, import->uri, import->version, &qmldirFilePath, &qmldirUrl); if (qmldirResult == QQmlImports::QmldirFound) { // This is a local library import - if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, qmldirFilePath, qmldirUrl, false, errors)) + if (!m_importCache.addLibraryImport( + importDatabase, import->uri, import->qualifier, + import->version, qmldirFilePath, qmldirUrl, false, errors)) return false; if (!loadImportDependencies(import, qmldirFilePath, errors)) @@ -606,10 +606,10 @@ 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->majorVersion))) { - if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, QString(), QString(), false, errors)) + && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->version))) { + if (!m_importCache.addLibraryImport( + importDatabase, import->uri, import->qualifier, import->version, + QString(), QString(), false, errors)) return false; } else { // We haven't yet resolved this import @@ -624,13 +624,15 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo : QQmlImportDatabase::Remote); if (!remotePathList.isEmpty()) { // Add this library and request the possible locations for it - if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, QString(), QString(), true, errors)) + if (!m_importCache.addLibraryImport( + importDatabase, import->uri, import->qualifier, import->version, + QString(), QString(), true, errors)) return false; // Probe for all possible locations int priority = 0; - const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion); + const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( + import->uri, remotePathList, import->version); for (const QString &qmldirPath : qmlDirPaths) { if (interceptor) { QUrl url = interceptor->intercept( @@ -663,8 +665,8 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo incomplete = true; } - if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, incomplete, errors)) + if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier, + import->version, incomplete, errors)) return false; if (incomplete) { @@ -703,8 +705,7 @@ bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport auto dependencyImport = std::make_shared<PendingImport>(); dependencyImport->uri = implicitImports; dependencyImport->qualifier = currentImport->qualifier; - dependencyImport->majorVersion = currentImport->majorVersion; - dependencyImport->minorVersion = currentImport->minorVersion; + dependencyImport->version = currentImport->version; if (!addImport(dependencyImport, errors)) return false; } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index adecf61896..a1ba2967e3 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -97,8 +97,7 @@ public: QString uri; QString qualifier; - int majorVersion = -1; - int minorVersion = -1; + QTypeRevision version; QV4::CompiledData::Location location; diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp index 9d6f269030..e6bf796d74 100644 --- a/src/qml/qml/qqmltypemodule.cpp +++ b/src/qml/qml/qqmltypemodule.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE -QQmlTypeModule::QQmlTypeModule(const QString &module, int majorVersion) +QQmlTypeModule::QQmlTypeModule(const QString &module, quint8 majorVersion) : d(new QQmlTypeModulePrivate(module, majorVersion)) { } @@ -61,23 +61,23 @@ QString QQmlTypeModule::module() const return d->module; } -int QQmlTypeModule::majorVersion() const +quint8 QQmlTypeModule::majorVersion() const { // No need to lock. d->majorVersion is const return d->majorVersion; } -int QQmlTypeModule::minimumMinorVersion() const +quint8 QQmlTypeModule::minimumMinorVersion() const { return d->minMinorVersion.loadRelaxed(); } -int QQmlTypeModule::maximumMinorVersion() const +quint8 QQmlTypeModule::maximumMinorVersion() const { return d->maxMinorVersion.loadRelaxed(); } -void QQmlTypeModule::addMinorVersion(int version) +void QQmlTypeModule::addMinorVersion(quint8 version) { for (int oldVersion = d->minMinorVersion.loadRelaxed(); oldVersion > version && !d->minMinorVersion.testAndSetOrdered(oldVersion, version); @@ -93,16 +93,16 @@ void QQmlTypeModule::addMinorVersion(int version) void QQmlTypeModule::add(QQmlTypePrivate *type) { QMutexLocker lock(&d->mutex); - addMinorVersion(type->version_min); + addMinorVersion(type->version.minorVersion()); QList<QQmlTypePrivate *> &list = d->typeHash[type->elementName]; for (int ii = 0; ii < list.count(); ++ii) { QQmlTypePrivate *in_list = list.at(ii); Q_ASSERT(in_list); - if (in_list->version_min < type->version_min) { + if (in_list->version.minorVersion() < type->version.minorVersion()) { list.insert(ii, type); return; - } else if (in_list->version_min == type->version_min) { + } else if (in_list->version.minorVersion() == type->version.minorVersion()) { list[ii] = type; return; } @@ -137,26 +137,26 @@ void QQmlTypeModule::lock() d->locked.storeRelaxed(1); } -QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const +QQmlType QQmlTypeModule::type(const QHashedStringRef &name, QTypeRevision version) const { QMutexLocker lock(&d->mutex); QList<QQmlTypePrivate *> *types = d->typeHash.value(name); if (types) { for (int ii = 0; ii < types->count(); ++ii) - if (types->at(ii)->version_min <= minor) + if (types->at(ii)->version.minorVersion() <= version.minorVersion()) return QQmlType(types->at(ii)); } return QQmlType(); } -QQmlType QQmlTypeModule::type(const QV4::String *name, int minor) const +QQmlType QQmlTypeModule::type(const QV4::String *name, QTypeRevision version) const { QMutexLocker lock(&d->mutex); QList<QQmlTypePrivate *> *types = d->typeHash.value(name); if (types) { for (int ii = 0; ii < types->count(); ++ii) - if (types->at(ii)->version_min <= minor) + if (types->at(ii)->version.minorVersion() <= version.minorVersion()) return QQmlType(types->at(ii)); } diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h index b84a91b5db..d3149567a3 100644 --- a/src/qml/qml/qqmltypemodule_p.h +++ b/src/qml/qml/qqmltypemodule_p.h @@ -53,6 +53,7 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qstring.h> +#include <QtCore/qversionnumber.h> #include <functional> @@ -72,7 +73,7 @@ class QQmlTypeModulePrivate; class QQmlTypeModule { public: - QQmlTypeModule(const QString &uri = QString(), int majorVersion = 0); + QQmlTypeModule(const QString &uri = QString(), quint8 majorVersion = 0); ~QQmlTypeModule(); void add(QQmlTypePrivate *); @@ -82,14 +83,14 @@ public: void lock(); QString module() const; - int majorVersion() const; + quint8 majorVersion() const; - void addMinorVersion(int minorVersion); - int minimumMinorVersion() const; - int maximumMinorVersion() const; + void addMinorVersion(quint8 minorVersion); + quint8 minimumMinorVersion() const; + quint8 maximumMinorVersion() const; - QQmlType type(const QHashedStringRef &, int) const; - QQmlType type(const QV4::String *, int) const; + QQmlType type(const QHashedStringRef &, QTypeRevision version) const; + QQmlType type(const QV4::String *, QTypeRevision version) const; void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const; diff --git a/src/qml/qml/qqmltypemodule_p_p.h b/src/qml/qml/qqmltypemodule_p_p.h index b1dab1c4a0..5d4d2e458a 100644 --- a/src/qml/qml/qqmltypemodule_p_p.h +++ b/src/qml/qml/qqmltypemodule_p_p.h @@ -62,15 +62,15 @@ QT_BEGIN_NAMESPACE class QQmlTypeModulePrivate { public: - QQmlTypeModulePrivate(QString module, int majorVersion) : + QQmlTypeModulePrivate(QString module, quint8 majorVersion) : module(std::move(module)), majorVersion(majorVersion) {} const QString module; - const int majorVersion = 0; + const quint8 majorVersion = 0; // Can only ever decrease - QAtomicInt minMinorVersion = std::numeric_limits<int>::max(); + QAtomicInt minMinorVersion = std::numeric_limits<quint8>::max(); // Can only ever increase QAtomicInt maxMinorVersion = 0; diff --git a/src/qml/qml/qqmltypemoduleversion.cpp b/src/qml/qml/qqmltypemoduleversion.cpp index bbbfa1a7b6..06467509d0 100644 --- a/src/qml/qml/qqmltypemoduleversion.cpp +++ b/src/qml/qml/qqmltypemoduleversion.cpp @@ -49,11 +49,11 @@ QQmlTypeModuleVersion::QQmlTypeModuleVersion() { } -QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, int minor) - : m_module(module), m_minor(minor) +QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, QTypeRevision version) + : m_module(module), m_minor(version.minorVersion()) { Q_ASSERT(m_module); - Q_ASSERT(m_minor >= 0); + Q_ASSERT(QTypeRevision::isValidSegment(m_minor)); } QQmlTypeModuleVersion::QQmlTypeModuleVersion(const QQmlTypeModuleVersion &o) @@ -73,7 +73,7 @@ QQmlTypeModule *QQmlTypeModuleVersion::module() const return m_module; } -int QQmlTypeModuleVersion::minorVersion() const +quint8 QQmlTypeModuleVersion::minorVersion() const { return m_minor; } @@ -82,14 +82,14 @@ QQmlType QQmlTypeModuleVersion::type(const QHashedStringRef &name) const { if (!m_module) return QQmlType(); - return m_module->type(name, m_minor); + return m_module->type(name, QTypeRevision::fromMinorVersion(m_minor)); } QQmlType QQmlTypeModuleVersion::type(const QV4::String *name) const { if (!m_module) return QQmlType(); - return m_module->type(name, m_minor); + return m_module->type(name, QTypeRevision::fromMinorVersion(m_minor)); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypemoduleversion_p.h b/src/qml/qml/qqmltypemoduleversion_p.h index 20f4709ecb..ecbab54bea 100644 --- a/src/qml/qml/qqmltypemoduleversion_p.h +++ b/src/qml/qml/qqmltypemoduleversion_p.h @@ -52,6 +52,7 @@ // #include <QtQml/qtqmlglobal.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -67,19 +68,19 @@ class QQmlTypeModuleVersion { public: QQmlTypeModuleVersion(); - QQmlTypeModuleVersion(QQmlTypeModule *, int); + QQmlTypeModuleVersion(QQmlTypeModule *, QTypeRevision); QQmlTypeModuleVersion(const QQmlTypeModuleVersion &); QQmlTypeModuleVersion &operator=(const QQmlTypeModuleVersion &); QQmlTypeModule *module() const; - int minorVersion() const; + quint8 minorVersion() const; QQmlType type(const QHashedStringRef &) const; QQmlType type(const QV4::String *) const; private: QQmlTypeModule *m_module; - int m_minor; + quint8 m_minor; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp index 1015403226..45333668e3 100644 --- a/src/qml/qml/qqmltypenamecache.cpp +++ b/src/qml/qml/qqmltypenamecache.cpp @@ -101,7 +101,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name) QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(name, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(name, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } @@ -129,7 +129,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name, QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } @@ -155,7 +155,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml QList<QQmlError> errors; QQmlType t; bool typeRecursionDetected = false; - bool typeFound = m_imports.resolveType(typeName, &t, nullptr, nullptr, &typeNamespace, &errors, + bool typeFound = m_imports.resolveType(typeName, &t, nullptr, &typeNamespace, &errors, QQmlType::AnyRegistrationType, recursionRestriction == QQmlImport::AllowRecursion ? &typeRecursionDetected : nullptr); if (typeFound) { @@ -191,7 +191,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index ff664adbe7..901b7a6fd7 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -293,7 +293,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, nullptr, nullptr, @@ -302,7 +302,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index 36b47a3302..8d20490d5e 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -60,17 +60,17 @@ static int parseInt(const QStringRef &str, bool *ok) return number; } -static bool parseVersion(const QString &str, int *major, int *minor) +static QTypeRevision parseVersion(const QString &str) { const int dotIndex = str.indexOf(QLatin1Char('.')); if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) { bool ok = false; - *major = parseInt(QStringRef(&str, 0, dotIndex), &ok); - if (ok) - *minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok); - return ok; + const int major = parseInt(QStringRef(&str, 0, dotIndex), &ok); + if (!ok) return QTypeRevision(); + const int minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok); + return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision(); } - return false; + return QTypeRevision(); } void QQmlDirParser::clear() @@ -203,7 +203,7 @@ bool QQmlDirParser::parse(const QString &source) QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1)); continue; } - Component entry(sections[1], sections[2], -1, -1); + Component entry(sections[1], sections[2], QTypeRevision()); entry.internal = true; _components.insert(entry.typeName, entry); } else if (sections[0] == QLatin1String("singleton")) { @@ -214,16 +214,16 @@ bool QQmlDirParser::parse(const QString &source) } else if (sectionCount == 3) { // handle qmldir directory listing case where singleton is defined in the following pattern: // singleton TestSingletonType TestSingletonType.qml - Component entry(sections[1], sections[2], -1, -1); + Component entry(sections[1], sections[2], QTypeRevision()); entry.singleton = true; _components.insert(entry.typeName, entry); } else { // handle qmldir module listing case where singleton is defined in the following pattern: // singleton TestSingletonType 2.0 TestSingletonType20.qml - int major, minor; - if (parseVersion(sections[2], &major, &minor)) { + const QTypeRevision version = parseVersion(sections[2]); + if (version.isValid()) { const QString &fileName = sections[3]; - Component entry(sections[1], fileName, major, minor); + Component entry(sections[1], fileName, version); entry.singleton = true; _components.insert(entry.typeName, entry); } else { @@ -253,9 +253,9 @@ bool QQmlDirParser::parse(const QString &source) continue; } - int major, minor; - if (parseVersion(sections[2], &major, &minor)) { - Component entry(sections[1], QString(), major, minor); + const QTypeRevision version = parseVersion(sections[2]); + if (version.isValid()) { + Component entry(sections[1], QString(), version); entry.internal = true; _dependencies.insert(entry.typeName, entry); } else { @@ -270,19 +270,19 @@ bool QQmlDirParser::parse(const QString &source) _imports << sections[1]; } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) - const Component entry(sections[0], sections[1], -1, -1); + const Component entry(sections[0], sections[1], QTypeRevision()); _components.insert(entry.typeName, entry); } else if (sectionCount == 3) { - int major, minor; - if (parseVersion(sections[1], &major, &minor)) { + const QTypeRevision version = parseVersion(sections[1]); + if (version.isValid()) { const QString &fileName = sections[2]; if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) { // A 'js' extension indicates a namespaced script import - const Script entry(sections[0], fileName, major, minor); + const Script entry(sections[0], fileName, version); _scripts.append(entry); } else { - const Component entry(sections[0], fileName, major, minor); + const Component entry(sections[0], fileName, version); _components.insert(entry.typeName, entry); } } else { @@ -387,15 +387,17 @@ QString QQmlDirParser::className() const QDebug &operator<< (QDebug &debug, const QQmlDirParser::Component &component) { - const QString output = QStringLiteral("{%1 %2.%3}"). - arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion); + const QString output = QStringLiteral("{%1 %2.%3}") + .arg(component.typeName).arg(component.version.majorVersion()) + .arg(component.version.minorVersion()); return debug << qPrintable(output); } QDebug &operator<< (QDebug &debug, const QQmlDirParser::Script &script) { - const QString output = QStringLiteral("{%1 %2.%3}"). - arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion); + const QString output = QStringLiteral("{%1 %2.%3}") + .arg(script.nameSpace).arg(script.version.majorVersion()) + .arg(script.version.minorVersion()); return debug << qPrintable(output); } diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index 3696a1aa12..ccdac8f484 100644 --- a/src/qml/qmldirparser/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -54,6 +54,7 @@ #include <QtCore/QUrl> #include <QtCore/QHash> #include <QtCore/QDebug> +#include <QtCore/QTypeRevision> #include <private/qtqmlcompilerglobal_p.h> #include <private/qqmljsengine_p.h> #include <private/qqmljsdiagnosticmessage_p.h> @@ -101,8 +102,8 @@ public: { Component() = default; - Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) - : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), + Component(const QString &typeName, const QString &fileName, QTypeRevision version) + : typeName(typeName), fileName(fileName), version(version), internal(false), singleton(false) { checkNonRelative("Component", typeName, fileName); @@ -110,8 +111,7 @@ public: QString typeName; QString fileName; - int majorVersion = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); bool internal = false; bool singleton = false; }; @@ -120,16 +120,15 @@ public: { Script() = default; - Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) - : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) + Script(const QString &nameSpace, const QString &fileName, QTypeRevision version) + : nameSpace(nameSpace), fileName(fileName), version(version) { checkNonRelative("Script", nameSpace, fileName); } QString nameSpace; QString fileName; - int majorVersion = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); }; QMultiHash<QString,Component> components() const; diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index 1f437a08c7..54bbccd617 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -1032,9 +1032,9 @@ int QQmlAdaptorModel::indexAt(int row, int column) const return column * rowCount() + row; } -void QQmlAdaptorModel::useImportVersion(int minorVersion) +void QQmlAdaptorModel::useImportVersion(QTypeRevision revision) { - modelItemRevision = minorVersion; + modelItemRevision = revision; } void QQmlAdaptorModel::objectDestroyed(QObject *) diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h index ee4862f3b4..d243edda92 100644 --- a/src/qmlmodels/qqmladaptormodel_p.h +++ b/src/qmlmodels/qqmladaptormodel_p.h @@ -115,7 +115,7 @@ public: QPersistentModelIndex rootIndex; QQmlListAccessor list; - int modelItemRevision = 0; + QTypeRevision modelItemRevision = QTypeRevision::zero(); QQmlAdaptorModel(); ~QQmlAdaptorModel(); @@ -132,7 +132,7 @@ public: int columnAt(int index) const; int indexAt(int row, int column) const; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision revision); inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); } inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index 29c307a47a..c1f9df3114 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -83,9 +83,9 @@ QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject { } -void QQmlTableInstanceModel::useImportVersion(int minorVersion) +void QQmlTableInstanceModel::useImportVersion(QTypeRevision version) { - m_adaptorModel.useImportVersion(minorVersion); + m_adaptorModel.useImportVersion(version); } QQmlTableInstanceModel::~QQmlTableInstanceModel() diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 661ea3a3aa..7e28984789 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -89,7 +89,7 @@ public: QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr); ~QQmlTableInstanceModel() override; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision version); int count() const override { return m_adaptorModel.count(); } int rows() const { return m_adaptorModel.rowCount(); } diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 49c9fccb66..c22f349ea0 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -414,7 +414,7 @@ int main(int argc, char **argv) creator.setOwnTypes(std::move(types)); creator.setForeignTypes(std::move(foreignTypes)); creator.setModule(module); - creator.setMajorVersion(parser.value(majorVersionOption).toInt()); + creator.setVersion(QTypeRevision::fromVersion(parser.value(majorVersionOption).toInt(), 0)); creator.generate(parser.value(pluginTypesOption), parser.value(dependenciesOption)); return EXIT_SUCCESS; diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 15a8113ac8..aceab7c2b1 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -27,18 +27,19 @@ ****************************************************************************/ #include "qmltypesclassdescription.h" +#include "qmltypescreator.h" #include <QtCore/qjsonarray.h> static void collectExtraVersions(const QJsonObject *component, const QString &key, - QList<int> &extraVersions) + QList<QTypeRevision> &extraVersions) { const QJsonArray &items = component->value(key).toArray(); for (const QJsonValue &item : items) { const QJsonObject obj = item.toObject(); const auto revision = obj.find(QLatin1String("revision")); if (revision != obj.end()) { - const int extraVersion = revision.value().toInt(); + const auto extraVersion = QTypeRevision::fromEncodedVersion(revision.value().toInt()); if (!extraVersions.contains(extraVersion)) extraVersions.append(extraVersion); } @@ -72,11 +73,12 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, if (defaultProp.isEmpty()) defaultProp = value; } else if (name == QLatin1String("QML.AddedInMinorVersion")) { + const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt()); if (topLevel) { - addedInRevision = value.toInt(); - revisions.append(value.toInt()); + addedInRevision = revision; + revisions.append(revision); } else if (!elementName.isEmpty()) { - revisions.append(value.toInt()); + revisions.append(revision); } } @@ -90,7 +92,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, else if (value != QLatin1String("anonymous")) elementName = value; } else if (name == QLatin1String("QML.RemovedInMinorVersion")) { - removedInRevision = value.toInt(); + removedInRevision = QTypeRevision::fromEncodedVersion(value.toInt()); } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { @@ -147,9 +149,9 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } } - if (addedInRevision == -1) { - revisions.append(0); - addedInRevision = 0; + if (!addedInRevision.isValid()) { + revisions.append(QTypeRevision::zero()); + addedInRevision = QTypeRevision::zero(); } std::sort(revisions.begin(), revisions.end()); diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 8f3a6ea124..8222016faf 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -33,6 +33,7 @@ #include <QtCore/qjsonobject.h> #include <QtCore/qvector.h> #include <QtCore/qset.h> +#include <QtCore/qversionnumber.h> struct QmlTypesClassDescription { @@ -41,9 +42,9 @@ struct QmlTypesClassDescription QString defaultProp; QString superClass; QString attachedType; - QList<int> revisions; - int addedInRevision = -1; - int removedInRevision = -1; + QList<QTypeRevision> revisions; + QTypeRevision addedInRevision; + QTypeRevision removedInRevision; bool isCreatable = true; bool isSingleton = false; bool isRootClass = false; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 911120027e..8991ee42b6 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -35,6 +35,7 @@ #include <QtCore/qsavefile.h> #include <QtCore/qfile.h> #include <QtCore/qjsondocument.h> +#include <QtCore/qversionnumber.h> static QString enquote(const QString &string) { @@ -63,13 +64,11 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle QStringList metaObjects; for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) { - const int revision = *it; + const QTypeRevision revision = *it; if (revision < collector.addedInRevision) continue; - if (collector.removedInRevision > collector.addedInRevision - && revision >= collector.removedInRevision) { + if (collector.removedInRevision.isValid() && !(revision < collector.removedInRevision)) break; - } if (collector.isBuiltin) { exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); @@ -78,8 +77,8 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4") .arg(m_module).arg(collector.elementName) - .arg(m_majorVersion).arg(revision))); - metaObjects.append(QString::number(revision)); + .arg(m_version.majorVersion()).arg(revision.minorVersion()))); + metaObjects.append(QString::number(revision.toEncodedVersion<quint16>())); } m_qml.writeArrayBinding(QLatin1String("exports"), exports); diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h index 9207a64b7e..2ef4e8ff4b 100644 --- a/src/qmltyperegistrar/qmltypescreator.h +++ b/src/qmltyperegistrar/qmltypescreator.h @@ -45,7 +45,7 @@ public: void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); } void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); } void setModule(QString module) { m_module = std::move(module); } - void setMajorVersion(int majorVersion) { m_majorVersion = majorVersion; } + void setVersion(QTypeRevision version) { m_version = version; } private: void writeClassProperties(const QmlTypesClassDescription &collector); @@ -62,7 +62,22 @@ private: QVector<QJsonObject> m_ownTypes; QVector<QJsonObject> m_foreignTypes; QString m_module; - int m_majorVersion = 0; + QTypeRevision m_version = QTypeRevision::zero(); }; +QT_BEGIN_NAMESPACE + +// We cannot generally assume that the unspecified version is smaller than any specified one. +// Therefore, this operator< should not move to QtCore. +inline bool operator<(QTypeRevision lhs, QTypeRevision rhs) +{ + return lhs.hasMajorVersion() + ? (rhs.hasMajorVersion() + && lhs.toEncodedVersion<quint16>() < rhs.toEncodedVersion<quint16>()) + : (rhs.hasMajorVersion() + || lhs.minorVersion() < rhs.minorVersion()); +} + +QT_END_NAMESPACE + #endif // QMLTYPESCREATOR_H diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index ed5fdf3a4a..4fd9158f4a 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -210,14 +210,14 @@ static bool isCrashingType(const QQmlType &type) return false; } -QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) +QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context) { ComponentCompleteDisabler disableComponentComplete; Q_UNUSED(disableComponentComplete) QObject *object = nullptr; - QQmlType type = QQmlMetaType::qmlType(typeName, majorNumber, minorNumber); + QQmlType type = QQmlMetaType::qmlType(typeName, version); if (isCrashingType(type)) { object = new QObject; @@ -242,7 +242,8 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in if (!object) { qWarning() << "QuickDesigner: Cannot create an object of type" - << QString::fromLatin1("%1 %2,%3").arg(typeName).arg(majorNumber).arg(minorNumber) + << QString::fromLatin1("%1 %2,%3").arg(typeName) + .arg(version.majorVersion()).arg(version.minorVersion()) << "- type isn't known to declarative meta type system"; } diff --git a/src/quick/designer/qquickdesignersupportitems_p.h b/src/quick/designer/qquickdesignersupportitems_p.h index 8c5a44d9fe..93b4c529fa 100644 --- a/src/quick/designer/qquickdesignersupportitems_p.h +++ b/src/quick/designer/qquickdesignersupportitems_p.h @@ -58,6 +58,7 @@ #include <QVariant> #include <QList> #include <QByteArray> +#include <QTypeRevision> #include <QQmlContext> #include <QQmlListReference> @@ -66,7 +67,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QQuickDesignerSupportItems { public: - static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context); + static QObject *createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context); static QObject *createComponent(const QUrl &componentUrl, QQmlContext *context); static void tweakObjects(QObject *object); static bool objectWasDeleted(QObject *object); diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 66e89f0a09..496aea73d1 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -2121,15 +2121,17 @@ void QQuickTableViewPrivate::fixup(QQuickFlickablePrivate::AxisData &data, qreal QQuickFlickablePrivate::fixup(data, minExtent, maxExtent); } -int QQuickTableViewPrivate::resolveImportVersion() +QTypeRevision QQuickTableViewPrivate::resolveImportVersion() { const auto data = QQmlData::get(q_func()); if (!data || !data->propertyCache) - return 0; + return QTypeRevision::zero(); const auto cppMetaObject = data->propertyCache->firstCppMetaObject(); const auto qmlTypeView = QQmlMetaType::qmlType(cppMetaObject); - return qmlTypeView.minorVersion(); + + // TODO: did we rather want qmlTypeView.revision() here? + return qmlTypeView.metaObjectRevision(); } void QQuickTableViewPrivate::createWrapperModel() diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index c629ae0a5d..03fe019916 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -395,7 +395,7 @@ public: void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options); - int resolveImportVersion(); + QTypeRevision resolveImportVersion(); void createWrapperModel(); void initItemCallback(int modelIndex, QObject *item); diff --git a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes index d84eb0011a..5c5ae73ca5 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes @@ -27,9 +27,9 @@ Module { "dumper.ExtendedType/Type 1.0", "dumper.ExtendedType/Type 1.1" ] - exportMetaObjectRevisions: [0, 101] + exportMetaObjectRevisions: [0, 257] Property { name: "baseProperty"; type: "int" } - Property { name: "extendedProperty"; revision: 101; type: "int" } - Property { name: "data"; revision: 101; type: "QObject"; isList: true; isReadonly: true } + Property { name: "extendedProperty"; revision: 257; type: "int" } + Property { name: "data"; revision: 257; type: "QObject"; isList: true; isReadonly: true } } } diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index bc4ba9437c..db79adac6c 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -94,7 +94,8 @@ namespace { QString toString(const QQmlDirParser::Component &c) { return c.typeName + QLatin1Char('|') + c.fileName + QLatin1Char('|') - + QString::number(c.majorVersion) + QLatin1Char('|') + QString::number(c.minorVersion) + + QString::number(c.version.majorVersion()) + QLatin1Char('|') + + QString::number(c.version.minorVersion()) + QLatin1Char('|') + (c.internal ? "true" : "false"); } @@ -112,7 +113,8 @@ namespace { QString toString(const QQmlDirParser::Script &s) { return s.nameSpace + QLatin1Char('|') + s.fileName + QLatin1Char('|') - + QString::number(s.majorVersion) + '|' + QString::number(s.minorVersion); + + QString::number(s.version.majorVersion()) + '|' + + QString::number(s.version.minorVersion()); } QStringList toStringList(const QList<QQmlDirParser::Script> &scripts) @@ -248,7 +250,7 @@ void tst_qqmldirparser::parse_data() << "unversioned-component/qmldir" << QStringList() << QStringList() - << (QStringList() << "foo|bar|-1|-1|false") + << (QStringList() << "foo|bar|255|255|false") << QStringList() << QStringList() << false; diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index 690db30838..0e70933ec6 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -77,7 +77,8 @@ void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations() QUrl testFile = testFileUrl("types.qml"); const auto qmlTypeForTestType = []() { - return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), 2, 0); + return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), + QTypeRevision::fromVersion(2, 0)); }; QVERIFY(!qmlTypeForTestType().isValid()); diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 9c865b3f73..6e95ddfdea 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -190,7 +190,9 @@ void tst_QQmlImport::completeQmldirPaths() QFETCH(int, minorVersion); QFETCH(QStringList, expectedPaths); - QCOMPARE(QQmlImports::completeQmldirPaths(uri, basePaths, majorVersion, minorVersion), expectedPaths); + QCOMPARE(QQmlImports::completeQmldirPaths( + uri, basePaths, QTypeRevision::fromVersion(majorVersion, minorVersion)), + expectedPaths); } class QmldirUrlInterceptor : public QQmlAbstractUrlInterceptor { diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 296d1b14e0..c8e6e9c935 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -217,13 +217,14 @@ void tst_qqmlmetatype::qmlPropertyValueInterceptorCast() void tst_qqmlmetatype::qmlType() { - QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); QCOMPARE(type.qmlTypeName(), QLatin1String("Test/ParserStatusTestType")); - type = QQmlMetaType::qmlType("Test/ParserStatusTestType", 1, 0); + type = QQmlMetaType::qmlType("Test/ParserStatusTestType", QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); @@ -282,19 +283,22 @@ void tst_qqmlmetatype::defaultObject() void tst_qqmlmetatype::registrationType() { - QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -310,7 +314,8 @@ void tst_qqmlmetatype::compositeType() QScopedPointer<QObject> obj(c.create()); QVERIFY(obj); - QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module().isEmpty()); QCOMPARE(type.elementName(), QLatin1String("ImplicitType")); @@ -380,10 +385,12 @@ void tst_qqmlmetatype::unregisterCustomType() int controllerId = 0; { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller1>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -403,10 +410,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller2>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -426,10 +435,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller1>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -480,7 +491,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider1>("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -496,7 +508,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider2>("mytypes", 1, 0, "StaticProvider", createStaticProvider2); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -512,7 +525,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider1>("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -548,7 +562,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() QQmlComponent c(&e); c.setData("import QtQuick 2.2\n Item { }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); @@ -568,7 +583,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() "import QtQuick 2.2 \n" "Item { KeyNavigation.up: null }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index c79fdc57b4..25a448a97f 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -167,8 +167,9 @@ void tst_qqmlpropertycache::revisionedProperties() QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion(new QQmlPropertyCache(metaObject), QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlRefPointer<QQmlPropertyCache> cacheWithVersion(new QQmlPropertyCache(metaObject, 1), - QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cacheWithVersion( + new QQmlPropertyCache(metaObject, QTypeRevision::fromEncodedVersion(1)), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cacheWithoutVersion, "propertyE"))); diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index b44977bd5a..062a8b5c9a 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -76,7 +76,10 @@ void tst_qquickdesignersupport::customData() QVERIFY(rootItem); - QScopedPointer<QObject> newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive(QLatin1String("QtQuick/Item"), 2, 6, view->rootContext())); + QScopedPointer<QObject> newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive( + QLatin1String("QtQuick/Item"), + QTypeRevision::fromVersion(2, 6), + view->rootContext())); QObject *newItem = newItemScopedPointer.data(); QVERIFY(newItem); diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index ed2e52f869..2044360b3d 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -196,7 +196,7 @@ void tst_creation::qobject_10tree_cpp() void tst_creation::qobject_qmltype() { - QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", 2, 0); + QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", QTypeRevision::fromVersion(2, 0)); QBENCHMARK { QObject *obj = t.create(); diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 71286137eb..a8ec527299 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -155,7 +155,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN } stream << " QQmlPrivate::RegisterQmlUnitCacheHook registration;\n"; - stream << " registration.version = 0;\n"; + stream << " registration.structVersion = 0;\n"; stream << " registration.lookupCachedQmlUnit = &lookupCachedUnit;\n"; stream << " QQmlPrivate::qmlregister(QQmlPrivate::QmlUnitCacheHookRegistration, ®istration);\n"; diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp index 75d9fa8a4f..af0e0aeff0 100644 --- a/tools/qmlformat/dumpastvisitor.cpp +++ b/tools/qmlformat/dumpastvisitor.cpp @@ -1221,8 +1221,8 @@ bool DumpAstVisitor::visit(UiImport *node) { result += parseUiQualifiedId(node->importUri); if (node->version) { - result += " " + QString::number(node->version->majorVersion) + "." - + QString::number(node->version->minorVersion); + result += " " + QString::number(node->version->version.majorVersion()) + "." + + QString::number(node->version->version.minorVersion()); } if (node->asToken.isValid()) { diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index b563d7df95..1059f12b54 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -123,7 +123,11 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con if (!name.isEmpty()) import[nameLiteral()] = name; import[typeLiteral()] = moduleLiteral(); - auto versionString = importNode->version ? QString::number(importNode->version->majorVersion) + QLatin1Char('.') + QString::number(importNode->version->minorVersion) : QString(); + auto versionString = importNode->version + ? QString::number(importNode->version->version.majorVersion()) + + QLatin1Char('.') + + QString::number(importNode->version->version.minorVersion()) + : QString(); import[versionLiteral()] = versionString; } diff --git a/tools/qmllint/componentversion.cpp b/tools/qmllint/componentversion.cpp index e5047b8302..95403ec15f 100644 --- a/tools/qmllint/componentversion.cpp +++ b/tools/qmllint/componentversion.cpp @@ -41,21 +41,21 @@ ComponentVersion::ComponentVersion(const QString &versionString) const int maybeMinor = versionString.midRef(dotIdx + 1).toInt(&ok); if (!ok) return; - m_major = maybeMajor; - m_minor = maybeMinor; + m_version = QTypeRevision::fromVersion(maybeMajor, maybeMinor); } bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() < rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() < rhs.version().minorVersion()); } bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() <= rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() <= rhs.version().minorVersion()); } bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs) @@ -70,8 +70,8 @@ bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs) bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() == rhs.minorVersion(); + return lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() == rhs.version().minorVersion(); } bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs) diff --git a/tools/qmllint/componentversion.h b/tools/qmllint/componentversion.h index 9c4604b9a3..bbb039fc40 100644 --- a/tools/qmllint/componentversion.h +++ b/tools/qmllint/componentversion.h @@ -40,24 +40,20 @@ // We mean it. #include <QtCore/qglobal.h> +#include <QtCore/qversionnumber.h> class ComponentVersion { public: - static const int NoVersion = -1; - ComponentVersion() = default; - ComponentVersion(int major, int minor) : m_major(major), m_minor(minor) {} + ComponentVersion(QTypeRevision version) : m_version(version) {} explicit ComponentVersion(const QString &versionString); - int majorVersion() const { return m_major; } - int minorVersion() const { return m_minor; } - - bool isValid() const { return m_major >= 0 && m_minor >= 0; } + QTypeRevision version() const { return m_version; } + bool isValid() const { return m_version.hasMajorVersion() && m_version.hasMinorVersion(); } private: - int m_major = NoVersion; - int m_minor = NoVersion; + QTypeRevision m_version; }; bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs); diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp index 807110c3c1..187471125a 100644 --- a/tools/qmllint/findunqualified.cpp +++ b/tools/qmllint/findunqualified.cpp @@ -92,8 +92,7 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade if (import->asToken.isValid()) { prefix += import->importId + QLatin1Char('.'); } - importHelper(path, prefix, import->version->majorVersion, - import->version->minorVersion); + importHelper(path, prefix, import->version->version); } } header = header->next; @@ -119,7 +118,7 @@ ScopeTree *FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath }; -QStringList completeImportPaths(const QString &uri, const QString &basePath, int vmaj, int vmin) +QStringList completeImportPaths(const QString &uri, const QString &basePath, QTypeRevision version) { static const QLatin1Char Slash('/'); static const QLatin1Char Backslash('\\'); @@ -130,15 +129,16 @@ QStringList completeImportPaths(const QString &uri, const QString &basePath, int // fully & partially versioned parts + 1 unversioned for each base path qmlDirPathsPaths.reserve(2 * parts.count() + 1); - auto versionString = [](int vmaj, int vmin, ImportVersion version) + auto versionString = [](QTypeRevision version, ImportVersion mode) { - if (version == FullyVersioned) { + if (mode == FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString::fromLatin1(".%1.%2").arg(vmaj).arg(vmin); + return QString::fromLatin1(".%1.%2").arg(version.majorVersion()) + .arg(version.minorVersion()); } - if (version == PartiallyVersioned) { + if (mode == PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString::fromLatin1(".%1").arg(vmaj); + return QString::fromLatin1(".%1").arg(version.majorVersion()); } // else extension without version number (eg. MyModule) return QString(); @@ -153,24 +153,24 @@ QStringList completeImportPaths(const QString &uri, const QString &basePath, int return str; }; - const ImportVersion initial = (vmin >= 0) + const ImportVersion initial = (version.hasMinorVersion()) ? FullyVersioned - : (vmaj >= 0 ? PartiallyVersioned : Unversioned); - for (int version = initial; version <= BasePath; ++version) { - const QString ver = versionString(vmaj, vmin, static_cast<ImportVersion>(version)); + : (version.hasMajorVersion() ? PartiallyVersioned : Unversioned); + for (int mode = initial; mode <= BasePath; ++mode) { + const QString ver = versionString(version, ImportVersion(mode)); QString dir = basePath; if (!dir.endsWith(Slash) && !dir.endsWith(Backslash)) dir += Slash; - if (version == BasePath) { + if (mode == BasePath) { qmlDirPathsPaths += dir; } else { // append to the end qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver; } - if (version < Unversioned) { + if (mode < Unversioned) { // insert in the middle for (int index = parts.count() - 2; index >= 0; --index) { qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash) @@ -222,7 +222,7 @@ FindUnqualifiedIDVisitor::Import FindUnqualifiedIDVisitor::readQmldir(const QStr (*mo)->addExport( it.key(), reader.typeNamespace(), - ComponentVersion(it->majorVersion, it->minorVersion)); + ComponentVersion(it->version)); } for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it) result.objects.insert( it.key(), ScopeTree::ConstPtr(it.value())); @@ -240,11 +240,11 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn auto const &id = split.at(0); if (split.length() > 1) { const auto version = split.at(1).split('.'); - importHelper(id, QString(), - version.at(0).toInt(), - version.length() > 1 ? version.at(1).toInt() : -1); + importHelper(id, QString(), QTypeRevision::fromVersion( + version.at(0).toInt(), + version.length() > 1 ? version.at(1).toInt() : -1)); } else { - importHelper(id, QString(), -1, -1); + importHelper(id, QString(), QTypeRevision()); } @@ -267,7 +267,7 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn } void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString &prefix, - int major, int minor) + QTypeRevision version) { const QString id = QString(module).replace(QLatin1Char('/'), QLatin1Char('.')); QPair<QString, QString> importId { id, prefix }; @@ -276,7 +276,7 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString m_alreadySeenImports.insert(importId); for (const QString &qmltypeDir : m_qmltypeDirs) { - auto qmltypesPaths = completeImportPaths(id, qmltypeDir, major, minor); + auto qmltypesPaths = completeImportPaths(id, qmltypeDir, version); for (auto const &qmltypesPath : qmltypesPaths) { if (QFile::exists(qmltypesPath + SlashQmldir)) { @@ -764,7 +764,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import) } path.chop(1); - importHelper(path, prefix, import->version->majorVersion, import->version->minorVersion); + importHelper(path, prefix, import->version->version); } return true; } diff --git a/tools/qmllint/findunqualified.h b/tools/qmllint/findunqualified.h index 6668b53b08..1c351e4fd9 100644 --- a/tools/qmllint/findunqualified.h +++ b/tools/qmllint/findunqualified.h @@ -91,7 +91,7 @@ private: void enterEnvironment(ScopeType type, const QString &name); void leaveEnvironment(); void importHelper(const QString &module, const QString &prefix = QString(), - int major = -1, int minor = -1); + QTypeRevision version = QTypeRevision()); void readQmltypes(const QString &filename, Import &result); Import readQmldir(const QString &dirname); diff --git a/tools/qmllint/typedescriptionreader.cpp b/tools/qmllint/typedescriptionreader.cpp index 3dc87ffc8d..8734f349d5 100644 --- a/tools/qmllint/typedescriptionreader.cpp +++ b/tools/qmllint/typedescriptionreader.cpp @@ -102,7 +102,7 @@ void TypeDescriptionReader::readDocument(UiProgram *ast) return; } - if (import->version->majorVersion != 1) { + if (import->version->version.majorVersion() != 1) { addError(import->version->firstSourceLocation(), tr("Major version different from 1 not supported.")); return; diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 947b5dff27..3efa4dc605 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -103,15 +103,15 @@ static QString enquote(const QString &string) struct QmlVersionInfo { QString pluginImportUri; - int majorVersion; - int minorVersion; + QTypeRevision version; bool strict; }; static bool matchingImportUri(const QQmlType &ty, const QmlVersionInfo& versionInfo) { if (versionInfo.strict) { return (versionInfo.pluginImportUri == ty.module() - && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1)) + && (ty.version().majorVersion() == versionInfo.version.majorVersion() + || !ty.version().hasMajorVersion())) || ty.module().isEmpty(); } return ty.module().isEmpty() @@ -335,23 +335,23 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, } class KnownAttributes { - QHash<QByteArray, int> m_properties; - QHash<QByteArray, QHash<int, int> > m_methods; + QHash<QByteArray, QTypeRevision> m_properties; + QHash<QByteArray, QHash<int, QTypeRevision> > m_methods; public: - bool knownMethod(const QByteArray &name, int nArgs, int revision) + bool knownMethod(const QByteArray &name, int nArgs, QTypeRevision revision) { if (m_methods.contains(name)) { - QHash<int, int> overloads = m_methods.value(name); - if (overloads.contains(nArgs) && overloads.value(nArgs) <= revision) + QHash<int, QTypeRevision> overloads = m_methods.value(name); + if (overloads.contains(nArgs) && overloads.value(nArgs).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; } m_methods[name][nArgs] = revision; return false; } - bool knownProperty(const QByteArray &name, int revision) + bool knownProperty(const QByteArray &name, QTypeRevision revision) { - if (m_properties.contains(name) && m_properties.value(name) <= revision) + if (m_properties.contains(name) && m_properties.value(name).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; m_properties[name] = revision; return false; @@ -375,13 +375,14 @@ public: { const QString module = type.module().isEmpty() ? versionInfo.pluginImportUri : type.module(); - const int majorVersion = type.majorVersion() >= 0 ? type.majorVersion() - : versionInfo.majorVersion; - const int minorVersion = type.minorVersion() >= 0 ? type.minorVersion() - : versionInfo.minorVersion; + QTypeRevision version = QTypeRevision::fromVersion( + type.version().hasMajorVersion() ? type.version().majorVersion() + : versionInfo.version.majorVersion(), + type.version().hasMinorVersion() ? type.version().minorVersion() + : versionInfo.version.minorVersion()); const QString versionedElement = type.elementName() - + QString::fromLatin1(" %1.%2").arg(majorVersion).arg(minorVersion); + + QString::fromLatin1(" %1.%2").arg(version.majorVersion()).arg(version.minorVersion()); return enquote((module == relocatableModuleUri) ? versionedElement @@ -390,7 +391,7 @@ public: void writeMetaContent(const QMetaObject *meta, KnownAttributes *knownAttributes = nullptr) { - QSet<QString> implicitSignals = dumpMetaProperties(meta, 0, knownAttributes); + QSet<QString> implicitSignals = dumpMetaProperties(meta, QTypeRevision::zero(), knownAttributes); if (meta == &QObject::staticMetaObject) { // for QObject, hide deleteLater() and onDestroyed @@ -405,17 +406,17 @@ public: } // and add toString(), destroy() and destroy(int) - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeStartObject(QLatin1String("Parameter")); @@ -498,7 +499,12 @@ public: qml->writeScriptBinding(QLatin1String("name"), exportString); qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString); - qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion())); + + // TODO: shouldn't this be metaObjectRevision().value<quint16>() + // rather than version().minorVersion() + qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() + << QString::number(compositeType.version().minorVersion())); + qml->writeBooleanBinding(QLatin1String("isComposite"), true); if (compositeType.isSingleton()) { @@ -537,10 +543,10 @@ public: struct QmlTypeInfo { QmlTypeInfo() {} - QmlTypeInfo(const QString &exportString, int revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) + QmlTypeInfo(const QString &exportString, QTypeRevision revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) : exportString(exportString), revision(revision), extendedObject(extendedObject), attachedTypeId(attachedTypeId) {} QString exportString; - int revision = 0; + QTypeRevision revision = QTypeRevision::zero(); const QMetaObject *extendedObject = nullptr; QByteArray attachedTypeId; }; @@ -563,11 +569,11 @@ public: if (attachedType != meta) attachedTypeId = convertToId(attachedType); } - const QString exportString = getExportString(type, { QString(), -1, -1, false }); - int metaObjectRevision = type.metaObjectRevision(); + const QString exportString = getExportString(type, { QString(), QTypeRevision(), false }); + QTypeRevision metaObjectRevision = type.metaObjectRevision(); if (extendedObject) { // emulate custom metaobjectrevision out of import - metaObjectRevision = type.majorVersion() * 100 + type.minorVersion(); + metaObjectRevision = type.version(); } QmlTypeInfo info = { exportString, metaObjectRevision, extendedObject, attachedTypeId }; @@ -576,7 +582,7 @@ public: // sort to ensure stable output std::sort(typeInfo.begin(), typeInfo.end(), [](const QmlTypeInfo &i1, const QmlTypeInfo &i2) { - return i1.revision < i2.revision; + return i1.revision.toEncodedVersion<quint16>() < i2.revision.toEncodedVersion<quint16>(); }); // determine default property @@ -600,7 +606,7 @@ public: if (!typeInfo.isEmpty()) { QMap<QString, QString> exports; // sort exports for (const QmlTypeInfo &iter : typeInfo) - exports.insert(iter.exportString, QString::number(iter.revision)); + exports.insert(iter.exportString, QString::number(iter.revision.toEncodedVersion<quint16>())); QStringList exportStrings = exports.keys(); QStringList metaObjectRevisions = exports.values(); @@ -681,22 +687,27 @@ private: qml->writeScriptBinding(QLatin1String("isPointer"), QLatin1String("true")); } - void dump(const QMetaProperty &prop, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + void dump(const QMetaProperty &prop, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { - int revision = metaRevision ? metaRevision : prop.revision(); + // TODO: should that not be metaRevision.isValid() rather than comparing to zero()? + QTypeRevision revision = (metaRevision == QTypeRevision::zero()) + ? QTypeRevision::fromEncodedVersion(prop.revision()) + : metaRevision; QByteArray propName = prop.name(); if (knownAttributes && knownAttributes->knownProperty(propName, revision)) return; qml->writeStartObject("Property"); qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(prop.name()))); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); writeTypeProperties(prop.typeName(), prop.isWritable()); qml->writeEndObject(); } - QSet<QString> dumpMetaProperties(const QMetaObject *meta, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + QSet<QString> dumpMetaProperties(const QMetaObject *meta, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { QSet<QString> implicitSignals; for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) { @@ -704,7 +715,7 @@ private: dump(property, metaRevision, knownAttributes); if (knownAttributes) knownAttributes->knownMethod(QByteArray(property.name()).append("Changed"), - 0, property.revision()); + 0, QTypeRevision::fromEncodedVersion(property.revision())); implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name()))); } return implicitSignals; @@ -732,7 +743,7 @@ private: return; } - int revision = meth.revision(); + QTypeRevision revision = QTypeRevision::fromEncodedVersion(meth.revision()); if (knownAttributes && knownAttributes->knownMethod(name, meth.parameterNames().size(), revision)) return; if (meth.methodType() == QMetaMethod::Signal) @@ -742,8 +753,8 @@ private: qml->writeScriptBinding(QLatin1String("name"), enquote(name)); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); if (typeName != QLatin1String("void")) qml->writeScriptBinding(QLatin1String("type"), enquote(typeName)); @@ -1001,9 +1012,9 @@ static bool operator<(const QQmlType &a, const QQmlType &b) { return a.qmlTypeName() < b.qmlTypeName() || (a.qmlTypeName() == b.qmlTypeName() - && ((a.majorVersion() < b.majorVersion()) - || (a.majorVersion() == b.majorVersion() - && a.minorVersion() < b.minorVersion()))); + && ((a.version().majorVersion() < b.version().majorVersion()) + || (a.version().majorVersion() == b.version().majorVersion() + && a.version().minorVersion() < b.version().minorVersion()))); } QT_END_NAMESPACE @@ -1243,11 +1254,13 @@ int main(int argc, char *argv[]) // composite types we want to dump information of QMap<QString, QList<QQmlType>> compositeTypes; - int majorVersion = qtQmlMajorVersion, minorVersion = qtQmlMinorVersion; + QTypeRevision version = QTypeRevision::fromVersion(qtQmlMajorVersion, qtQmlMinorVersion); QmlVersionInfo info; if (action == Builtins) { QMap<QString, QList<QQmlType>> defaultCompositeTypes; - QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion, strict}); + QSet<const QMetaObject *> builtins = collectReachableMetaObjects( + &engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, + {QLatin1String("Qt"), version, strict}); Q_ASSERT(builtins.size() == 1); metas.insert(*builtins.begin()); } else { @@ -1256,12 +1269,13 @@ int main(int argc, char *argv[]) if (!ok) qCritical("Invalid version number"); else { - majorVersion = versionSplitted.at(0).toInt(&ok); + const int majorVersion = versionSplitted.at(0).toInt(&ok); if (!ok) qCritical("Invalid major version"); - minorVersion = versionSplitted.at(1).toInt(&ok); + const int minorVersion = versionSplitted.at(1).toInt(&ok); if (!ok) qCritical("Invalid minor version"); + version = QTypeRevision::fromVersion(majorVersion, minorVersion); } QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes(); // find a valid QtQuick import @@ -1273,9 +1287,9 @@ int main(int argc, char *argv[]) } else { QString module = qtObjectType.qmlTypeName(); module = module.mid(0, module.lastIndexOf(QLatin1Char('/'))); - importCode = QString("import %1 %2.%3").arg(module, - QString::number(qtObjectType.majorVersion()), - QString::number(qtObjectType.minorVersion())).toUtf8(); + importCode = QString("import %1 %2.%3").arg( + module, QString::number(qtObjectType.version().majorVersion()), + QString::number(qtObjectType.version().minorVersion())).toUtf8(); } // avoid importing dependencies? for (const QString &moduleToImport : qAsConst(dependencies)) { @@ -1307,7 +1321,7 @@ int main(int argc, char *argv[]) return EXIT_IMPORTERROR; } } - info = {pluginImportUri, majorVersion, minorVersion, strict}; + info = {pluginImportUri, version, strict}; QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, info, defaultTypes); for (auto it = compositeTypes.begin(), end = compositeTypes.end(); it != end; ++it) { |