diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmlplugindump/main.cpp | 110 | ||||
-rw-r--r-- | tools/qmlplugindump/qmlplugindump.pro | 17 |
2 files changed, 84 insertions, 43 deletions
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index dda5d3da87..7e50118041 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -66,6 +66,7 @@ #endif QString pluginImportPath; +bool verbose = false; void collectReachableMetaObjects(const QMetaObject *meta, QSet<const QMetaObject *> *metas) { @@ -88,13 +89,15 @@ void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *met return; const QMetaObject *meta = object->metaObject(); - qDebug() << "Processing object" << meta->className(); + if (verbose) + qDebug() << "Processing object" << meta->className(); collectReachableMetaObjects(meta, metas); for (int index = 0; index < meta->propertyCount(); ++index) { QMetaProperty prop = meta->property(index); if (QDeclarativeMetaType::isQObject(prop.userType())) { - qDebug() << " Processing property" << prop.name(); + if (verbose) + qDebug() << " Processing property" << prop.name(); currentProperty = QString("%1::%2").arg(meta->className(), prop.name()); // if the property was not initialized during construction, @@ -157,29 +160,36 @@ QSet<const QMetaObject *> collectReachableMetaObjects(const QString &importCode, 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; + // 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) { - 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); + 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->module() == extensionExport->module() + && baseExport->majorVersion() == extensionExport->majorVersion() + && baseExport->minorVersion() == extensionExport->minorVersion()) { + match = true; + break; + } + } + if (!match) + newBaseExports.insert(baseExport); } - ++c; + baseExports = newBaseExports; } + qmlTypesByCppName[baseCpp] = baseExports; } // find even more QMetaObjects by instantiating QML types and running @@ -187,9 +197,15 @@ QSet<const QMetaObject *> collectReachableMetaObjects(const QString &importCode, foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) { if (ty->isExtendedType()) continue; + if (!ty->isCreatable()) + continue; + if (ty->typeName() == "QDeclarativeComponent") + continue; QByteArray tyName = ty->qmlTypeName(); tyName = tyName.mid(tyName.lastIndexOf('/') + 1); + if (tyName.isEmpty()) + continue; QByteArray code = importCode.toUtf8(); code += tyName; @@ -202,7 +218,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(const QString &importCode, if (object) collectReachableMetaObjects(object, &metas); else - qDebug() << "Could not create" << tyName << ":" << c.errorString(); + qWarning() << "Could not create" << tyName << ":" << c.errorString(); } return metas; @@ -424,9 +440,9 @@ void sigSegvHandler(int) { void printUsage(const QString &appName) { qWarning() << qPrintable(QString( - "Usage: %1 [-notrelocatable] module.uri version [module/import/path]\n" - " %1 -path path/to/qmldir/directory [version]\n" - " %1 -builtins\n" + "Usage: %1 [-v] [-notrelocatable] module.uri version [module/import/path]\n" + " %1 [-v] -path path/to/qmldir/directory [version]\n" + " %1 [-v] -builtins\n" "Example: %1 Qt.labs.particles 4.7 /home/user/dev/qt-install/imports").arg( appName)); } @@ -436,13 +452,13 @@ int main(int argc, char *argv[]) #ifdef Q_OS_UNIX // qmldump may crash, but we don't want any crash handlers to pop up // therefore we intercept the segfault and just exit() ourselves - struct sigaction action; + struct sigaction sigAction; - sigemptyset(&action.sa_mask); - action.sa_handler = &sigSegvHandler; - action.sa_flags = 0; + sigemptyset(&sigAction.sa_mask); + sigAction.sa_handler = &sigSegvHandler; + sigAction.sa_flags = 0; - sigaction(SIGSEGV, &action, 0); + sigaction(SIGSEGV, &sigAction, 0); #endif #ifdef QT_SIMULATOR @@ -452,10 +468,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); const QStringList args = app.arguments(); const QString appName = QFileInfo(app.applicationFilePath()).baseName(); - if (!(args.size() >= 3 - || (args.size() == 2 - && (args.at(1) == QLatin1String("--builtins") - || args.at(1) == QLatin1String("-builtins"))))) { + if (args.size() < 2) { printUsage(appName); return EXIT_INVALIDARGUMENTS; } @@ -463,8 +476,9 @@ int main(int argc, char *argv[]) QString pluginImportUri; QString pluginImportVersion; bool relocatable = true; - bool pathImport = false; - if (args.size() >= 3) { + enum Action { Uri, Path, Builtins }; + Action action = Uri; + { QStringList positionalArgs; foreach (const QString &arg, args) { if (!arg.startsWith(QLatin1Char('-'))) { @@ -477,14 +491,19 @@ int main(int argc, char *argv[]) relocatable = false; } else if (arg == QLatin1String("--path") || arg == QLatin1String("-path")) { - pathImport = true; + action = Path; + } else if (arg == QLatin1String("--builtins") + || arg == QLatin1String("-builtins")) { + action = Builtins; + } else if (arg == QLatin1String("-v")) { + verbose = true; } else { qWarning() << "Invalid argument: " << arg; return EXIT_INVALIDARGUMENTS; } } - if (!pathImport) { + if (action == Uri) { if (positionalArgs.size() != 3 && positionalArgs.size() != 4) { qWarning() << "Incorrect number of positional arguments"; return EXIT_INVALIDARGUMENTS; @@ -493,7 +512,7 @@ int main(int argc, char *argv[]) pluginImportVersion = positionalArgs[2]; if (positionalArgs.size() >= 4) pluginImportPath = positionalArgs[3]; - } else { + } else if (action == Path) { if (positionalArgs.size() != 2 && positionalArgs.size() != 3) { qWarning() << "Incorrect number of positional arguments"; return EXIT_INVALIDARGUMENTS; @@ -501,6 +520,11 @@ int main(int argc, char *argv[]) pluginImportPath = QDir::fromNativeSeparators(positionalArgs[1]); if (positionalArgs.size() == 3) pluginImportVersion = positionalArgs[2]; + } else if (action == Builtins) { + if (positionalArgs.size() != 1) { + qWarning() << "Incorrect number of positional arguments"; + return EXIT_INVALIDARGUMENTS; + } } } @@ -516,11 +540,11 @@ int main(int argc, char *argv[]) // this will hold the meta objects we want to dump information of QSet<const QMetaObject *> metas; - if (pluginImportUri.isEmpty() && !pathImport) { + if (action == Builtins) { metas = defaultReachable; } else { // find all QMetaObjects reachable when the specified module is imported - if (!pathImport) { + if (action != Path) { importCode += QString("import %0 %1\n").arg(pluginImportUri, pluginImportVersion).toAscii(); } else { // pluginImportVersion can be empty @@ -567,7 +591,7 @@ int main(int argc, char *argv[]) QmlStreamWriter qml(&bytes); qml.writeStartDocument(); - qml.writeLibraryImport(QLatin1String("QtQuick.tooling"), 1, 0); + qml.writeLibraryImport(QLatin1String("QtQuick.tooling"), 1, 1); qml.write("\n" "// This file describes the plugin-supplied types contained in the library.\n" "// It is used for QML tooling purposes only.\n" diff --git a/tools/qmlplugindump/qmlplugindump.pro b/tools/qmlplugindump/qmlplugindump.pro index b9fc0fc0ad..2e5ac5e366 100644 --- a/tools/qmlplugindump/qmlplugindump.pro +++ b/tools/qmlplugindump/qmlplugindump.pro @@ -16,5 +16,22 @@ HEADERS += \ OTHER_FILES += Info.plist macx: QMAKE_INFO_PLIST = Info.plist +# Build debug and release versions of the tool on Windows - +# if debug and release versions of Qt have been built. +!build_pass:win32 { + CONFIG -= debug release debug_and_release build_all + + contains(QT_CONFIG,debug):contains(QT_CONFIG,release) { + CONFIG += debug_and_release build_all + } else { + contains(QT_CONFIG,debug): CONFIG += debug + contains(QT_CONFIG,release): CONFIG += release + } +} + +CONFIG(debug, debug|release) { + win32: TARGET = $$join(TARGET,,,d) +} + target.path = $$[QT_INSTALL_BINS] INSTALLS += target |