foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) { qmlTypesByCppName[ty->metaObject()->className()].insert(ty); if (ty->isExtendedType()) { extensions[ty->typeName()].insert(ty->metaObject()->className()); } collectReachableMetaObjects(ty, &metas); } // Adjust exports of the base object if there are extensions. // For each export of a base object there can be a single extension object overriding it. // Example: QDeclarativeGraphicsWidget overrides the QtQuick/QGraphicsWidget export // of QGraphicsWidget. foreach (const QByteArray &baseCpp, extensions.keys()) { QSet<const QDeclarativeType *> baseExports = qmlTypesByCppName.value(baseCpp); const QSet<QByteArray> extensionCppNames = extensions.value(baseCpp); foreach (const QByteArray &extensionCppName, extensionCppNames) { const QSet<const QDeclarativeType *> extensionExports = qmlTypesByCppName.value(extensionCppName); // remove extension exports from base imports // unfortunately the QDeclarativeType pointers don't match, so can't use QSet::substract QSet<const QDeclarativeType *> newBaseExports; foreach (const QDeclarativeType *baseExport, baseExports) { bool match = false; foreach (const QDeclarativeType *extensionExport, extensionExports) { if (baseExport->qmlTypeName() == extensionExport->qmlTypeName() && baseExport->majorVersion() == extensionExport->majorVersion() && baseExport->minorVersion() == extensionExport->minorVersion()) { match = true; break; }
collectReachableMetaObjects(ty, &metas); } // Adjust ids of extended objects. // The chain ends up being: // __extended__.originalname - the base object // __extension_0_.originalname - first extension // .. // __extension_n-2_.originalname - second to last extension // originalname - last extension // ### does this actually work for multiple extensions? it seems like the prototypes might be wrong foreach (const QByteArray &extendedCpp, extensions.keys()) { cppToId.remove(extendedCpp); const QByteArray extendedId = convertToId(extendedCpp); cppToId.insert(extendedCpp, "__extended__." + extendedId); QSet<QByteArray> extensionCppNames = extensions.value(extendedCpp); int c = 0; foreach (const QByteArray &extensionCppName, extensionCppNames) { if (c != extensionCppNames.size() - 1) { QByteArray adjustedName = QString("__extension__%1.%2").arg(QString::number(c), QString(extendedId)).toAscii(); cppToId.insert(extensionCppName, adjustedName); } else { cppToId.insert(extensionCppName, extendedId); } ++c; } } // find even more QMetaObjects by instantiating QML types and running // over the instances foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) {