diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index 897c56a891333469976ffcb85e4943f2c6a21c65..831e9fb160b0879c435bae82a36bcbe71e0f2c44 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -373,6 +373,7 @@ LibraryInfo::LibraryInfo(const QmlDirParser &parser) : _status(Found) , _components(parser.components()) , _plugins(parser.plugins()) + , _typeinfos(parser.typeInfos()) , _dumpStatus(NoTypeInfo) { } diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h index 9b6191d8fa125c4f7248ebaff63f5f43ce1e6f61..b2f824cecb0da69e4612f6e0ad38ebc55d64c42e 100644 --- a/src/libs/qmljs/qmljsdocument.h +++ b/src/libs/qmljs/qmljsdocument.h @@ -142,6 +142,7 @@ private: Status _status; QList<QmlDirParser::Component> _components; QList<QmlDirParser::Plugin> _plugins; + QList<QmlDirParser::TypeInfo> _typeinfos; typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList; FakeMetaObjectList _metaObjects; @@ -159,6 +160,9 @@ public: QList<QmlDirParser::Plugin> plugins() const { return _plugins; } + QList<QmlDirParser::TypeInfo> typeInfos() const + { return _typeinfos; } + FakeMetaObjectList metaObjects() const { return _metaObjects; } diff --git a/src/plugins/qmljstools/qmljsplugindumper.cpp b/src/plugins/qmljstools/qmljsplugindumper.cpp index 1130f773b32524dd1489a74c46eb9c3c1dcc6f32..f27373e4b286e51d2ff06d9105fcfe8cda7e2be4 100644 --- a/src/plugins/qmljstools/qmljsplugindumper.cpp +++ b/src/plugins/qmljstools/qmljsplugindumper.cpp @@ -119,7 +119,7 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec // prefer QTDIR/imports/builtins.qmltypes if available const QString builtinQmltypesPath = info.qtImportsPath + QLatin1String("/builtins.qmltypes"); if (QFile::exists(builtinQmltypesPath)) { - loadQmltypesFile(builtinQmltypesPath, info.qtImportsPath, builtinInfo); + loadQmltypesFile(QStringList(builtinQmltypesPath), info.qtImportsPath, builtinInfo); return; } @@ -134,6 +134,13 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec m_qtToInfo.insert(info.qtImportsPath, info); } +static QString makeAbsolute(const QString &path, const QString &base) +{ + if (QFileInfo(path).isAbsolute()) + return path; + return QString("%1%2%3").arg(base, QDir::separator(), path); +} + void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion) { const QString canonicalLibraryPath = QDir::cleanPath(libraryPath); @@ -159,6 +166,16 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString & plugin.importUri = importUri; plugin.importVersion = importVersion; + // add default qmltypes file if it exists + const QLatin1String defaultQmltypesFileName("plugins.qmltypes"); + const QString defaultQmltypesPath = makeAbsolute(defaultQmltypesFileName, canonicalLibraryPath); + if (QFile::exists(defaultQmltypesPath)) + plugin.typeInfoPaths += defaultQmltypesPath; + + // add typeinfo files listed in qmldir + foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos()) + plugin.typeInfoPaths += makeAbsolute(typeInfo.fileName, canonicalLibraryPath); + // watch plugin libraries foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) { const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name); @@ -169,10 +186,11 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString & } } - // watch library xml file - if (plugin.hasPredumpedQmlTypesFile()) { - const QString &path = plugin.predumpedQmlTypesFilePath(); - if (!path.isEmpty()) { + // watch library qmltypes file + if (!plugin.typeInfoPaths.isEmpty()) { + foreach (const QString &path, plugin.typeInfoPaths) { + if (!QFile::exists(path)) + continue; if (!pluginWatcher()->watchesFile(path)) pluginWatcher()->addFile(path, Utils::FileSystemWatcher::WatchModifiedDate); m_libraryToPluginIndex.insert(path, index); @@ -316,43 +334,54 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary) dump(plugin); } -void PluginDumper::loadQmltypesFile(const QString &qmltypesFilePath, +void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths, const QString &libraryPath, QmlJS::LibraryInfo libraryInfo) { - Utils::FileReader reader; - if (!reader.fetch(qmltypesFilePath, QFile::Text)) { - libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, reader.errorString()); - m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); - return; - } + QStringList errors; + QStringList warnings; + QList<FakeMetaObject::ConstPtr> objects; + + foreach (const QString &qmltypesFilePath, qmltypesFilePaths) { + Utils::FileReader reader; + if (!reader.fetch(qmltypesFilePath, QFile::Text)) { + errors += reader.errorString(); + continue; + } - QString error; - QString warning; - const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(reader.data(), &error, &warning); + QString error; + QString warning; + objects += parseHelper(reader.data(), &error, &warning); + if (!error.isEmpty()) + errors += tr("Failed to parse '%1'.\nError: %2").arg(qmltypesFilePath, error); + if (!warning.isEmpty()) + warnings += warning; + } - if (error.isEmpty()) { - libraryInfo.setMetaObjects(objectsList); + libraryInfo.setMetaObjects(objects); + if (errors.isEmpty()) { libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone); } else { - libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, - tr("Failed to parse '%1'.\nError: %2").arg(qmltypesFilePath, error)); + errors.prepend(tr("Errors while reading typeinfo files:")); + libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, errors.join(QLatin1String("\n"))); } - if (!warning.isEmpty()) - printParseWarnings(libraryPath, warning); + + if (!warnings.isEmpty()) + printParseWarnings(libraryPath, warnings.join(QLatin1String("\n"))); m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); } void PluginDumper::dump(const Plugin &plugin) { - if (plugin.hasPredumpedQmlTypesFile()) { + // if there are type infos, don't dump! + if (!plugin.typeInfoPaths.isEmpty()) { const Snapshot snapshot = m_modelManager->snapshot(); LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); if (!libraryInfo.isValid()) return; - loadQmltypesFile(plugin.predumpedQmlTypesFilePath(), plugin.qmldirPath, libraryInfo); + loadQmltypesFile(plugin.typeInfoPaths, plugin.qmldirPath, libraryInfo); return; } @@ -501,13 +530,3 @@ QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldi return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib")); #endif } - -bool PluginDumper::Plugin::hasPredumpedQmlTypesFile() const -{ - return QFileInfo(predumpedQmlTypesFilePath()).isFile(); -} - -QString PluginDumper::Plugin::predumpedQmlTypesFilePath() const -{ - return QString("%1%2plugins.qmltypes").arg(qmldirPath, QDir::separator()); -} diff --git a/src/plugins/qmljstools/qmljsplugindumper.h b/src/plugins/qmljstools/qmljsplugindumper.h index 34e203c2bbf86e2e834f34df0cc185900bea52bd..9f782e30ed06276b3a9672008504e1e353d2f0b3 100644 --- a/src/plugins/qmljstools/qmljsplugindumper.h +++ b/src/plugins/qmljstools/qmljsplugindumper.h @@ -83,13 +83,11 @@ private: QString importPath; QString importUri; QString importVersion; - - bool hasPredumpedQmlTypesFile() const; - QString predumpedQmlTypesFilePath() const; + QStringList typeInfoPaths; }; void dump(const Plugin &plugin); - void loadQmltypesFile(const QString &qmltypesFilePath, + void loadQmltypesFile(const QStringList &qmltypesFilePaths, const QString &libraryPath, QmlJS::LibraryInfo libraryInfo); QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,