aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmltyperegistrar
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-01-18 11:24:02 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-01-18 13:42:48 +0100
commitbdb2b66f3d7d027e3022aabd63fe73d305ed058f (patch)
treea1e3dd0ca8748b846ba136b4997fd0176f628a6d /src/qmltyperegistrar
parent65b88e61a5a67a0377b375b444fa4fb2a4c9f2b5 (diff)
Add support for extended types to qmltyperegistrar
We generate the extensions as separate types. This also covers the case of value types being extended by "themselves". We can properly express this now, so we don't need the hackery of generating the local members of a type with QML_FOREIGN into the foreign type anymore. This also fixes interfaces from local types being written for foreign types. Fixes: QTBUG-89501 Change-Id: Ic76acd7eef09a92c1e36bd7a649c7a2deb24597b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmltyperegistrar')
-rw-r--r--src/qmltyperegistrar/metatypesjsonprocessor.cpp35
-rw-r--r--src/qmltyperegistrar/metatypesjsonprocessor.h5
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.cpp1
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.cpp130
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.h13
-rw-r--r--src/qmltyperegistrar/qmltypescreator.cpp159
-rw-r--r--src/qmltyperegistrar/qmltypescreator.h2
7 files changed, 216 insertions, 129 deletions
diff --git a/src/qmltyperegistrar/metatypesjsonprocessor.cpp b/src/qmltyperegistrar/metatypesjsonprocessor.cpp
index a9c3128350..0e0723d072 100644
--- a/src/qmltyperegistrar/metatypesjsonprocessor.cpp
+++ b/src/qmltyperegistrar/metatypesjsonprocessor.cpp
@@ -110,16 +110,24 @@ bool MetaTypesJsonProcessor::processForeignTypes(const QStringList &foreignTypes
return success;
}
+static void sortStringList(QStringList *list)
+{
+ std::sort(list->begin(), list->end());
+ const auto newEnd = std::unique(list->begin(), list->end());
+ list->erase(QStringList::const_iterator(newEnd), list->constEnd());
+}
+
void MetaTypesJsonProcessor::postProcessTypes()
{
sortTypes(m_types);
- sortIncludes();
+ sortStringList(&m_includes);
}
void MetaTypesJsonProcessor::postProcessForeignTypes()
{
sortTypes(m_foreignTypes);
- m_types += foreignRelatedTypes();
+ addRelatedTypes();
+ sortStringList(&m_referencedTypes);
sortTypes(m_types);
}
@@ -145,13 +153,14 @@ MetaTypesJsonProcessor::RegistrationMode MetaTypesJsonProcessor::qmlTypeRegistra
return NoRegistration;
}
-QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
+void MetaTypesJsonProcessor::addRelatedTypes()
{
const QLatin1String classInfosKey("classInfos");
const QLatin1String nameKey("name");
const QLatin1String qualifiedClassNameKey("qualifiedClassName");
const QLatin1String qmlNamePrefix("QML.");
const QLatin1String qmlForeignName("QML.Foreign");
+ const QLatin1String qmlExtendedName("QML.Extended");
const QLatin1String qmlAttachedName("QML.Attached");
const QLatin1String qmlSequenceName("QML.Sequence");
const QLatin1String valueKey("value");
@@ -162,7 +171,6 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
QSet<QString> processedRelatedNames;
QQueue<QJsonObject> typeQueue;
typeQueue.append(m_types);
- QVector<QJsonObject> relatedTypes;
// First mark all classes registered from this module as already processed.
for (const QJsonObject &type : m_types) {
@@ -197,12 +205,13 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
}
auto addType = [&](const QString &typeName) {
+ m_referencedTypes.append(typeName);
if (processedRelatedNames.contains(typeName))
return;
processedRelatedNames.insert(typeName);
if (const QJsonObject *other
= QmlTypesClassDescription::findType(m_foreignTypes, typeName)) {
- relatedTypes.append(*other);
+ m_types.append(*other);
typeQueue.enqueue(*other);
}
};
@@ -216,7 +225,8 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
for (const QJsonValue &classInfo : classInfos) {
const QJsonObject obj = classInfo.toObject();
const QString objNameValue = obj.value(nameKey).toString();
- if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName) {
+ if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName
+ || objNameValue == qmlExtendedName) {
addType(obj.value(valueKey).toString());
} else if (objNameValue == qmlForeignName) {
const QString foreignClassName = obj.value(valueKey).toString();
@@ -233,13 +243,13 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
for (const QJsonValue &otherClassInfo : otherClassInfos) {
const QJsonObject obj = otherClassInfo.toObject();
const QString objNameValue = obj.value(nameKey).toString();
- if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName) {
+ if (objNameValue == qmlAttachedName || objNameValue == qmlSequenceName
+ || objNameValue == qmlExtendedName) {
addType(obj.value(valueKey).toString());
break;
}
// No, you cannot chain QML_FOREIGN declarations. Sorry.
}
- break;
}
}
}
@@ -251,8 +261,6 @@ QVector<QJsonObject> MetaTypesJsonProcessor::foreignRelatedTypes() const
addType(superObject.value(nameKey).toString());
}
}
-
- return relatedTypes;
}
void MetaTypesJsonProcessor::sortTypes(QVector<QJsonObject> &types)
@@ -264,13 +272,6 @@ void MetaTypesJsonProcessor::sortTypes(QVector<QJsonObject> &types)
});
}
-void MetaTypesJsonProcessor::sortIncludes()
-{
- std::sort(m_includes.begin(), m_includes.end());
- const auto newEnd = std::unique(m_includes.begin(), m_includes.end());
- m_includes.erase(QList<QString>::const_iterator(newEnd), m_includes.constEnd());
-}
-
QString MetaTypesJsonProcessor::resolvedInclude(const QString &include)
{
return (m_privateIncludes && include.endsWith(QLatin1String("_p.h")))
diff --git a/src/qmltyperegistrar/metatypesjsonprocessor.h b/src/qmltyperegistrar/metatypesjsonprocessor.h
index 341a64a98b..94016e3bc0 100644
--- a/src/qmltyperegistrar/metatypesjsonprocessor.h
+++ b/src/qmltyperegistrar/metatypesjsonprocessor.h
@@ -48,6 +48,7 @@ public:
QVector<QJsonObject> types() const { return m_types; }
QVector<QJsonObject> foreignTypes() const { return m_foreignTypes; }
+ QStringList referencedTypes() const { return m_referencedTypes; }
QStringList includes() const { return m_includes; }
private:
@@ -59,15 +60,15 @@ private:
};
static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef);
- QVector<QJsonObject> foreignRelatedTypes() const;
+ void addRelatedTypes();
void sortTypes(QVector<QJsonObject> &types);
- void sortIncludes();
QString resolvedInclude(const QString &include);;
void processTypes(const QJsonObject &types);
void processForeignTypes(const QJsonObject &types);
QStringList m_includes;
+ QStringList m_referencedTypes;
QVector<QJsonObject> m_types;
QVector<QJsonObject> m_foreignTypes;
bool m_privateIncludes = false;
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp
index 4e010a3252..7ae59b3e37 100644
--- a/src/qmltyperegistrar/qmltyperegistrar.cpp
+++ b/src/qmltyperegistrar/qmltyperegistrar.cpp
@@ -245,6 +245,7 @@ int main(int argc, char **argv)
QmlTypesCreator creator;
creator.setOwnTypes(processor.types());
creator.setForeignTypes(processor.foreignTypes());
+ creator.setReferencedTypes(processor.referencedTypes());
creator.setModule(module);
creator.setVersion(QTypeRevision::fromVersion(parser.value(majorVersionOption).toInt(), 0));
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp
index 4d7e4ac072..5af8ea5be6 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.cpp
+++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp
@@ -58,15 +58,32 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject>
return (it != types.end() && it->value(qualifiedClassNameKey) == name) ? &(*it) : nullptr;
}
-void QmlTypesClassDescription::collect(const QJsonObject *classDef,
- const QVector<QJsonObject> &types,
- const QVector<QJsonObject> &foreign,
- CollectMode mode, QTypeRevision defaultRevision)
+void QmlTypesClassDescription::collectSuperClasses(
+ const QJsonObject *classDef, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, CollectMode mode, QTypeRevision defaultRevision)
{
- const QJsonObject *origClassDef = classDef; // if we find QML.Foreign, classDef changes.
- if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool())
- file = classDef->value(QLatin1String("inputFile")).toString();
+ const auto supers = classDef->value(QLatin1String("superClasses")).toArray();
+ for (const QJsonValue &superValue : supers) {
+ const QJsonObject superObject = superValue.toObject();
+ if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) {
+ const QString superName = superObject[QLatin1String("name")].toString();
+ const CollectMode superMode = (mode == TopLevel) ? SuperClass : RelatedType;
+ if (const QJsonObject *other = findType(types, superName))
+ collect(other, types, foreign, superMode, defaultRevision);
+ else if (const QJsonObject *other = findType(foreign, superName))
+ collect(other, types, foreign, superMode, defaultRevision);
+ else // If we cannot locate a type for it, there is no point in recording the superClass
+ continue;
+
+ if (mode == TopLevel && superClass.isEmpty())
+ superClass = superName;
+ }
+ }
+}
+
+void QmlTypesClassDescription::collectInterfaces(const QJsonObject *classDef)
+{
if (classDef->contains(QLatin1String("interfaces"))) {
const QJsonArray array = classDef->value(QLatin1String("interfaces")).toArray();
for (const QJsonValue &value : array) {
@@ -74,6 +91,43 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
implementsInterfaces << object[QLatin1String("className")].toString();
}
}
+}
+
+void QmlTypesClassDescription::collectLocalAnonymous(
+ const QJsonObject *classDef, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision)
+{
+ file = classDef->value(QLatin1String("inputFile")).toString();
+
+ resolvedClass = classDef;
+ className = classDef->value(QLatin1String("qualifiedClassName")).toString();
+
+ if (classDef->value(QStringLiteral("object")).toBool())
+ accessSemantics = QStringLiteral("reference");
+ else if (classDef->value(QStringLiteral("gadget")).toBool())
+ accessSemantics = QStringLiteral("value");
+ else
+ accessSemantics = QStringLiteral("none");
+
+ 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")) {
+ defaultProp = obj[QLatin1String("value")].toString();
+ break;
+ }
+ }
+
+ collectInterfaces(classDef);
+ collectSuperClasses(classDef, types, foreign, TopLevel, defaultRevision);
+}
+
+void QmlTypesClassDescription::collect(
+ const QJsonObject *classDef, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, CollectMode mode, QTypeRevision defaultRevision)
+{
+ if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool())
+ file = classDef->value(QLatin1String("inputFile")).toString();
const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray();
const QString classDefName = classDef->value(QLatin1String("className")).toString();
@@ -83,7 +137,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
const QString value = obj[QLatin1String("value")].toString();
if (name == QLatin1String("DefaultProperty")) {
- if (mode != AttachedType && defaultProp.isEmpty())
+ if (mode != RelatedType && defaultProp.isEmpty())
defaultProp = value;
} else if (name == QLatin1String("QML.AddedInVersion")) {
const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt());
@@ -111,6 +165,9 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
} else if (name == QLatin1String("QML.Attached")) {
attachedType = value;
collectRelated(value, types, foreign, defaultRevision);
+ } else if (name == QLatin1String("QML.Extended")) {
+ extensionType = value;
+ collectRelated(value, types, foreign, defaultRevision);
} else if (name == QLatin1String("QML.Sequence")) {
sequenceValueType = value;
collectRelated(value, types, foreign, defaultRevision);
@@ -131,55 +188,40 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
} else if (foreignName == QLatin1String("QML.Attached")) {
attachedType = foreignValue;
collectRelated(foreignValue, types, foreign, defaultRevision);
+ } else if (foreignName == QLatin1String("QML.Extended")) {
+ extensionType = 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.
className = value;
+ classDef = nullptr;
}
} else if (name == QLatin1String("QML.Root")) {
isRootClass = true;
}
}
- if (mode == AttachedType || !elementName.isEmpty()) {
- collectExtraVersions(classDef, QString::fromLatin1("properties"), revisions);
- collectExtraVersions(classDef, QString::fromLatin1("slots"), revisions);
- collectExtraVersions(classDef, QString::fromLatin1("methods"), revisions);
- collectExtraVersions(classDef, QString::fromLatin1("signals"), revisions);
- }
-
- auto supers = classDef->value(QLatin1String("superClasses")).toArray();
- if (classDef != origClassDef) {
- const QJsonArray origSupers = origClassDef->value(QLatin1String("superClasses")).toArray();
- for (const QJsonValue origSuper : origSupers)
- supers.append(origSuper);
- }
-
- for (const QJsonValue &superValue : qAsConst(supers)) {
- const QJsonObject superObject = superValue.toObject();
- if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) {
- const QString superName = superObject[QLatin1String("name")].toString();
-
- const CollectMode superMode = (mode == TopLevel) ? SuperClass : AttachedType;
- if (const QJsonObject *other = findType(types, superName))
- collect(other, types, foreign, superMode, defaultRevision);
- else if (const QJsonObject *other = findType(foreign, superName))
- collect(other, types, foreign, superMode, defaultRevision);
- else // If we cannot locate a type for it, there is no point in recording the superClass
- continue;
-
- if (mode == TopLevel && superClass.isEmpty())
- superClass = superName;
+ if (classDef) {
+ if (mode == RelatedType || !elementName.isEmpty()) {
+ collectExtraVersions(classDef, QString::fromLatin1("properties"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("slots"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("methods"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("signals"), revisions);
}
+
+ collectSuperClasses(classDef, types, foreign, mode, defaultRevision);
}
if (mode != TopLevel)
return;
+ if (classDef)
+ collectInterfaces(classDef);
+
if (!addedInRevision.isValid()) {
revisions.append(defaultRevision);
addedInRevision = defaultRevision;
@@ -192,17 +234,19 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
revisions.erase(QList<QTypeRevision>::const_iterator(end), revisions.constEnd());
resolvedClass = classDef;
- if (className.isEmpty() && mode == TopLevel)
+ if (className.isEmpty() && classDef)
className = classDef->value(QLatin1String("qualifiedClassName")).toString();
if (!sequenceValueType.isEmpty()) {
isCreatable = false;
accessSemantics = QLatin1String("sequence");
- } else if (classDef->value(QLatin1String("object")).toBool()) {
+ } else if (classDef && classDef->value(QLatin1String("object")).toBool()) {
accessSemantics = QLatin1String("reference");
} else {
isCreatable = false;
- accessSemantics = classDef->value(QLatin1String("gadget")).toBool()
+ // If no classDef, we assume it's a value type defined by the foreign/extended trick.
+ // Objects and namespaces always have metaobjects and therefore classDefs.
+ accessSemantics = (!classDef || classDef->value(QLatin1String("gadget")).toBool())
? QLatin1String("value")
: QLatin1String("none");
}
@@ -214,7 +258,7 @@ void QmlTypesClassDescription::collectRelated(const QString &related,
QTypeRevision defaultRevision)
{
if (const QJsonObject *other = findType(types, related))
- collect(other, types, foreign, AttachedType, defaultRevision);
+ collect(other, types, foreign, RelatedType, defaultRevision);
else if (const QJsonObject *other = findType(foreign, related))
- collect(other, types, foreign, AttachedType, defaultRevision);
+ collect(other, types, foreign, RelatedType, defaultRevision);
}
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h
index fd172d1922..04d3adac77 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.h
+++ b/src/qmltyperegistrar/qmltypesclassdescription.h
@@ -44,6 +44,7 @@ struct QmlTypesClassDescription
QString defaultProp;
QString superClass;
QString attachedType;
+ QString extensionType;
QString sequenceValueType;
QString accessSemantics;
QList<QTypeRevision> revisions;
@@ -57,7 +58,7 @@ struct QmlTypesClassDescription
enum CollectMode {
TopLevel,
SuperClass,
- AttachedType
+ RelatedType
};
void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types,
@@ -67,6 +68,16 @@ struct QmlTypesClassDescription
const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision);
static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name);
+
+ void collectLocalAnonymous(const QJsonObject *classDef,const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision);
+
+
+private:
+ void collectSuperClasses(
+ const QJsonObject *classDef, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, CollectMode mode, QTypeRevision defaultRevision);
+ void collectInterfaces(const QJsonObject *classDef);
};
#endif // QMLTYPESCLASSDESCRIPTION_H
diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp
index 62996ff90b..b5a3cd749c 100644
--- a/src/qmltyperegistrar/qmltypescreator.cpp
+++ b/src/qmltyperegistrar/qmltypescreator.cpp
@@ -97,6 +97,9 @@ 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)
@@ -249,7 +252,7 @@ static bool isAllowedInMajorVersion(const QJsonValue &member, QTypeRevision maxM
|| memberRevision.majorVersion() <= maxMajorVersion.majorVersion();
}
-static QJsonArray members(const QJsonObject *classDef, const QJsonObject *origClassDef,
+static QJsonArray members(const QJsonObject *classDef,
const QString &key, QTypeRevision maxMajorVersion)
{
QJsonArray classDefMembers;
@@ -260,14 +263,6 @@ static QJsonArray members(const QJsonObject *classDef, const QJsonObject *origCl
classDefMembers.append(member);
}
- if (classDef != origClassDef) {
- const QJsonArray origClassDefMembers = origClassDef->value(key).toArray();
- for (const QJsonValue member : origClassDefMembers) {
- if (isAllowedInMajorVersion(member, maxMajorVersion))
- classDefMembers.append(member);
- }
- }
-
return classDefMembers;
}
@@ -298,6 +293,57 @@ void QmlTypesCreator::writeComponents()
const QLatin1String intType("int");
const QLatin1String stringType("string");
+ auto writeRootClass = [&](const QJsonObject *classDef, const QSet<QString> &notifySignals) {
+ // Hide destroyed() signals
+ QJsonArray componentSignals = members(classDef, signalsKey, m_version);
+ for (auto it = componentSignals.begin(); it != componentSignals.end();) {
+ if (it->toObject().value(nameKey).toString() == destroyedName)
+ it = componentSignals.erase(it);
+ else
+ ++it;
+ }
+ writeMethods(componentSignals, signalElement, notifySignals);
+
+ // Hide deleteLater() methods
+ QJsonArray componentMethods = members(classDef, methodsKey, m_version);
+ const QJsonArray componentSlots = members(classDef, slotsKey, m_version);
+ for (const QJsonValue &componentSlot : componentSlots)
+ componentMethods.append(componentSlot);
+ for (auto it = componentMethods.begin(); it != componentMethods.end();) {
+ if (it->toObject().value(nameKey).toString() == deleteLaterName)
+ it = componentMethods.erase(it);
+ else
+ ++it;
+ }
+
+ // Add toString()
+ QJsonObject toStringMethod;
+ toStringMethod.insert(nameKey, toStringName);
+ toStringMethod.insert(accessKey, publicAccess);
+ toStringMethod.insert(returnTypeKey, stringType);
+ componentMethods.append(toStringMethod);
+
+ // Add destroy()
+ QJsonObject destroyMethod;
+ destroyMethod.insert(nameKey, destroyName);
+ destroyMethod.insert(accessKey, publicAccess);
+ componentMethods.append(destroyMethod);
+
+ // Add destroy(int)
+ QJsonObject destroyMethodWithArgument;
+ destroyMethodWithArgument.insert(nameKey, destroyName);
+ destroyMethodWithArgument.insert(accessKey, publicAccess);
+ QJsonObject delayArgument;
+ delayArgument.insert(nameKey, delayName);
+ delayArgument.insert(typeKey, intType);
+ QJsonArray destroyArguments;
+ destroyArguments.append(delayArgument);
+ destroyMethodWithArgument.insert(argumentsKey, destroyArguments);
+ componentMethods.append(destroyMethodWithArgument);
+
+ writeMethods(componentMethods, methodElement);
+ };
+
for (const QJsonObject &component : m_ownTypes) {
m_qml.writeStartObject(componentElement);
@@ -307,69 +353,50 @@ void QmlTypesCreator::writeComponents()
writeClassProperties(collector);
- const QJsonObject *classDef = collector.resolvedClass;
- writeEnums(members(classDef, &component, enumsKey, m_version));
-
- QSet<QString> notifySignals;
- writeProperties(members(classDef, &component, propertiesKey, m_version), notifySignals);
+ if (const QJsonObject *classDef = collector.resolvedClass) {
+ writeEnums(members(classDef, enumsKey, m_version));
- if (collector.isRootClass) {
+ QSet<QString> notifySignals;
+ writeProperties(members(classDef, propertiesKey, m_version), notifySignals);
- // Hide destroyed() signals
- QJsonArray componentSignals = members(classDef, &component, signalsKey, m_version);
- for (auto it = componentSignals.begin(); it != componentSignals.end();) {
- if (it->toObject().value(nameKey).toString() == destroyedName)
- it = componentSignals.erase(it);
- else
- ++it;
- }
- writeMethods(componentSignals, signalElement, notifySignals);
-
- // Hide deleteLater() methods
- QJsonArray componentMethods = members(classDef, &component, methodsKey, m_version);
- const QJsonArray componentSlots = members(classDef, &component, slotsKey, m_version);
- for (const QJsonValue componentSlot : componentSlots)
- componentMethods.append(componentSlot);
- for (auto it = componentMethods.begin(); it != componentMethods.end();) {
- if (it->toObject().value(nameKey).toString() == deleteLaterName)
- it = componentMethods.erase(it);
- else
- ++it;
+ if (collector.isRootClass) {
+ writeRootClass(classDef, notifySignals);
+ } else {
+ writeMethods(members(classDef, signalsKey, m_version), signalElement,
+ notifySignals);
+ writeMethods(members(classDef, slotsKey, m_version), methodElement);
+ writeMethods(members(classDef, methodsKey, m_version), methodElement);
}
+ }
+ m_qml.writeEndObject();
+
+ if (collector.resolvedClass != &component
+ && std::binary_search(
+ m_referencedTypes.begin(), m_referencedTypes.end(),
+ component.value(QStringLiteral("qualifiedClassName")).toString())) {
+
+ // This type is referenced from elsewhere and has a QML_FOREIGN of its own. We need to
+ // also generate a description of the local type then. All the QML_* macros are
+ // ignored, and the result is an anonymous type.
+
+ m_qml.writeStartObject(componentElement);
+
+ QmlTypesClassDescription collector;
+ collector.collectLocalAnonymous(&component, m_ownTypes, m_foreignTypes, m_version);
- // Add toString()
- QJsonObject toStringMethod;
- toStringMethod.insert(nameKey, toStringName);
- toStringMethod.insert(accessKey, publicAccess);
- toStringMethod.insert(returnTypeKey, stringType);
- componentMethods.append(toStringMethod);
-
- // Add destroy()
- QJsonObject destroyMethod;
- destroyMethod.insert(nameKey, destroyName);
- destroyMethod.insert(accessKey, publicAccess);
- componentMethods.append(destroyMethod);
-
- // Add destroy(int)
- QJsonObject destroyMethodWithArgument;
- destroyMethodWithArgument.insert(nameKey, destroyName);
- destroyMethodWithArgument.insert(accessKey, publicAccess);
- QJsonObject delayArgument;
- delayArgument.insert(nameKey, delayName);
- delayArgument.insert(typeKey, intType);
- QJsonArray destroyArguments;
- destroyArguments.append(delayArgument);
- destroyMethodWithArgument.insert(argumentsKey, destroyArguments);
- componentMethods.append(destroyMethodWithArgument);
-
- writeMethods(componentMethods, methodElement);
- } else {
- writeMethods(members(classDef, &component, signalsKey, m_version), signalElement,
+ writeClassProperties(collector);
+ writeEnums(members(&component, enumsKey, m_version));
+
+ QSet<QString> notifySignals;
+ writeProperties(members(&component, propertiesKey, m_version), notifySignals);
+
+ writeMethods(members(&component, signalsKey, m_version), signalElement,
notifySignals);
- writeMethods(members(classDef, &component, slotsKey, m_version), methodElement);
- writeMethods(members(classDef, &component, methodsKey, m_version), methodElement);
+ writeMethods(members(&component, slotsKey, m_version), methodElement);
+ writeMethods(members(&component, methodsKey, m_version), methodElement);
+
+ m_qml.writeEndObject();
}
- m_qml.writeEndObject();
}
}
diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h
index 2216a8a967..208cc19952 100644
--- a/src/qmltyperegistrar/qmltypescreator.h
+++ b/src/qmltyperegistrar/qmltypescreator.h
@@ -44,6 +44,7 @@ public:
void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); }
void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); }
+ void setReferencedTypes(QStringList referencedTypes) { m_referencedTypes = std::move(referencedTypes); }
void setModule(QString module) { m_module = std::move(module); }
void setVersion(QTypeRevision version) { m_version = version; }
@@ -61,6 +62,7 @@ private:
QQmlJSStreamWriter m_qml;
QVector<QJsonObject> m_ownTypes;
QVector<QJsonObject> m_foreignTypes;
+ QStringList m_referencedTypes;
QString m_module;
QTypeRevision m_version = QTypeRevision::zero();
};