aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorCaroline Chao <caroline.chao@digia.com>2013-09-03 14:03:21 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-13 08:51:33 +0200
commit0ef673efe8bf381e1aa0202752deac27e86ada53 (patch)
tree33be088ca3cc6f447bf2f2dc5fee17fab0324641 /tools
parent32a69d67afbe146f8edbca4b018ebaf36d47b076 (diff)
qmlplugindump: Add support for composite types
Task-number: QTBUG-33106 Change-Id: I80fc817eb59256e860f3fdd591104930688ef84c Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/qmlplugindump/main.cpp193
1 files changed, 139 insertions, 54 deletions
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index ead6392d7f..f312604e17 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -140,6 +140,9 @@ public:
*/
static QHash<QByteArray, QSet<const QQmlType *> > qmlTypesByCppName;
+// No different versioning possible for a composite type.
+static QMap<QString, const QQmlType * > qmlTypesByCompositeName;
+
static QHash<QByteArray, QByteArray> cppToId;
/* Takes a C++ type name, such as Qt::LayoutDirection or QString and
@@ -191,8 +194,9 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const
if (ty->isExtendedType())
extensions[ty->typeName()].insert(ty->metaObject()->className());
collectReachableMetaObjects(ty, &metas);
+ } else {
+ qmlTypesByCompositeName[ty->elementName()] = ty;
}
- // TODO actually handle composite types
}
// Adjust exports of the base object if there are extensions.
@@ -288,6 +292,135 @@ public:
relocatableModuleUri = uri;
}
+ const QString getExportString(QString qmlTyName, int majorVersion, int minorVersion)
+ {
+ if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) {
+ qmlTyName.remove(0, relocatableModuleUri.size() + 1);
+ }
+ if (qmlTyName.startsWith("./")) {
+ qmlTyName.remove(0, 2);
+ }
+ if (qmlTyName.startsWith("/")) {
+ qmlTyName.remove(0, 1);
+ }
+ const QString exportString = enquote(
+ QString("%1 %2.%3").arg(
+ qmlTyName,
+ QString::number(majorVersion),
+ QString::number(minorVersion)));
+ return exportString;
+ }
+
+ void writeMetaContent(const QMetaObject *meta)
+ {
+ QSet<QString> implicitSignals;
+ for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
+ const QMetaProperty &property = meta->property(index);
+ dump(property);
+ implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
+ }
+
+ if (meta == &QObject::staticMetaObject) {
+ // for QObject, hide deleteLater() and onDestroyed
+ for (int index = meta->methodOffset(); index < meta->methodCount(); ++index) {
+ QMetaMethod method = meta->method(index);
+ QByteArray signature = method.methodSignature();
+ if (signature == QByteArrayLiteral("destroyed(QObject*)")
+ || signature == QByteArrayLiteral("destroyed()")
+ || signature == QByteArrayLiteral("deleteLater()"))
+ continue;
+ dump(method, implicitSignals);
+ }
+
+ // and add toString(), destroy() and destroy(int)
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
+ qml->writeEndObject();
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeEndObject();
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeStartObject(QLatin1String("Parameter"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
+ qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
+ qml->writeEndObject();
+ qml->writeEndObject();
+ } else {
+ for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
+ dump(meta->method(index), implicitSignals);
+ }
+ }
+
+ QString getPrototypeNameForCompositeType(const QMetaObject *metaObject)
+ {
+ QString prototypeName;
+ const QMetaObject *superMetaObject = metaObject->superClass();
+ if (!superMetaObject)
+ return "QObject";
+ QString className = convertToId(superMetaObject->className());
+ if (className.startsWith("QQuick"))
+ prototypeName = className;
+ else
+ prototypeName = getPrototypeNameForCompositeType(superMetaObject);
+ return prototypeName;
+ }
+
+ void dumpComposite(QQmlEngine *engine, const QQmlType *compositeType, QSet<QByteArray> &defaultReachableNames)
+ {
+
+ QQmlComponent e(engine, compositeType->sourceUrl());
+ QObject *object = e.create();
+
+ if (!object)
+ return;
+
+ qml->writeStartObject("Component");
+
+ const QMetaObject *mainMeta = object->metaObject();
+
+ // Get C++ base class name for the composite type
+ QString prototypeName = getPrototypeNameForCompositeType(mainMeta);
+ qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
+
+ QString qmlTyName = compositeType->qmlTypeName();
+ // name should be unique
+ qml->writeScriptBinding(QLatin1String("name"), enquote(qmlTyName));
+ const QString exportString = getExportString(qmlTyName, compositeType->majorVersion(), compositeType->minorVersion());
+ qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString);
+ qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType->minorVersion()));
+
+ for (int index = mainMeta->classInfoCount() - 1 ; index >= 0 ; --index) {
+ QMetaClassInfo classInfo = mainMeta->classInfo(index);
+ if (QLatin1String(classInfo.name()) == QLatin1String("DefaultProperty")) {
+ qml->writeScriptBinding(QLatin1String("defaultProperty"), enquote(QLatin1String(classInfo.value())));
+ break;
+ }
+ }
+
+ QSet<const QMetaObject *> metas;
+ QSet<const QMetaObject *> candidatesComposite;
+ collectReachableMetaObjects(mainMeta, &candidatesComposite);
+
+ // Also eliminate meta objects with the same classname.
+ // This is required because extended objects seem not to share
+ // a single meta object instance.
+ foreach (const QMetaObject *mo, candidatesComposite) {
+ if (!defaultReachableNames.contains(mo->className()))
+ metas.insert(mo);
+ }
+
+ // put the metaobjects into a map so they are always dumped in the same order
+ QMap<QString, const QMetaObject *> nameToMeta;
+ foreach (const QMetaObject *meta, metas)
+ nameToMeta.insert(convertToId(meta), meta);
+
+ foreach (const QMetaObject *meta, nameToMeta)
+ writeMetaContent(meta);
+
+ qml->writeEndObject();
+ }
+
void dump(const QMetaObject *meta)
{
qml->writeStartObject("Component");
@@ -311,21 +444,7 @@ public:
QHash<QString, const QQmlType *> exports;
foreach (const QQmlType *qmlTy, qmlTypes) {
- QString qmlTyName = qmlTy->qmlTypeName();
- if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) {
- qmlTyName.remove(0, relocatableModuleUri.size() + 1);
- }
- if (qmlTyName.startsWith("./")) {
- qmlTyName.remove(0, 2);
- }
- if (qmlTyName.startsWith("/")) {
- qmlTyName.remove(0, 1);
- }
- const QString exportString = enquote(
- QString("%1 %2.%3").arg(
- qmlTyName,
- QString::number(qmlTy->majorVersion()),
- QString::number(qmlTy->minorVersion())));
+ const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion());
exports.insert(exportString, qmlTy);
}
@@ -355,43 +474,7 @@ public:
for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index)
dump(meta->enumerator(index));
- QSet<QString> implicitSignals;
- for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
- const QMetaProperty &property = meta->property(index);
- dump(property);
- implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
- }
-
- if (meta == &QObject::staticMetaObject) {
- // for QObject, hide deleteLater() and onDestroyed
- for (int index = meta->methodOffset(); index < meta->methodCount(); ++index) {
- QMetaMethod method = meta->method(index);
- QByteArray signature = method.methodSignature();
- if (signature == QByteArrayLiteral("destroyed(QObject*)")
- || signature == QByteArrayLiteral("destroyed()")
- || signature == QByteArrayLiteral("deleteLater()"))
- continue;
- dump(method, implicitSignals);
- }
-
- // and add toString(), destroy() and destroy(int)
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeStartObject(QLatin1String("Parameter"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
- qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
- qml->writeEndObject();
- qml->writeEndObject();
- } else {
- for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
- dump(meta->method(index), implicitSignals);
- }
+ writeMetaContent(meta);
qml->writeEndObject();
}
@@ -673,6 +756,7 @@ int main(int argc, char *argv[])
// add some otherwise unreachable QMetaObjects
defaultReachable.insert(&QQuickMouseEvent::staticMetaObject);
// QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
+ QSet<QByteArray> defaultReachableNames;
// this will hold the meta objects we want to dump information of
QSet<const QMetaObject *> metas;
@@ -724,7 +808,6 @@ int main(int argc, char *argv[])
// Also eliminate meta objects with the same classname.
// This is required because extended objects seem not to share
// a single meta object instance.
- QSet<QByteArray> defaultReachableNames;
foreach (const QMetaObject *mo, defaultReachable)
defaultReachableNames.insert(QByteArray(mo->className()));
foreach (const QMetaObject *mo, candidates) {
@@ -762,6 +845,8 @@ int main(int argc, char *argv[])
foreach (const QMetaObject *meta, nameToMeta) {
dumper.dump(meta);
}
+ foreach (const QQmlType *compositeType, qmlTypesByCompositeName)
+ dumper.dumpComposite(&engine, compositeType, defaultReachableNames);
// define QEasingCurve as an extension of QQmlEasingValueType, this way
// properties using the QEasingCurve type get useful type information.