diff options
author | Christian Kamm <[email protected]> | 2010-11-26 14:24:59 +0100 |
---|---|---|
committer | Christian Kamm <[email protected]> | 2010-11-26 14:27:13 +0100 |
commit | 3fcbbd1a65eff177062a25d8cb1bf02241aeae86 (patch) | |
tree | 4fdadc0b25ddde72bfad8e5d3bce598c4b2b1cbf /src/plugins/qmljstools/qmljsplugindumper.cpp | |
parent | 42fbb45b090be0c7068a529cecc6be5f497fd47a (diff) |
QmlJS: Allow QML plugins to ship pre-dumped type descriptions.
If there's a library.xml file next to the qmldir file, Creator will
read that instead of trying to run qmldump on the library.
Reviewed-by: Erik Verbruggen
Diffstat (limited to 'src/plugins/qmljstools/qmljsplugindumper.cpp')
-rw-r--r-- | src/plugins/qmljstools/qmljsplugindumper.cpp | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/src/plugins/qmljstools/qmljsplugindumper.cpp b/src/plugins/qmljstools/qmljsplugindumper.cpp index bcaaaac7be3..bc514fc54c1 100644 --- a/src/plugins/qmljstools/qmljsplugindumper.cpp +++ b/src/plugins/qmljstools/qmljsplugindumper.cpp @@ -65,7 +65,8 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString & if (m_runningQmldumps.values().contains(canonicalLibraryPath)) return; const Snapshot snapshot = m_modelManager->snapshot(); - if (snapshot.libraryInfo(canonicalLibraryPath).dumpStatus() != LibraryInfo::DumpNotStartedOrRunning) + const LibraryInfo libraryInfo = snapshot.libraryInfo(canonicalLibraryPath); + if (libraryInfo.dumpStatus() != LibraryInfo::DumpNotStartedOrRunning) return; // avoid inserting the same plugin twice @@ -82,12 +83,20 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString & plugin.importPath = importPath; plugin.importUri = importUri; + // watch plugin libraries foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) { const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name); m_pluginWatcher->addFile(pluginLibrary); m_libraryToPluginIndex.insert(pluginLibrary, index); } + // watch library xml file + if (plugin.hasPredumpedXmlFile()) { + const QString &path = plugin.predumpedXmlFilePath(); + m_pluginWatcher->addFile(path); + m_libraryToPluginIndex.insert(path, index); + } + dump(plugin); } @@ -112,6 +121,23 @@ static QString qmldumpFailedMessage() return PluginDumper::tr("Type dump of C++ plugin failed.\nCheck 'General Messages' output pane for details."); } +static QList<const Interpreter::FakeMetaObject *> parseHelper(const QByteArray &xml, QString *error) +{ + QList<const Interpreter::FakeMetaObject *> ret; + QMap<QString, Interpreter::FakeMetaObject *> newObjects; + *error = Interpreter::CppQmlTypesLoader::parseQmlTypeXml(xml, &newObjects); + + if (error->isEmpty()) { + // convert from QList<T *> to QList<const T *> + QMapIterator<QString, Interpreter::FakeMetaObject *> it(newObjects); + while (it.hasNext()) { + it.next(); + ret.append(it.value()); + } + } + return ret; +} + void PluginDumper::qmlPluginTypeDumpDone(int exitCode) { QProcess *process = qobject_cast<QProcess *>(sender()); @@ -130,20 +156,13 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode) } const QByteArray output = process->readAllStandardOutput(); - QMap<QString, Interpreter::FakeMetaObject *> newObjects; - const QString error = Interpreter::CppQmlTypesLoader::parseQmlTypeXml(output, &newObjects); - if (!error.isEmpty()) { + QString error; + QList<const Interpreter::FakeMetaObject *> objectsList = parseHelper(output, &error); + if (exitCode == 0 && !error.isEmpty()) { libraryInfo.setDumpStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error)); } if (exitCode == 0 && error.isEmpty()) { - // convert from QList<T *> to QList<const T *> - QList<const Interpreter::FakeMetaObject *> objectsList; - QMapIterator<QString, Interpreter::FakeMetaObject *> it(newObjects); - while (it.hasNext()) { - it.next(); - objectsList.append(it.value()); - } libraryInfo.setMetaObjects(objectsList); if (libraryPath.isEmpty()) Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList); @@ -186,6 +205,38 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary) void PluginDumper::dump(const Plugin &plugin) { + if (plugin.hasPredumpedXmlFile()) { + const Snapshot snapshot = m_modelManager->snapshot(); + LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); + if (!libraryInfo.isValid()) + return; + + const QString &path = plugin.predumpedXmlFilePath(); + QFile libraryXmlFile(path); + if (!libraryXmlFile.open(QFile::ReadOnly | QFile::Text)) { + libraryInfo.setDumpStatus(LibraryInfo::DumpError, + tr("Could not open file '%1' for reading.").arg(path)); + m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo); + return; + } + + const QByteArray xml = libraryXmlFile.readAll(); + libraryXmlFile.close(); + + QString error; + const QList<const Interpreter::FakeMetaObject *> objectsList = parseHelper(xml, &error); + + if (error.isEmpty()) { + libraryInfo.setMetaObjects(objectsList); + libraryInfo.setDumpStatus(LibraryInfo::DumpDone); + } else { + libraryInfo.setDumpStatus(LibraryInfo::DumpError, + tr("Failed to parse '%1'.\nError: %2").arg(path, error)); + } + m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo); + return; + } + ProjectExplorer::Project *activeProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject(); if (!activeProject) return; @@ -323,3 +374,13 @@ QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldi return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib")); #endif } + +bool PluginDumper::Plugin::hasPredumpedXmlFile() const +{ + return QFileInfo(predumpedXmlFilePath()).isFile(); +} + +QString PluginDumper::Plugin::predumpedXmlFilePath() const +{ + return QString("%1%2library.xml").arg(qmldirPath, QDir::separator()); +} |