diff options
Diffstat (limited to 'src/qmltyperegistrar/qmltypesclassdescription.cpp')
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 130 |
1 files changed, 87 insertions, 43 deletions
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); } |