diff --git a/src/libs/qmljs/parser/cmd.sed b/src/libs/qmljs/parser/cmd.sed index fa2ef28f2f5..740da4e3d1a 100644 --- a/src/libs/qmljs/parser/cmd.sed +++ b/src/libs/qmljs/parser/cmd.sed @@ -1,3 +1,11 @@ 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/ diff --git a/src/libs/qmljs/parser/gen-parser.sh b/src/libs/qmljs/parser/gen-parser.sh index 1925432977a..5b999e27f15 100755 --- a/src/libs/qmljs/parser/gen-parser.sh +++ b/src/libs/qmljs/parser/gen-parser.sh @@ -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 diff --git a/src/libs/qmljs/parser/qmldirparser_p.h b/src/libs/qmljs/parser/qmldirparser_p.h index c58c03fb8c0..8ab6095c382 100644 --- a/src/libs/qmljs/parser/qmldirparser_p.h +++ b/src/libs/qmljs/parser/qmldirparser_p.h @@ -56,11 +56,13 @@ #include #include +#include "qmljsglobal_p.h" + QT_BEGIN_NAMESPACE class QmlError; -class QmlDirParser +class QML_PARSER_EXPORT QmlDirParser { Q_DISABLE_COPY(QmlDirParser) diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index 68693c4772d..6b4f3ed96ba 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -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 { diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h index 126f364e620..fd3742e8b86 100644 --- a/src/libs/qmljs/qmljsdocument.h +++ b/src/libs/qmljs/qmljsdocument.h @@ -35,6 +35,7 @@ #include #include +#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 _components; + QList _plugins; + +public: + LibraryInfo(); + LibraryInfo(const QmlDirParser &parser); + ~LibraryInfo(); + + QList components() const + { return _components; } + + QList plugins() const + { return _plugins; } + + bool isValid() const + { return _valid; } +}; + class QMLJS_EXPORT Snapshot { typedef QMap _Base; QMap _documents; + QMap _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; diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index f8b184b9c5c..24d417baa87 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -1,7 +1,6 @@ #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")) + + const LibraryInfo libraryInfo = _snapshot.libraryInfo(dir.path()); + if (!libraryInfo.isValid()) continue; - QFile qmldirFile(dir.filePath("qmldir")); - qmldirFile.open(QFile::ReadOnly); - QString qmldirData = QString::fromUtf8(qmldirFile.readAll()); - QmlDirParser qmldirParser; - qmldirParser.setSource(qmldirData); - qmldirParser.parse(); - QSet importedTypes; - foreach (const QmlDirParser::Component &component, qmldirParser.components()) { + foreach (const QmlDirParser::Component &component, libraryInfo.components()) { if (importedTypes.contains(component.typeName)) continue; diff --git a/src/plugins/qmljseditor/qmljsmodelmanager.cpp b/src/plugins/qmljseditor/qmljsmodelmanager.cpp index e765b5fa377..52a781efdd8 100644 --- a/src/plugins/qmljseditor/qmljsmodelmanager.cpp +++ b/src/plugins/qmljseditor/qmljsmodelmanager.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -62,9 +63,12 @@ ModelManager::ModelManager(QObject *parent): m_synchronizer.setCancelOnWait(true); qRegisterMetaType("QmlJS::Document::Ptr"); + qRegisterMetaType("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 &future, QMap workingCopy, QStringList files, @@ -270,13 +284,33 @@ void ModelManager::parseDirectories(QFutureInterface &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); diff --git a/src/plugins/qmljseditor/qmljsmodelmanager.h b/src/plugins/qmljseditor/qmljsmodelmanager.h index aafdc2a89f5..8ca17240196 100644 --- a/src/plugins/qmljseditor/qmljsmodelmanager.h +++ b/src/plugins/qmljseditor/qmljsmodelmanager.h @@ -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