diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-01 15:03:19 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-01 16:51:51 +0100 |
commit | f6fc35b45b449fe7aaca3237f29393a12fc3f90c (patch) | |
tree | bd808ac4fd916f49417f08e0e32105e614c7f0fd /src/qmltyperegistrar | |
parent | 24ec3b3e7fa09900d791dcaedb0820a0b1890336 (diff) |
QmlCompiler: Allow for multiple extensions per object
Previously, the assumption was that each object could only have a single
extension object. As proven by the new qqmllanguage test this is not the
case. Each registered object in the type hierarchy can have its own
extension. Therefore, adjust the algorithms that generate qmltypes and
iterate the extension objects when analyzing them.
This leads us to the realization that anonymous types can in fact
meaningfully carry extensions and implement interfaces. Adapt
qmltyperegistrar accordingly.
For the test to compile, however, we need to realize that the class
declaring interfaces needs to befriend all potential subclass's
QmlInterface structs. Fix that, too. The rabbit hole went deep.
Change-Id: Ia451897e927e03b95c3062e829edf1dfcd216613
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmltyperegistrar')
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 9 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypescreator.cpp | 22 |
2 files changed, 18 insertions, 13 deletions
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 70a4e49d19..2310b8b3b2 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -112,9 +112,14 @@ void QmlTypesClassDescription::collectLocalAnonymous( const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { const QJsonObject obj = classInfo.toObject(); - if (obj[QLatin1String("name")].toString() == QLatin1String("DefaultProperty")) { + const QString name = obj[QStringLiteral("name")].toString(); + const QString value = obj[QStringLiteral("value")].toString(); + + if (name == QStringLiteral("DefaultProperty")) { defaultProp = obj[QLatin1String("value")].toString(); - break; + } else if (name == QStringLiteral("QML.Extended")) { + extensionType = value; + collectRelated(value, types, foreign, defaultRevision); } } diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 4dafdc4490..f754679fb9 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -61,6 +61,17 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle if (!collector.sequenceValueType.isEmpty()) m_qml.writeScriptBinding(QLatin1String("valueType"), enquote(collector.sequenceValueType)); + if (!collector.extensionType.isEmpty()) + m_qml.writeScriptBinding(QLatin1String("extension"), enquote(collector.extensionType)); + + if (!collector.implementsInterfaces.isEmpty()) { + QStringList interfaces; + for (const QString &interface : collector.implementsInterfaces) + interfaces << enquote(interface); + + m_qml.writeArrayBinding(QLatin1String("interfaces"), interfaces); + } + if (collector.elementName.isEmpty()) return; @@ -96,17 +107,6 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle if (!collector.attachedType.isEmpty()) m_qml.writeScriptBinding(QLatin1String("attachedType"), enquote(collector.attachedType)); - - if (!collector.extensionType.isEmpty()) - m_qml.writeScriptBinding(QLatin1String("extension"), enquote(collector.extensionType)); - - if (!collector.implementsInterfaces.isEmpty()) { - QStringList interfaces; - for (const QString &interface : collector.implementsInterfaces) - interfaces << enquote(interface); - - m_qml.writeArrayBinding(QLatin1String("interfaces"), interfaces); - } } void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key, bool isReadonly, |