From e61dca72682c9f65c6ab6254fc7e80b49be3ad43 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Jun 2017 13:45:56 +0200 Subject: Change data structures in QQmlMetaTypeData Make sure any QQmlType stored in the meta type data has a refcount of 1. This should now make it possible to clean out unused types by iterating over the list of types and removing those that have a refcount of 1. Some care is still needed for C++ registered types, that will need to get one more refcount, so we don't accidentally remove them. Task-number: QTBUG-61536 Change-Id: Id2a18dae5ddcb815f34013f5fde1f05d2d9d0214 Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- tools/qmlplugindump/main.cpp | 110 +++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 55 deletions(-) (limited to 'tools/qmlplugindump') diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 911ef9e9a4..982936011d 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -164,11 +164,11 @@ public: To do this, we need to find the QQmlTypes associated with this QMetaObject. */ -static QHash > qmlTypesByCppName; +static QHash > qmlTypesByCppName; /* A composite type is completely specified by name, major version and minor version. */ -static QMap > qmlTypesByCompositeName; +static QMap > qmlTypesByCompositeName; static QHash cppToId; @@ -213,12 +213,12 @@ QByteArray convertToId(const QMetaObject *mo) // Collect all metaobjects for types registered with qmlRegisterType() without parameters void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet& metas ) { const auto qmlAllTypes = QQmlMetaType::qmlAllTypes(); - for (const QQmlType *ty : qmlAllTypes) { - if ( ! metas.contains(ty->metaObject()) ) { - if (!ty->isComposite()) { - collectReachableMetaObjects(engine, *ty, &metas); + for (const QQmlType &ty : qmlAllTypes) { + if ( ! metas.contains(ty.metaObject()) ) { + if (!ty.isComposite()) { + collectReachableMetaObjects(engine, ty, &metas); } else { - qmlTypesByCompositeName[ty->elementName()].insert(ty); + qmlTypesByCompositeName[ty.elementName()].insert(ty); } } } @@ -227,25 +227,25 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet collectReachableMetaObjects(QQmlEngine *engine, QSet &noncreatables, QSet &singletons, - const QList &skip = QList()) + const QList &skip = QList()) { QSet metas; metas.insert(FriendlyQObject::qtMeta()); QHash > extensions; const auto qmlTypes = QQmlMetaType::qmlTypes(); - for (const QQmlType *ty : qmlTypes) { - if (!ty->isCreatable()) - noncreatables.insert(ty->metaObject()); - if (ty->isSingleton()) - singletons.insert(ty->metaObject()); - if (!ty->isComposite()) { - qmlTypesByCppName[ty->metaObject()->className()].insert(ty); - if (ty->isExtendedType()) - extensions[ty->typeName()].insert(ty->metaObject()->className()); - collectReachableMetaObjects(QQmlEnginePrivate::get(engine), *ty, &metas); + for (const QQmlType &ty : qmlTypes) { + if (!ty.isCreatable()) + noncreatables.insert(ty.metaObject()); + if (ty.isSingleton()) + singletons.insert(ty.metaObject()); + if (!ty.isComposite()) { + qmlTypesByCppName[ty.metaObject()->className()].insert(ty); + if (ty.isExtendedType()) + extensions[ty.typeName()].insert(ty.metaObject()->className()); + collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas); } else { - qmlTypesByCompositeName[ty->elementName()].insert(ty); + qmlTypesByCompositeName[ty.elementName()].insert(ty); } } @@ -254,21 +254,21 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, // Example: QDeclarativeGraphicsWidget overrides the QtQuick/QGraphicsWidget export // of QGraphicsWidget. for (auto it = extensions.cbegin(), end = extensions.cend(); it != end; ++it) { - QSet baseExports = qmlTypesByCppName.value(it.key()); + QSet baseExports = qmlTypesByCppName.value(it.key()); const QSet extensionCppNames = it.value(); for (const QByteArray &extensionCppName : extensionCppNames) { - const QSet extensionExports = qmlTypesByCppName.value(extensionCppName); + const QSet extensionExports = qmlTypesByCppName.value(extensionCppName); // remove extension exports from base imports // unfortunately the QQmlType pointers don't match, so can't use QSet::subtract - QSet newBaseExports; - for (const QQmlType *baseExport : qAsConst(baseExports)) { + QSet newBaseExports; + for (const QQmlType &baseExport : qAsConst(baseExports)) { bool match = false; - for (const QQmlType *extensionExport : extensionExports) { - if (baseExport->qmlTypeName() == extensionExport->qmlTypeName() - && baseExport->majorVersion() == extensionExport->majorVersion() - && baseExport->minorVersion() == extensionExport->minorVersion()) { + for (const QQmlType &extensionExport : extensionExports) { + if (baseExport.qmlTypeName() == extensionExport.qmlTypeName() + && baseExport.majorVersion() == extensionExport.majorVersion() + && baseExport.minorVersion() == extensionExport.minorVersion()) { match = true; break; } @@ -284,17 +284,17 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, if (creatable) { // find even more QMetaObjects by instantiating QML types and running // over the instances - for (QQmlType *ty : qmlTypes) { + for (const QQmlType &ty : qmlTypes) { if (skip.contains(ty)) continue; - if (ty->isExtendedType()) + if (ty.isExtendedType()) continue; - if (!ty->isCreatable()) + if (!ty.isCreatable()) continue; - if (ty->typeName() == "QQmlComponent") + if (ty.typeName() == "QQmlComponent") continue; - QString tyName = ty->qmlTypeName(); + QString tyName = ty.qmlTypeName(); tyName = tyName.mid(tyName.lastIndexOf(QLatin1Char('/')) + 1); if (tyName.isEmpty()) continue; @@ -302,11 +302,11 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, inObjectInstantiation = tyName; QObject *object = 0; - if (ty->isSingleton()) { - QQmlType::SingletonInstanceInfo *siinfo = ty->singletonInstanceInfo(); + if (ty.isSingleton()) { + QQmlType::SingletonInstanceInfo *siinfo = ty.singletonInstanceInfo(); if (!siinfo) { std::cerr << "Internal error, " << qPrintable(tyName) - << "(" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" + << "(" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << " is singleton, but has no singletonInstanceInfo" << std::endl; continue; } @@ -324,8 +324,8 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, } else { if (verbose) std::cerr << "Trying to create object " << qPrintable( tyName ) - << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl; - object = ty->create(); + << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl; + object = ty.create(); } inObjectInstantiation.clear(); @@ -333,7 +333,7 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, if (object) { if (verbose) std::cerr << "Got " << qPrintable( tyName ) - << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl; + << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl; collectReachableMetaObjects(object, &metas); object->deleteLater(); } else { @@ -476,17 +476,17 @@ public: return prototypeName; } - void dumpComposite(QQmlEngine *engine, const QSet &compositeType, QSet &defaultReachableNames) + void dumpComposite(QQmlEngine *engine, const QSet &compositeType, QSet &defaultReachableNames) { - for (const QQmlType *type : compositeType) + for (const QQmlType &type : compositeType) dumpCompositeItem(engine, type, defaultReachableNames); } - void dumpCompositeItem(QQmlEngine *engine, const QQmlType *compositeType, QSet &defaultReachableNames) + void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet &defaultReachableNames) { - QQmlComponent e(engine, compositeType->sourceUrl()); + QQmlComponent e(engine, compositeType.sourceUrl()); if (!e.isReady()) { - std::cerr << "WARNING: skipping module " << compositeType->elementName().toStdString() + std::cerr << "WARNING: skipping module " << compositeType.elementName().toStdString() << std::endl << e.errorString().toStdString() << std::endl; return; } @@ -507,14 +507,14 @@ public: &objectsToMerge); qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName)); - QString qmlTyName = compositeType->qmlTypeName(); - const QString exportString = getExportString(qmlTyName, compositeType->majorVersion(), compositeType->minorVersion()); + QString qmlTyName = compositeType.qmlTypeName(); + const QString exportString = getExportString(qmlTyName, compositeType.majorVersion(), compositeType.minorVersion()); qml->writeScriptBinding(QLatin1String("name"), exportString); qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString); - qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType->minorVersion())); + qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion())); qml->writeBooleanBinding(QLatin1String("isComposite"), true); - if (compositeType->isSingleton()) { + if (compositeType.isSingleton()) { qml->writeBooleanBinding(QLatin1String("isCreatable"), false); qml->writeBooleanBinding(QLatin1String("isSingleton"), true); } @@ -551,12 +551,12 @@ public: if (meta->superClass()) qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()))); - const QSet qmlTypes = qmlTypesByCppName.value(meta->className()); + const QSet qmlTypes = qmlTypesByCppName.value(meta->className()); if (!qmlTypes.isEmpty()) { - QHash exports; + QHash exports; - for (const QQmlType *qmlTy : qmlTypes) { - const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion()); + for (const QQmlType &qmlTy : qmlTypes) { + const QString exportString = getExportString(qmlTy.qmlTypeName(), qmlTy.majorVersion(), qmlTy.minorVersion()); exports.insert(exportString, qmlTy); } @@ -574,12 +574,12 @@ public: // write meta object revisions QStringList metaObjectRevisions; for (const QString &exportString : qAsConst(exportStrings)) { - int metaObjectRevision = exports[exportString]->metaObjectRevision(); + int metaObjectRevision = exports[exportString].metaObjectRevision(); metaObjectRevisions += QString::number(metaObjectRevision); } qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), metaObjectRevisions); - if (const QMetaObject *attachedType = (*qmlTypes.begin())->attachedPropertiesType(engine)) { + if (const QMetaObject *attachedType = (*qmlTypes.begin()).attachedPropertiesType(engine)) { // Can happen when a type is registered that returns itself as attachedPropertiesType() // because there is no creatable type to attach to. if (attachedType != meta) { @@ -1185,7 +1185,7 @@ int main(int argc, char *argv[]) QSet uncreatableMetas; QSet singletonMetas; QSet defaultReachable = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas); - QList defaultTypes = QQmlMetaType::qmlTypes(); + QList defaultTypes = QQmlMetaType::qmlTypes(); // add some otherwise unreachable QMetaObjects defaultReachable.insert(&QQuickMouseEvent::staticMetaObject); @@ -1324,7 +1324,7 @@ int main(int argc, char *argv[]) dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta)); } - QMap >::const_iterator iter = qmlTypesByCompositeName.constBegin(); + QMap >::const_iterator iter = qmlTypesByCompositeName.constBegin(); for (; iter != qmlTypesByCompositeName.constEnd(); ++iter) dumper.dumpComposite(&engine, iter.value(), defaultReachableNames); -- cgit v1.2.3