diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 33 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sequenceobject_p.h | 46 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 43 | ||||
-rw-r--r-- | src/qml/qml/qqml.h | 33 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 46 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 1 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope_p.h | 10 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypedescriptionreader.cpp | 6 | ||||
-rw-r--r-- | src/qmltyperegistrar/metatypesjsonprocessor.cpp | 9 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 29 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.h | 5 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypescreator.cpp | 3 |
14 files changed, 212 insertions, 60 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index fe34207ddc..b09f874ef3 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -709,8 +709,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) static_cast<VariantPrototype *>(variantPrototype())->init(); #if QT_CONFIG(qml_sequence_object) - static const bool registered = QV4::SequencePrototype::registerDefaultTypes(); - Q_UNUSED(registered); sequencePrototype()->cast<SequencePrototype>()->init(); #endif diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 5c7f8289f2..73fa2385fd 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -37,7 +37,6 @@ ** ****************************************************************************/ -#include <QtQml/qqml.h> #include <QtCore/qsequentialiterable.h> #include "qv4sequenceobject_p.h" @@ -51,10 +50,6 @@ #include "qv4objectiterator_p.h" #include <private/qqmlmetatype_p.h> #include <private/qqmltype_p_p.h> -#if QT_CONFIG(qml_itemmodel) -#include <private/qqmlmodelindexvaluetype_p.h> -#include <QtCore/qabstractitemmodel.h> -#endif #include <algorithm> @@ -581,34 +576,6 @@ namespace QV4 { DEFINE_OBJECT_VTABLE(QV4Sequence); } - -template<typename SequenceType> -void registerSequenceType() -{ - qRegisterMetaType<SequenceType>(); - qmlRegisterAnonymousSequentialContainer<SequenceType>("QML", 1); -} - -bool SequencePrototype::registerDefaultTypes() -{ - registerSequenceType<std::vector<int>>(); - registerSequenceType<std::vector<qreal>>(); - registerSequenceType<std::vector<bool>>(); - registerSequenceType<QList<int>>(); - registerSequenceType<QList<qreal>>(); - registerSequenceType<QList<bool>>(); - registerSequenceType<QStringList>(); - registerSequenceType<std::vector<QString>>(); - registerSequenceType<QList<QUrl>>(); - registerSequenceType<std::vector<QUrl>>(); -#if QT_CONFIG(qml_itemmodel) - registerSequenceType<QModelIndexList>(); - registerSequenceType<std::vector<QModelIndex>>(); - registerSequenceType<QItemSelection>(); -#endif - return true; -} - void SequencePrototype::init() { defineDefaultProperty(QStringLiteral("sort"), method_sort, 1); diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 6229a4b5ec..9143430872 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -53,12 +53,18 @@ #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> +#include <QtQml/qqml.h> #include "qv4value_p.h" #include "qv4object_p.h" #include "qv4context_p.h" #include "qv4string_p.h" +#if QT_CONFIG(qml_itemmodel) +#include <private/qqmlmodelindexvaluetype_p.h> +#include <QtCore/qabstractitemmodel.h> +#endif + QT_REQUIRE_CONFIG(qml_sequence_object); QT_BEGIN_NAMESPACE @@ -68,7 +74,6 @@ namespace QV4 { struct Q_QML_PRIVATE_EXPORT SequencePrototype : public QV4::Object { V4_PROTOTYPE(arrayPrototype) - static bool registerDefaultTypes(); void init(); static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); @@ -84,6 +89,45 @@ struct Q_QML_PRIVATE_EXPORT SequencePrototype : public QV4::Object } +#define QT_DECLARE_SEQUENTIAL_CONTAINER(LOCAL, FOREIGN, VALUE) \ + struct LOCAL \ + { \ + Q_GADGET \ + QML_ANONYMOUS \ + QML_SEQUENTIAL_CONTAINER(VALUE) \ + QML_FOREIGN(FOREIGN) \ + QML_ADDED_IN_VERSION(2, 0) \ + } + +// We use the original QT_COORD_TYPE name because that will match up with relevant other +// types in plugins.qmltypes (if you use either float or double, that is; otherwise you're +// on your own). +#ifdef QT_COORD_TYPE +QT_DECLARE_SEQUENTIAL_CONTAINER(QStdRealVectorForeign, std::vector<qreal>, QT_COORD_TYPE); +QT_DECLARE_SEQUENTIAL_CONTAINER(QRealListForeign, QList<qreal>, QT_COORD_TYPE); +#else +QT_DECLARE_SEQUENTIAL_CONTAINER(QRealStdVectorForeign, std::vector<qreal>, double); +QT_DECLARE_SEQUENTIAL_CONTAINER(QRealListForeign, QList<qreal>, double); +#endif + +QT_DECLARE_SEQUENTIAL_CONTAINER(QIntStdVectorForeign, std::vector<int>, int); +QT_DECLARE_SEQUENTIAL_CONTAINER(QBoolStdVectorForeign, std::vector<bool>, bool); +QT_DECLARE_SEQUENTIAL_CONTAINER(QStringStdVectorForeign, std::vector<QString>, QString); +QT_DECLARE_SEQUENTIAL_CONTAINER(QUrlStdVectorForeign, std::vector<QUrl>, QUrl); + +QT_DECLARE_SEQUENTIAL_CONTAINER(QIntListForeign, QList<int>, int); +QT_DECLARE_SEQUENTIAL_CONTAINER(QBoolListForeign, QList<bool>, bool); +QT_DECLARE_SEQUENTIAL_CONTAINER(QStringListForeign, QStringList, QString); +QT_DECLARE_SEQUENTIAL_CONTAINER(QUrlListForeign, QList<QUrl>, QUrl); + +#if QT_CONFIG(qml_itemmodel) +QT_DECLARE_SEQUENTIAL_CONTAINER(QModelIndexListForeign, QModelIndexList, QModelIndex); +QT_DECLARE_SEQUENTIAL_CONTAINER(QModelIndexStdVectorForeign, std::vector<QModelIndex>, QModelIndex); +QT_DECLARE_SEQUENTIAL_CONTAINER(QItemSelectionForeign, QItemSelection, QItemSelectionRange); +#endif + +#undef QT_DECLARE_SEQUENTIAL_CONTAINER + QT_END_NAMESPACE #endif // QV4SEQUENCEWRAPPER_P_H diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 20608a60e4..40e629284b 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -421,6 +421,48 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) } break; } + case SequentialContainerAndRevisionsRegistration: { + const RegisterSequentialContainerAndRevisions &type + = *reinterpret_cast<RegisterSequentialContainerAndRevisions *>(data); + const char *elementName = classElementName(type.classInfoMetaObject); + RegisterSequentialContainer revisionRegistration = { + 0, + type.uri, + type.version, + elementName, + type.typeId, + type.metaSequence, + QTypeRevision() + }; + + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::fromMinorVersion(0)); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); + + QVector<QTypeRevision> revisions = { added }; + uniqueRevisions(&revisions, type.version, added); + + for (QTypeRevision revision : qAsConst(revisions)) { + if (revision < added) + continue; + if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion()) + break; + + // When removed, we still add revisions, but anonymous ones + if (removed.isValid() && !(revision < removed)) + revisionRegistration.typeName = nullptr; + else + revisionRegistration.typeName = elementName; + + assignVersions(&revisionRegistration, revision, type.version); + const int id = qmlregister(SequentialContainerRegistration, &revisionRegistration); + if (type.qmlTypeIds) + type.qmlTypeIds->append(id); + } + break; + } case TypeRegistration: dtype = QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data)); break; @@ -472,6 +514,7 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data) break; case TypeAndRevisionsRegistration: case SingletonAndRevisionsRegistration: + case SequentialContainerAndRevisionsRegistration: // Currently unnecessary. We'd need a special data structure to hold // URI + majorVersion and then we'd iterate the minor versions, look up the // associated QQmlType objects by uri/elementName/major/minor and qmlunregister diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 75f7ae5f06..7f0c81c514 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -94,6 +94,14 @@ template<typename T, typename... Args> \ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *); +#define QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) \ + Q_CLASSINFO("QML.Sequence", #VALUE_TYPE) \ + using QmlSequenceValueType = VALUE_TYPE; \ + enum class QmlIsSequence {yes = true}; \ + template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSequence; \ + template<typename T, typename... Args> \ + friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *); + #define QML_ADDED_IN_MINOR_VERSION(VERSION) \ Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION)) @@ -792,17 +800,18 @@ inline int qmlRegisterAnonymousSequentialContainer(const char *uri, int versionM QTypeRevision::fromMajorVersion(versionMajor), nullptr, QMetaType::fromType<Container>(), - QMetaSequence::fromContainer<Container>() + QMetaSequence::fromContainer<Container>(), + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::SequentialContainerRegistration, &type); } -template<class T, class Resolved, class Extended, bool Singleton, bool Interface> +template<class T, class Resolved, class Extended, bool Singleton, bool Interface, bool Sequence> struct QmlTypeAndRevisionsRegistration; template<class T, class Resolved, class Extended> -struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *extension) { @@ -812,8 +821,19 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> { } }; +template<class T, class Resolved> +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, false, true> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *) + { + QQmlPrivate::qmlRegisterSequenceAndRevisions<Resolved>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds); + } +}; + template<class T, class Resolved, class Extended> -struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *extension) { @@ -824,7 +844,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> { }; template<class T, class Resolved> -struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> { +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false> { static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, const QMetaObject *) { @@ -845,7 +865,8 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> T, typename QQmlPrivate::QmlResolved<T>::Type, typename QQmlPrivate::QmlExtended<T>::Type, QQmlPrivate::QmlSingleton<T>::Value, - QQmlPrivate::QmlInterface<T>::Value> + QQmlPrivate::QmlInterface<T>::Value, + QQmlPrivate::QmlSequence<T>::Value> ::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds, QQmlPrivate::QmlExtendedNamespace<T>::metaObject()); qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor, qmlTypeIds); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index e59ebc97eb..9dea173127 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -667,7 +667,8 @@ QQmlType QQmlMetaType::registerSequentialContainer( QQmlMetaTypeDataPtr data; - if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(), + const QString typeName = QString::fromUtf8(container.typeName); + if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, typeName, container.version, {})) { return QQmlType(); } @@ -675,8 +676,9 @@ QQmlType QQmlMetaType::registerSequentialContainer( QQmlTypePrivate *priv = new QQmlTypePrivate(QQmlType::SequentialContainerType); data->registerType(priv); - priv->setName(QString::fromUtf8(container.uri), QString()); + priv->setName(QString::fromUtf8(container.uri), typeName); priv->version = container.version; + priv->revision = container.revision; priv->typeId = container.typeId; *priv->extraData.ld = container.metaSequence; diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 19072f0751..feee3f8686 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -574,6 +574,19 @@ namespace QQmlPrivate const char *typeName; QMetaType typeId; QMetaSequence metaSequence; + QTypeRevision revision; + }; + + struct RegisterSequentialContainerAndRevisions { + int structVersion; + const char *uri; + QTypeRevision version; + + const QMetaObject *classInfoMetaObject; + QMetaType typeId; + QMetaSequence metaSequence; + + QVector<int> *qmlTypeIds; }; struct AOTCompiledFunction { @@ -605,6 +618,7 @@ namespace QQmlPrivate TypeAndRevisionsRegistration = 7, SingletonAndRevisionsRegistration = 8, SequentialContainerRegistration = 9, + SequentialContainerAndRevisionsRegistration = 10, }; int Q_QML_EXPORT qmlregister(RegistrationType, void *); @@ -717,6 +731,20 @@ namespace QQmlPrivate }; template<class T, class = std::void_t<>> + struct QmlSequence + { + static constexpr bool Value = false; + }; + + template<class T> + struct QmlSequence<T, std::void_t<typename T::QmlIsSequence>> + { + Q_STATIC_ASSERT((std::is_same_v<typename T::QmlSequenceValueType, + typename QmlResolved<T>::Type::value_type>)); + static constexpr bool Value = bool(T::QmlIsSequence::yes); + }; + + template<class T, class = std::void_t<>> struct QmlInterface { static constexpr bool Value = false; @@ -823,6 +851,24 @@ namespace QQmlPrivate qmlregister(TypeAndRevisionsRegistration, &type); } + template<typename T> + void qmlRegisterSequenceAndRevisions(const char *uri, int versionMajor, + const QMetaObject *classInfoMetaObject, + QVector<int> *qmlTypeIds) + { + RegisterSequentialContainerAndRevisions type = { + 0, + uri, + QTypeRevision::fromMajorVersion(versionMajor), + classInfoMetaObject, + QMetaType::fromType<T>(), + QMetaSequence::fromContainer<T>(), + qmlTypeIds + }; + + qmlregister(SequentialContainerAndRevisionsRegistration, &type); + } + template<> void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>( const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index 0787e1062e..ed029208dc 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -152,6 +152,7 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont m_baseType = findType(m_baseTypeName); m_attachedType = findType(m_attachedTypeName); + m_valueType = findType(m_valueTypeName); for (auto it = m_properties.begin(), end = m_properties.end(); it != end; ++it) it->setType(findType(it->typeName())); diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index 99645a8071..24e401fa0a 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -101,7 +101,8 @@ public: enum class AccessSemantics { Reference, Value, - None + None, + Sequence }; enum Flag { @@ -200,6 +201,10 @@ public: void setAttachedTypeName(const QString &name) { m_attachedTypeName = name; } QQmlJSScope::ConstPtr attachedType() const { return m_attachedType; } + QString valueTypeName() const { return m_valueTypeName; } + void setValueTypeName(const QString &name) { m_valueTypeName = name; } + QQmlJSScope::ConstPtr valueType() const { return m_valueType; } + bool isSingleton() const { return m_flags & Singleton; } bool isCreatable() const { return m_flags & Creatable; } bool isComposite() const { return m_flags & Composite; } @@ -258,6 +263,9 @@ private: QString m_attachedTypeName; QQmlJSScope::WeakConstPtr m_attachedType; + QString m_valueTypeName; + QQmlJSScope::WeakConstPtr m_valueType; + Flags m_flags; AccessSemantics m_semantics = AccessSemantics::Reference; diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 215a82b4bc..fd875dd715 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -224,6 +224,8 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) readMetaObjectRevisions(script, scope); } else if (name == QLatin1String("attachedType")) { scope->setAttachedTypeName(readStringBinding(script)); + } else if (name == QLatin1String("valueType")) { + scope->setValueTypeName(readStringBinding(script)); } else if (name == QLatin1String("isSingleton")) { scope->setIsSingleton(readBoolBinding(script)); } else if (name == QLatin1String("isCreatable")) { @@ -238,6 +240,8 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) scope->setAccessSemantics(QQmlJSScope::AccessSemantics::Value); } else if (semantics == QLatin1String("none")) { scope->setAccessSemantics(QQmlJSScope::AccessSemantics::None); + } else if (semantics == QLatin1String("sequence")) { + scope->setAccessSemantics(QQmlJSScope::AccessSemantics::Sequence); } else { addWarning(script->firstSourceLocation(), tr("Unknown access semantics \"%1\".").arg(semantics)); @@ -245,7 +249,7 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) } else { addWarning(script->firstSourceLocation(), tr("Expected only name, prototype, defaultProperty, attachedType, " - "exports, isSingleton, isCreatable, isComposite and " + "valueType, exports, isSingleton, isCreatable, isComposite and " "exportMetaObjectRevisions script bindings, not \"%1\".").arg(name)); } } else { diff --git a/src/qmltyperegistrar/metatypesjsonprocessor.cpp b/src/qmltyperegistrar/metatypesjsonprocessor.cpp index f71a94c67d..e4b9c32b8b 100644 --- a/src/qmltyperegistrar/metatypesjsonprocessor.cpp +++ b/src/qmltyperegistrar/metatypesjsonprocessor.cpp @@ -153,6 +153,7 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const const QLatin1String qmlNamePrefix("QML."); const QLatin1String qmlForeignName("QML.Foreign"); const QLatin1String qmlAttachedName("QML.Attached"); + const QLatin1String qmlSequenceName("QML.Sequence"); const QLatin1String valueKey("value"); const QLatin1String superClassesKey("superClasses"); const QLatin1String accessKey("access"); @@ -214,9 +215,10 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const const auto classInfos = classDef.value(classInfosKey).toArray(); for (const QJsonValue classInfo : classInfos) { const QJsonObject obj = classInfo.toObject(); - if (obj.value(nameKey).toString() == qmlAttachedName) { + const QString objNameValue = obj.value(nameKey).toString(); + if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName) { addType(obj.value(valueKey).toString()); - } else if (obj.value(nameKey).toString() == qmlForeignName) { + } else if (objNameValue == qmlForeignName) { const QString foreignClassName = obj.value(valueKey).toString(); if (const QJsonObject *other = QmlTypesClassDescription::findType( m_foreignTypes, foreignClassName)) { @@ -230,7 +232,8 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const const auto otherClassInfos = other->value(classInfosKey).toArray(); for (const QJsonValue otherClassInfo : otherClassInfos) { const QJsonObject obj = otherClassInfo.toObject(); - if (obj.value(nameKey).toString() == qmlAttachedName) { + const QString objNameValue = obj.value(nameKey).toString(); + if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName) { addType(obj.value(valueKey).toString()); break; } diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 20f5d4c46a..94cfd2c2a4 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -99,7 +99,11 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { - collectAttached(value, types, foreign, defaultRevision); + attachedType = value; + collectRelated(value, types, foreign, defaultRevision); + } else if (name == QLatin1String("QML.Sequence")) { + sequenceValueType = value; + collectRelated(value, types, foreign, defaultRevision); } else if (name == QLatin1String("QML.Singleton")) { if (value == QLatin1String("true")) isSingleton = true; @@ -112,10 +116,15 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QJsonObject obj = classInfo.toObject(); const QString foreignName = obj[QLatin1String("name")].toString(); const QString foreignValue = obj[QLatin1String("value")].toString(); - if (defaultProp.isEmpty() && foreignName == QLatin1String("DefaultProperty")) + if (defaultProp.isEmpty() && foreignName == QLatin1String("DefaultProperty")) { defaultProp = foreignValue; - else if (foreignName == QLatin1String("QML.Attached")) - collectAttached(foreignValue, types, foreign, defaultRevision); + } else if (foreignName == QLatin1String("QML.Attached")) { + attachedType = foreignValue; + collectRelated(foreignValue, types, foreign, defaultRevision); + } else if (foreignName == QLatin1String("QML.Sequence")) { + sequenceValueType = foreignValue; + collectRelated(foreignValue, types, foreign, defaultRevision); + } } } else { // The foreign type does not have a meta object: We only override the name. @@ -176,7 +185,10 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, if (className.isEmpty() && mode == TopLevel) className = classDef->value(QLatin1String("qualifiedClassName")).toString(); - if (classDef->value(QLatin1String("object")).toBool()) { + if (!sequenceValueType.isEmpty()) { + isCreatable = false; + accessSemantics = QLatin1String("sequence"); + } else if (classDef->value(QLatin1String("object")).toBool()) { accessSemantics = QLatin1String("reference"); } else { isCreatable = false; @@ -186,14 +198,13 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } } -void QmlTypesClassDescription::collectAttached(const QString &attached, +void QmlTypesClassDescription::collectRelated(const QString &related, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision) { - attachedType = attached; - if (const QJsonObject *other = findType(types, attachedType)) + if (const QJsonObject *other = findType(types, related)) collect(other, types, foreign, AttachedType, defaultRevision); - else if (const QJsonObject *other = findType(foreign, attachedType)) + else if (const QJsonObject *other = findType(foreign, related)) collect(other, types, foreign, AttachedType, defaultRevision); } diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 17235c58eb..7e496159ff 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -44,6 +44,7 @@ struct QmlTypesClassDescription QString defaultProp; QString superClass; QString attachedType; + QString sequenceValueType; QString accessSemantics; QList<QTypeRevision> revisions; QTypeRevision addedInRevision; @@ -61,8 +62,8 @@ struct QmlTypesClassDescription void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, CollectMode mode, QTypeRevision defaultRevision); - void collectAttached(const QString &attached, const QVector<QJsonObject> &types, - const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision); + void collectRelated(const QString &related, const QVector<QJsonObject> &types, + const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision); static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name); }; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 50980685e9..9e1e757b69 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -58,6 +58,9 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle if (!collector.superClass.isEmpty()) m_qml.writeScriptBinding(QLatin1String("prototype"), enquote(collector.superClass)); + if (!collector.sequenceValueType.isEmpty()) + m_qml.writeScriptBinding(QLatin1String("valueType"), enquote(collector.sequenceValueType)); + if (collector.elementName.isEmpty()) return; |