diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-03-10 15:09:37 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-03-12 15:03:03 +0100 |
commit | 26c5243491f495194f04b449128dae36118e28da (patch) | |
tree | 7fb14678a6fc9e44a10c9224d005e2cbdc6bcb63 /src/qmltyperegistrar | |
parent | 1c7d264e3b2e9a2f0021786ea6967185f8282af0 (diff) | |
parent | c24c5baeda4101b0058689adf9200b77a722c3a2 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Conflicts:
dependencies.yaml
src/qml/qml/qqmlengine.cpp
Change-Id: I6a73fd1064286f4a2232de85c2ce7f80452d4641
Diffstat (limited to 'src/qmltyperegistrar')
-rw-r--r-- | src/qmltyperegistrar/qmltyperegistrar.cpp | 53 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.cpp | 84 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypesclassdescription.h | 18 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypescreator.cpp | 28 | ||||
-rw-r--r-- | src/qmltyperegistrar/qmltypescreator.h | 4 |
5 files changed, 123 insertions, 64 deletions
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 4738e28314..33f1ebbbd5 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -47,14 +47,32 @@ struct ScopedPointerFileCloser static inline void cleanup(FILE *handle) { if (handle) fclose(handle); } }; -static bool acceptClassForQmlTypeRegistration(const QJsonObject &classDef) +enum RegistrationMode { + NoRegistration, + ObjectRegistration, + GadgetRegistration, + NamespaceRegistration +}; + +static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef) { const QJsonArray classInfos = classDef[QLatin1String("classInfos")].toArray(); for (const QJsonValue &info: classInfos) { - if (info[QLatin1String("name")].toString() == QLatin1String("QML.Element")) - return true; + const QString name = info[QLatin1String("name")].toString(); + if (name == QLatin1String("QML.Element")) { + if (classDef[QLatin1String("object")].toBool()) + return ObjectRegistration; + if (classDef[QLatin1String("gadget")].toBool()) + return GadgetRegistration; + if (classDef[QLatin1String("namespace")].toBool()) + return NamespaceRegistration; + qWarning() << "Not registering classInfo which is neither an object, " + "nor a gadget, nor a namespace:" + << name; + break; + } } - return false; + return NoRegistration; } static bool argumentsFromCommandLineAndFile(QStringList &allArguments, const QStringList &arguments) @@ -317,7 +335,10 @@ int main(int argc, char **argv) const QJsonArray classes = metaObject[QLatin1String("classes")].toArray(); for (const auto &cls : classes) { QJsonObject classDef = cls.toObject(); - if (acceptClassForQmlTypeRegistration(classDef)) { + switch (qmlTypeRegistrationMode(classDef)) { + case NamespaceRegistration: + case GadgetRegistration: + case ObjectRegistration: { const QString include = metaObject[QLatin1String("inputFile")].toString(); const bool declaredInHeader = include.endsWith(QLatin1String(".h")); if (declaredInHeader) { @@ -329,9 +350,13 @@ int main(int argc, char **argv) qPrintable(classDef.value(QLatin1String("qualifiedClassName")) .toString())); } + types.append(classDef); - } else { + break; + } + case NoRegistration: foreignTypes.append(classDef); + break; } } }; @@ -393,16 +418,22 @@ int main(int argc, char **argv) continue; const QString className = classDef[QLatin1String("qualifiedClassName")].toString(); - fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", qPrintable(className), - qPrintable(module), qPrintable(majorVersion)); + + if (classDef.value(QLatin1String("namespace")).toBool()) { + fprintf(output, "\n qmlRegisterNamespaceAndRevisions(&%s::staticMetaObject, \"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } else { + fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } } fprintf(output, "\n qmlRegisterModule(\"%s\", %s, %s);", qPrintable(module), qPrintable(majorVersion), qPrintable(parser.value(minorVersionOption))); fprintf(output, "\n}\n"); - fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s, %s);\n", - qPrintable(module), qPrintable(majorVersion), qPrintable(functionName)); + fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s);\n", + qPrintable(module), qPrintable(functionName)); if (!parser.isSet(pluginTypesOption)) return EXIT_SUCCESS; @@ -447,7 +478,7 @@ int main(int argc, char **argv) creator.setOwnTypes(std::move(types)); creator.setForeignTypes(std::move(foreignTypes)); creator.setModule(module); - creator.setMajorVersion(parser.value(majorVersionOption).toInt()); + creator.setVersion(QTypeRevision::fromVersion(parser.value(majorVersionOption).toInt(), 0)); creator.generate(parser.value(pluginTypesOption), parser.value(dependenciesOption)); return EXIT_SUCCESS; diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 15a8113ac8..e21abd97bc 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -27,18 +27,19 @@ ****************************************************************************/ #include "qmltypesclassdescription.h" +#include "qmltypescreator.h" #include <QtCore/qjsonarray.h> static void collectExtraVersions(const QJsonObject *component, const QString &key, - QList<int> &extraVersions) + QList<QTypeRevision> &extraVersions) { const QJsonArray &items = component->value(key).toArray(); for (const QJsonValue &item : items) { const QJsonObject obj = item.toObject(); const auto revision = obj.find(QLatin1String("revision")); if (revision != obj.end()) { - const int extraVersion = revision.value().toInt(); + const auto extraVersion = QTypeRevision::fromEncodedVersion(revision.value().toInt()); if (!extraVersions.contains(extraVersion)) extraVersions.append(extraVersion); } @@ -60,7 +61,7 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject> void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, - bool topLevel) + CollectMode mode, QTypeRevision defaultRevision) { const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { @@ -69,18 +70,19 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QString value = obj[QLatin1String("value")].toString(); if (name == QLatin1String("DefaultProperty")) { - if (defaultProp.isEmpty()) + if (mode != AttachedType && defaultProp.isEmpty()) defaultProp = value; - } else if (name == QLatin1String("QML.AddedInMinorVersion")) { - if (topLevel) { - addedInRevision = value.toInt(); - revisions.append(value.toInt()); + } else if (name == QLatin1String("QML.AddedInVersion")) { + const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt()); + if (mode == TopLevel) { + addedInRevision = revision; + revisions.append(revision); } else if (!elementName.isEmpty()) { - revisions.append(value.toInt()); + revisions.append(revision); } } - if (!topLevel) + if (mode != TopLevel) continue; // These only apply to the original class @@ -89,32 +91,28 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, elementName = classDef->value(QLatin1String("className")).toString(); else if (value != QLatin1String("anonymous")) elementName = value; - } else if (name == QLatin1String("QML.RemovedInMinorVersion")) { - removedInRevision = value.toInt(); + } else if (name == QLatin1String("QML.RemovedInVersion")) { + removedInRevision = QTypeRevision::fromEncodedVersion(value.toInt()); } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { - attachedType = value; - if (const QJsonObject *other = findType(types, attachedType)) - collect(other, types, foreign, false); - else if (const QJsonObject *other = findType(foreign, attachedType)) - collect(other, types, foreign, false); + collectAttached(value, types, foreign, defaultRevision); } else if (name == QLatin1String("QML.Singleton")) { if (value == QLatin1String("true")) isSingleton = true; } else if (name == QLatin1String("QML.Foreign")) { if (const QJsonObject *other = findType(foreign, value)) { classDef = other; - if (defaultProp.isEmpty()) { - // Foreign type can have a default property - const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); - for (const QJsonValue &classInfo : classInfos) { - QJsonObject obj = classInfo.toObject(); - if (obj[QLatin1String("name")].toString() == QLatin1String("DefaultProperty")) { - defaultProp = obj[QLatin1String("value")].toString(); - break; - } - } + // Foreign type can have a default property or an attached types + const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); + for (const QJsonValue &classInfo : classInfos) { + 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")) + defaultProp = foreignValue; + else if (foreignName == QLatin1String("QML.Attached")) + collectAttached(foreignValue, types, foreign, defaultRevision); } } } else if (name == QLatin1String("QML.Root")) { @@ -125,7 +123,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } } - if (!elementName.isEmpty()) { + if (mode == AttachedType || !elementName.isEmpty()) { collectExtraVersions(classDef, QString::fromLatin1("properties"), revisions); collectExtraVersions(classDef, QString::fromLatin1("slots"), revisions); collectExtraVersions(classDef, QString::fromLatin1("methods"), revisions); @@ -137,19 +135,22 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QJsonObject superObject = supers.first().toObject(); if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) { const QString superName = superObject[QLatin1String("name")].toString(); - if (topLevel && superClass.isEmpty()) + if (mode == TopLevel && superClass.isEmpty()) superClass = superName; + const CollectMode superMode = (mode == TopLevel) ? SuperClass : AttachedType; if (const QJsonObject *other = findType(types, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, superMode, defaultRevision); else if (const QJsonObject *other = findType(foreign, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, superMode, defaultRevision); } } - if (addedInRevision == -1) { - revisions.append(0); - addedInRevision = 0; + if (!addedInRevision.isValid()) { + revisions.append(defaultRevision); + addedInRevision = defaultRevision; + } else if (addedInRevision < defaultRevision) { + revisions.append(defaultRevision); } std::sort(revisions.begin(), revisions.end()); @@ -157,4 +158,19 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, revisions.erase(end, revisions.end()); resolvedClass = classDef; + + // If it's not a QObject, it's not creatable + isCreatable = isCreatable && classDef->value(QLatin1String("object")).toBool(); +} + +void QmlTypesClassDescription::collectAttached(const QString &attached, + const QVector<QJsonObject> &types, + const QVector<QJsonObject> &foreign, + QTypeRevision defaultRevision) +{ + attachedType = attached; + if (const QJsonObject *other = findType(types, attachedType)) + collect(other, types, foreign, AttachedType, defaultRevision); + else if (const QJsonObject *other = findType(foreign, attachedType)) + collect(other, types, foreign, AttachedType, defaultRevision); } diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 8f3a6ea124..e4ae37a84e 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -33,6 +33,7 @@ #include <QtCore/qjsonobject.h> #include <QtCore/qvector.h> #include <QtCore/qset.h> +#include <QtCore/qversionnumber.h> struct QmlTypesClassDescription { @@ -41,16 +42,25 @@ struct QmlTypesClassDescription QString defaultProp; QString superClass; QString attachedType; - QList<int> revisions; - int addedInRevision = -1; - int removedInRevision = -1; + QList<QTypeRevision> revisions; + QTypeRevision addedInRevision; + QTypeRevision removedInRevision; bool isCreatable = true; bool isSingleton = false; bool isRootClass = false; bool isBuiltin = false; + enum CollectMode { + TopLevel, + SuperClass, + AttachedType + }; + void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, - const QVector<QJsonObject> &foreign, bool topLevel); + const QVector<QJsonObject> &foreign, CollectMode mode, + QTypeRevision defaultRevision); + void collectAttached(const QString &attached, 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 911120027e..3569bbe253 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -35,6 +35,7 @@ #include <QtCore/qsavefile.h> #include <QtCore/qfile.h> #include <QtCore/qjsondocument.h> +#include <QtCore/qversionnumber.h> static QString enquote(const QString &string) { @@ -62,24 +63,24 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle QStringList exports; QStringList metaObjects; + if (collector.isBuiltin) { + exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); + metaObjects.append(QString::number(QTypeRevision::fromVersion(1, 0).toEncodedVersion<quint16>())); + } + for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) { - const int revision = *it; + const QTypeRevision revision = *it; if (revision < collector.addedInRevision) continue; - if (collector.removedInRevision > collector.addedInRevision - && revision >= collector.removedInRevision) { + if (collector.removedInRevision.isValid() && !(revision < collector.removedInRevision)) break; - } - - if (collector.isBuiltin) { - exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); - metaObjects.append(QLatin1String("0")); - } exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4") - .arg(m_module).arg(collector.elementName) - .arg(m_majorVersion).arg(revision))); - metaObjects.append(QString::number(revision)); + .arg(m_module).arg(collector.elementName) + .arg(revision.hasMajorVersion() ? revision.majorVersion() + : m_version.majorVersion()) + .arg(revision.minorVersion()))); + metaObjects.append(QString::number(revision.toEncodedVersion<quint16>())); } m_qml.writeArrayBinding(QLatin1String("exports"), exports); @@ -245,7 +246,8 @@ void QmlTypesCreator::writeComponents() m_qml.writeStartObject(componentElement); QmlTypesClassDescription collector; - collector.collect(&component, m_ownTypes, m_foreignTypes, true); + collector.collect(&component, m_ownTypes, m_foreignTypes, + QmlTypesClassDescription::TopLevel, m_version); writeClassProperties(collector); diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h index 9207a64b7e..808c189323 100644 --- a/src/qmltyperegistrar/qmltypescreator.h +++ b/src/qmltyperegistrar/qmltypescreator.h @@ -45,7 +45,7 @@ public: void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); } void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); } void setModule(QString module) { m_module = std::move(module); } - void setMajorVersion(int majorVersion) { m_majorVersion = majorVersion; } + void setVersion(QTypeRevision version) { m_version = version; } private: void writeClassProperties(const QmlTypesClassDescription &collector); @@ -62,7 +62,7 @@ private: QVector<QJsonObject> m_ownTypes; QVector<QJsonObject> m_foreignTypes; QString m_module; - int m_majorVersion = 0; + QTypeRevision m_version = QTypeRevision::zero(); }; #endif // QMLTYPESCREATOR_H |