QmlJS: Honor typeinfo lines in qmldir files.

Change-Id: I1ddad1eb031bc4b95671be4a474b5e8e72f6e350
Reviewed-on: http://codereview.qt-project.org/4137
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
This commit is contained in:
Christian Kamm
2011-09-02 13:25:08 +02:00
parent 10a956a8f7
commit bfc95befa8
4 changed files with 59 additions and 37 deletions

View File

@@ -373,6 +373,7 @@ LibraryInfo::LibraryInfo(const QmlDirParser &parser)
: _status(Found) : _status(Found)
, _components(parser.components()) , _components(parser.components())
, _plugins(parser.plugins()) , _plugins(parser.plugins())
, _typeinfos(parser.typeInfos())
, _dumpStatus(NoTypeInfo) , _dumpStatus(NoTypeInfo)
{ {
} }

View File

@@ -142,6 +142,7 @@ private:
Status _status; Status _status;
QList<QmlDirParser::Component> _components; QList<QmlDirParser::Component> _components;
QList<QmlDirParser::Plugin> _plugins; QList<QmlDirParser::Plugin> _plugins;
QList<QmlDirParser::TypeInfo> _typeinfos;
typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList; typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList;
FakeMetaObjectList _metaObjects; FakeMetaObjectList _metaObjects;
@@ -159,6 +160,9 @@ public:
QList<QmlDirParser::Plugin> plugins() const QList<QmlDirParser::Plugin> plugins() const
{ return _plugins; } { return _plugins; }
QList<QmlDirParser::TypeInfo> typeInfos() const
{ return _typeinfos; }
FakeMetaObjectList metaObjects() const FakeMetaObjectList metaObjects() const
{ return _metaObjects; } { return _metaObjects; }

View File

@@ -119,7 +119,7 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
// prefer QTDIR/imports/builtins.qmltypes if available // prefer QTDIR/imports/builtins.qmltypes if available
const QString builtinQmltypesPath = info.qtImportsPath + QLatin1String("/builtins.qmltypes"); const QString builtinQmltypesPath = info.qtImportsPath + QLatin1String("/builtins.qmltypes");
if (QFile::exists(builtinQmltypesPath)) { if (QFile::exists(builtinQmltypesPath)) {
loadQmltypesFile(builtinQmltypesPath, info.qtImportsPath, builtinInfo); loadQmltypesFile(QStringList(builtinQmltypesPath), info.qtImportsPath, builtinInfo);
return; return;
} }
@@ -134,6 +134,13 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
m_qtToInfo.insert(info.qtImportsPath, info); 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) void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{ {
const QString canonicalLibraryPath = QDir::cleanPath(libraryPath); const QString canonicalLibraryPath = QDir::cleanPath(libraryPath);
@@ -159,6 +166,16 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
plugin.importUri = importUri; plugin.importUri = importUri;
plugin.importVersion = importVersion; 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 // watch plugin libraries
foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) { foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name); 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 // watch library qmltypes file
if (plugin.hasPredumpedQmlTypesFile()) { if (!plugin.typeInfoPaths.isEmpty()) {
const QString &path = plugin.predumpedQmlTypesFilePath(); foreach (const QString &path, plugin.typeInfoPaths) {
if (!path.isEmpty()) { if (!QFile::exists(path))
continue;
if (!pluginWatcher()->watchesFile(path)) if (!pluginWatcher()->watchesFile(path))
pluginWatcher()->addFile(path, Utils::FileSystemWatcher::WatchModifiedDate); pluginWatcher()->addFile(path, Utils::FileSystemWatcher::WatchModifiedDate);
m_libraryToPluginIndex.insert(path, index); m_libraryToPluginIndex.insert(path, index);
@@ -316,43 +334,54 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary)
dump(plugin); dump(plugin);
} }
void PluginDumper::loadQmltypesFile(const QString &qmltypesFilePath, void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
const QString &libraryPath, const QString &libraryPath,
QmlJS::LibraryInfo libraryInfo) QmlJS::LibraryInfo libraryInfo)
{ {
Utils::FileReader reader; QStringList errors;
if (!reader.fetch(qmltypesFilePath, QFile::Text)) { QStringList warnings;
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, reader.errorString()); QList<FakeMetaObject::ConstPtr> objects;
m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
return; foreach (const QString &qmltypesFilePath, qmltypesFilePaths) {
Utils::FileReader reader;
if (!reader.fetch(qmltypesFilePath, QFile::Text)) {
errors += reader.errorString();
continue;
}
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;
} }
QString error; libraryInfo.setMetaObjects(objects);
QString warning; if (errors.isEmpty()) {
const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(reader.data(), &error, &warning);
if (error.isEmpty()) {
libraryInfo.setMetaObjects(objectsList);
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone); libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone);
} else { } else {
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, errors.prepend(tr("Errors while reading typeinfo files:"));
tr("Failed to parse '%1'.\nError: %2").arg(qmltypesFilePath, error)); 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); m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
} }
void PluginDumper::dump(const Plugin &plugin) 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(); const Snapshot snapshot = m_modelManager->snapshot();
LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath);
if (!libraryInfo.isValid()) if (!libraryInfo.isValid())
return; return;
loadQmltypesFile(plugin.predumpedQmlTypesFilePath(), plugin.qmldirPath, libraryInfo); loadQmltypesFile(plugin.typeInfoPaths, plugin.qmldirPath, libraryInfo);
return; return;
} }
@@ -501,13 +530,3 @@ QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldi
return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib")); return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
#endif #endif
} }
bool PluginDumper::Plugin::hasPredumpedQmlTypesFile() const
{
return QFileInfo(predumpedQmlTypesFilePath()).isFile();
}
QString PluginDumper::Plugin::predumpedQmlTypesFilePath() const
{
return QString("%1%2plugins.qmltypes").arg(qmldirPath, QDir::separator());
}

View File

@@ -83,13 +83,11 @@ private:
QString importPath; QString importPath;
QString importUri; QString importUri;
QString importVersion; QString importVersion;
QStringList typeInfoPaths;
bool hasPredumpedQmlTypesFile() const;
QString predumpedQmlTypesFilePath() const;
}; };
void dump(const Plugin &plugin); void dump(const Plugin &plugin);
void loadQmltypesFile(const QString &qmltypesFilePath, void loadQmltypesFile(const QStringList &qmltypesFilePaths,
const QString &libraryPath, const QString &libraryPath,
QmlJS::LibraryInfo libraryInfo); QmlJS::LibraryInfo libraryInfo);
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,