aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmltyperegistrar/qmltypesclassdescription.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmltyperegistrar/qmltypesclassdescription.cpp')
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.cpp130
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);
}