OSDN Git Service

QmlJS: Honor typeinfo lines in qmldir files.
authorChristian Kamm <christian.d.kamm@nokia.com>
Fri, 2 Sep 2011 11:25:08 +0000 (13:25 +0200)
committerChristian Kamm <christian.d.kamm@nokia.com>
Thu, 8 Sep 2011 10:34:32 +0000 (12:34 +0200)
Change-Id: I1ddad1eb031bc4b95671be4a474b5e8e72f6e350
Reviewed-on: http://codereview.qt-project.org/4137
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
src/libs/qmljs/qmljsdocument.cpp
src/libs/qmljs/qmljsdocument.h
src/plugins/qmljstools/qmljsplugindumper.cpp
src/plugins/qmljstools/qmljsplugindumper.h

index 897c56a..831e9fb 100644 (file)
@@ -373,6 +373,7 @@ LibraryInfo::LibraryInfo(const QmlDirParser &parser)
     : _status(Found)
     , _components(parser.components())
     , _plugins(parser.plugins())
+    , _typeinfos(parser.typeInfos())
     , _dumpStatus(NoTypeInfo)
 {
 }
index 9b6191d..b2f824c 100644 (file)
@@ -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; }
 
index 1130f77..f27373e 100644 (file)
@@ -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());
-}
index 34e203c..9f782e3 100644 (file)
@@ -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,