Commit 6eadfa3a authored by Christian Kamm's avatar Christian Kamm
Browse files

Read qmldir files in a thread and cache them in Snapshot.

Reviewed-by: Erik Verbruggen
parent 4261aca7
s/qdeclarative/qml/g
s/QDECLARATIVE/QML/g
s/QDeclarative/Qml/g
# adjust pri file
s/ \$\$PWD\/qmljsglobal_p.h/ $$PWD\/qmljsglobal_p.h \\\
$$PWD\/qmldirparser_p.h \\\
$$PWD\/qmlerror.h/
s/ \$\$PWD\/qmljsparser.cpp/ $$PWD\/qmljsparser.cpp \\\
$$PWD\/qmldirparser.cpp \\\
$$PWD\/qmlerror.cpp/
......@@ -10,3 +10,5 @@ for i in $QTDIR/src/declarative/qml/qdeclarative{error.{h,cpp},dirparser{_p.h,.c
sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qdeclarative/qml/)
done
# export QmlDirParser
perl -p -0777 -i -e 's/QT_BEGIN_NAMESPACE\n\nclass QmlError;\n\nclass QmlDirParser/#include "qmljsglobal_p.h"\n\nQT_BEGIN_NAMESPACE\n\nclass QmlError;\n\nclass QML_PARSER_EXPORT QmlDirParser/' qmldirparser_p.h
......@@ -56,11 +56,13 @@
#include <QtCore/QUrl>
#include <QtCore/QHash>
#include "qmljsglobal_p.h"
QT_BEGIN_NAMESPACE
class QmlError;
class QmlDirParser
class QML_PARSER_EXPORT QmlDirParser
{
Q_DISABLE_COPY(QmlDirParser)
......
......@@ -202,6 +202,22 @@ Bind *Document::bind() const
return _bind;
}
LibraryInfo::LibraryInfo()
: _valid(false)
{
}
LibraryInfo::LibraryInfo(const QmlDirParser &parser)
: _valid(true)
, _components(parser.components())
, _plugins(parser.plugins())
{
}
LibraryInfo::~LibraryInfo()
{
}
Snapshot::Snapshot()
{
}
......@@ -216,6 +232,11 @@ void Snapshot::insert(const Document::Ptr &document)
_documents.insert(document->fileName(), document);
}
void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
{
_libraries.insert(path, info);
}
Document::Ptr Snapshot::documentFromSource(const QString &code,
const QString &fileName) const
{
......
......@@ -35,6 +35,7 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include "parser/qmldirparser_p.h"
#include "parser/qmljsengine_p.h"
#include "qmljs_global.h"
......@@ -102,10 +103,32 @@ private:
friend class Snapshot;
};
class QMLJS_EXPORT LibraryInfo
{
bool _valid;
QList<QmlDirParser::Component> _components;
QList<QmlDirParser::Plugin> _plugins;
public:
LibraryInfo();
LibraryInfo(const QmlDirParser &parser);
~LibraryInfo();
QList<QmlDirParser::Component> components() const
{ return _components; }
QList<QmlDirParser::Plugin> plugins() const
{ return _plugins; }
bool isValid() const
{ return _valid; }
};
class QMLJS_EXPORT Snapshot
{
typedef QMap<QString, Document::Ptr> _Base;
QMap<QString, Document::Ptr> _documents;
QMap<QString, LibraryInfo> _libraries;
public:
Snapshot();
......@@ -118,10 +141,14 @@ public:
const_iterator end() const { return _documents.end(); }
void insert(const Document::Ptr &document);
void insertLibraryInfo(const QString &path, const LibraryInfo &info);
Document::Ptr document(const QString &fileName) const
{ return _documents.value(fileName); }
LibraryInfo libraryInfo(const QString &path) const
{ return _libraries.value(path); }
Document::Ptr documentFromSource(const QString &code,
const QString &fileName) const;
......
#include "qmljslink.h"
#include "parser/qmljsast_p.h"
#include "parser/qmldirparser_p.h"
#include "qmljsdocument.h"
#include "qmljsbind.h"
#include "qmljsscopebuilder.h"
......@@ -289,18 +288,13 @@ void Link::importNonFile(Interpreter::ObjectValue *typeEnv, Document::Ptr doc, A
QDir dir(importPath);
if (!dir.cd(package))
continue;
if (!dir.exists("qmldir"))
continue;
QFile qmldirFile(dir.filePath("qmldir"));
qmldirFile.open(QFile::ReadOnly);
QString qmldirData = QString::fromUtf8(qmldirFile.readAll());
QmlDirParser qmldirParser;
qmldirParser.setSource(qmldirData);
qmldirParser.parse();
const LibraryInfo libraryInfo = _snapshot.libraryInfo(dir.path());
if (!libraryInfo.isValid())
continue;
QSet<QString> importedTypes;
foreach (const QmlDirParser::Component &component, qmldirParser.components()) {
foreach (const QmlDirParser::Component &component, libraryInfo.components()) {
if (importedTypes.contains(component.typeName))
continue;
......
......@@ -36,6 +36,7 @@
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/mimedatabase.h>
#include <qmljs/qmljsinterpreter.h>
#include <qmljs/parser/qmldirparser_p.h>
#include <texteditor/itexteditor.h>
#include <QDir>
......@@ -62,9 +63,12 @@ ModelManager::ModelManager(QObject *parent):
m_synchronizer.setCancelOnWait(true);
qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");
connect(this, SIGNAL(documentUpdated(QmlJS::Document::Ptr)),
this, SLOT(onDocumentUpdated(QmlJS::Document::Ptr)));
connect(this, SIGNAL(libraryInfoUpdated(QString,QmlJS::LibraryInfo)),
this, SLOT(onLibraryInfoUpdated(QString,QmlJS::LibraryInfo)));
loadQmlTypeDescriptions();
......@@ -197,6 +201,16 @@ void ModelManager::onDocumentUpdated(Document::Ptr doc)
_snapshot.insert(doc);
}
void ModelManager::emitLibraryInfoUpdated(const QString &path, const LibraryInfo &info)
{ emit libraryInfoUpdated(path, info); }
void ModelManager::onLibraryInfoUpdated(const QString &path, const LibraryInfo &info)
{
QMutexLocker locker(&m_mutex);
_snapshot.insertLibraryInfo(path, info);
}
void ModelManager::parse(QFutureInterface<void> &future,
QMap<QString, WorkingCopy> workingCopy,
QStringList files,
......@@ -270,13 +284,33 @@ void ModelManager::parseDirectories(QFutureInterface<void> &future,
pattern << glob.pattern();
foreach (const QRegExp &glob, qmlSourceTy.globPatterns())
pattern << glob.pattern();
pattern << QLatin1String("qmldir");
QStringList importedFiles;
QStringList qmldirFiles;
foreach (const QString &path, directories) {
QDirIterator fileIterator(path, pattern, QDir::Files,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (fileIterator.hasNext())
importedFiles << fileIterator.next();
while (fileIterator.hasNext()) {
fileIterator.next();
if (fileIterator.fileName() == QLatin1String("qmldir"))
qmldirFiles << fileIterator.filePath();
else
importedFiles << fileIterator.filePath();
}
}
foreach (const QString &qmldirFilePath, qmldirFiles) {
QFile qmldirFile(qmldirFilePath);
qmldirFile.open(QFile::ReadOnly);
QString qmldirData = QString::fromUtf8(qmldirFile.readAll());
QmlDirParser qmldirParser;
qmldirParser.setSource(qmldirData);
qmldirParser.parse();
modelManager->emitLibraryInfoUpdated(QFileInfo(qmldirFilePath).path(),
LibraryInfo(qmldirParser));
}
parse(future, workingCopy, importedFiles, modelManager);
......
......@@ -58,6 +58,7 @@ public:
virtual void updateSourceDirectories(const QStringList &directories);
void emitDocumentUpdated(QmlJS::Document::Ptr doc);
void emitLibraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
virtual void setProjectImportPaths(const QStringList &importPaths);
virtual QStringList importPaths() const;
......@@ -65,10 +66,12 @@ public:
Q_SIGNALS:
void projectPathChanged(const QString &projectPath);
void aboutToRemoveFiles(const QStringList &files);
void libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
private Q_SLOTS:
// this should be executed in the GUI thread.
void onDocumentUpdated(QmlJS::Document::Ptr doc);
void onLibraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
protected:
struct WorkingCopy
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment