summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2011-05-27 14:51:30 +0200
committerhjk <qthjk@ovi.com>2011-06-08 13:29:59 +0200
commit8b95ca89572479262c9eb3dd4b2ecd88ddf6db5c (patch)
tree57245a0ea2579b8b31ec838bff6c9d1db6f5d1a2
parent7b9ef7923f9a8d33f118e703695b4e23d57c1c4c (diff)
downloadqt-creator-8b95ca89572479262c9eb3dd4b2ecd88ddf6db5c.tar.gz
QmlJS: Allow for QML modules with version subdirectories.
That means import Foo 2.1 can resolve to /path/Foo.2.1 or /path/Foo.2 or /path/Foo Task-number: QTCREATORBUG-4607 Change-Id: Ie1efc5be2ca2ed3ccc130e8a662f94aed11bec1ax Reviewed-on: http://codereview.qt.nokia.com/194 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com> (cherry picked from commit 8742026380faeb39c7084872d5c146f301253a78) Reviewed-on: http://codereview.qt.nokia.com/380 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: hjk <qthjk@ovi.com>
-rw-r--r--src/libs/languageutils/componentversion.cpp3
-rw-r--r--src/libs/languageutils/componentversion.h1
-rw-r--r--src/libs/qmljs/qmljsdocument.cpp6
-rw-r--r--src/libs/qmljs/qmljsdocument.h17
-rw-r--r--src/libs/qmljs/qmljslink.cpp32
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.cpp80
6 files changed, 105 insertions, 34 deletions
diff --git a/src/libs/languageutils/componentversion.cpp b/src/libs/languageutils/componentversion.cpp
index 7811bb438c..4368d5f94f 100644
--- a/src/libs/languageutils/componentversion.cpp
+++ b/src/libs/languageutils/componentversion.cpp
@@ -34,9 +34,12 @@
#include <QtCore/QString>
+#include <limits>
+
using namespace LanguageUtils;
const int ComponentVersion::NoVersion = -1;
+const int ComponentVersion::MaxVersion = std::numeric_limits<int>::max();
ComponentVersion::ComponentVersion()
: _major(NoVersion), _minor(NoVersion)
diff --git a/src/libs/languageutils/componentversion.h b/src/libs/languageutils/componentversion.h
index 5f8e413fb6..baa8d4e187 100644
--- a/src/libs/languageutils/componentversion.h
+++ b/src/libs/languageutils/componentversion.h
@@ -44,6 +44,7 @@ class LANGUAGEUTILS_EXPORT ComponentVersion
public:
static const int NoVersion;
+ static const int MaxVersion;
ComponentVersion();
ComponentVersion(int major, int minor);
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 467c522c74..2cfeb1d6ee 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -357,14 +357,14 @@ void Document::extractPragmas(QString *source)
}
}
-LibraryInfo::LibraryInfo()
- : _valid(false)
+LibraryInfo::LibraryInfo(Status status)
+ : _status(status)
, _dumpStatus(DumpNotStartedOrRunning)
{
}
LibraryInfo::LibraryInfo(const QmlDirParser &parser)
- : _valid(true)
+ : _status(Found)
, _components(parser.components())
, _plugins(parser.plugins())
, _dumpStatus(DumpNotStartedOrRunning)
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 2c1a516cac..b1aaadaa32 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -127,8 +127,14 @@ public:
DumpError
};
+ enum Status {
+ NotScanned,
+ NotFound,
+ Found
+ };
+
private:
- bool _valid;
+ Status _status;
QList<QmlDirParser::Component> _components;
QList<QmlDirParser::Plugin> _plugins;
typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList;
@@ -138,8 +144,8 @@ private:
QString _dumpError;
public:
- LibraryInfo();
- LibraryInfo(const QmlDirParser &parser);
+ explicit LibraryInfo(Status status = NotScanned);
+ explicit LibraryInfo(const QmlDirParser &parser);
~LibraryInfo();
QList<QmlDirParser::Component> components() const
@@ -155,7 +161,10 @@ public:
{ _metaObjects = objects; }
bool isValid() const
- { return _valid; }
+ { return _status == Found; }
+
+ bool wasScanned() const
+ { return _status != NotScanned; }
DumpStatus dumpStatus() const
{ return _dumpStatus; }
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 8f20b447d2..c9c1bb8e92 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -43,8 +43,6 @@
#include <QtCore/QDir>
#include <QtCore/QDebug>
-#include <limits>
-
using namespace LanguageUtils;
using namespace QmlJS;
using namespace QmlJS::Interpreter;
@@ -276,18 +274,37 @@ ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo
bool importFound = false;
- // check the filesystem
const QString &packagePath = importInfo.name();
+ // check the filesystem with full version
foreach (const QString &importPath, d->importPaths) {
- QString libraryPath = importPath;
- libraryPath += QDir::separator();
- libraryPath += packagePath;
+ QString libraryPath = QString("%1/%2.%3").arg(importPath, packagePath, version.toString());
if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
importFound = true;
break;
}
}
+ if (!importFound) {
+ // check the filesystem with major version
+ foreach (const QString &importPath, d->importPaths) {
+ QString libraryPath = QString("%1/%2.%3").arg(importPath, packagePath,
+ QString::number(version.majorVersion()));
+ if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
+ importFound = true;
+ break;
+ }
+ }
+ }
+ if (!importFound) {
+ // check the filesystem with no version
+ foreach (const QString &importPath, d->importPaths) {
+ QString libraryPath = QString("%1/%2").arg(importPath, packagePath);
+ if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
+ importFound = true;
+ break;
+ }
+ }
+ }
// if there are cpp-based types for this package, use them too
if (engine()->cppQmlTypes().hasPackage(packageName)) {
@@ -406,8 +423,7 @@ void Link::loadQmldirComponents(Interpreter::ObjectValue *import, ComponentVersi
// if the version isn't valid, import the latest
if (!version.isValid()) {
- const int maxVersion = std::numeric_limits<int>::max();
- version = ComponentVersion(maxVersion, maxVersion);
+ version = ComponentVersion(ComponentVersion::MaxVersion, ComponentVersion::MaxVersion);
}
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index 08f943e055..5cb426e2c2 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -285,7 +285,9 @@ void ModelManager::updateLibraryInfo(const QString &path, const LibraryInfo &inf
QMutexLocker locker(&m_mutex);
_snapshot.insertLibraryInfo(path, info);
}
- emit libraryInfoUpdated(path, info);
+ // only emit if we got new useful information
+ if (info.isValid())
+ emit libraryInfoUpdated(path, info);
}
static QStringList qmlFilesInDirectory(const QString &path)
@@ -356,15 +358,22 @@ static bool findNewQmlLibraryInPath(const QString &path,
QSet<QString> *newLibraries)
{
// if we know there is a library, done
- if (snapshot.libraryInfo(path).isValid())
+ const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
+ if (existingInfo.isValid())
return true;
if (newLibraries->contains(path))
return true;
+ // if we looked at the path before, done
+ if (existingInfo.wasScanned())
+ return false;
const QDir dir(path);
QFile qmldirFile(dir.filePath(QLatin1String("qmldir")));
- if (!qmldirFile.exists())
+ if (!qmldirFile.exists()) {
+ LibraryInfo libraryInfo(LibraryInfo::NotFound);
+ modelManager->updateLibraryInfo(path, libraryInfo);
return false;
+ }
#ifdef Q_OS_WIN
// QTCREATORBUG-3402 - be case sensitive even here?
@@ -380,8 +389,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
const QString libraryPath = QFileInfo(qmldirFile).absolutePath();
newLibraries->insert(libraryPath);
- modelManager->updateLibraryInfo(libraryPath,
- LibraryInfo(qmldirParser));
+ modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
// scan the qml files in the library
foreach (const QmlDirParser::Component &component, qmldirParser.components()) {
@@ -398,30 +406,62 @@ static bool findNewQmlLibraryInPath(const QString &path,
return true;
}
+static void findNewQmlLibrary(
+ const QString &path,
+ const LanguageUtils::ComponentVersion &version,
+ const Snapshot &snapshot,
+ ModelManager *modelManager,
+ QStringList *importedFiles,
+ QSet<QString> *scannedPaths,
+ QSet<QString> *newLibraries)
+{
+ QString libraryPath = QString("%1.%2.%3").arg(
+ path,
+ QString::number(version.majorVersion()),
+ QString::number(version.minorVersion()));
+ findNewQmlLibraryInPath(
+ libraryPath, snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
+
+ libraryPath = QString("%1.%2").arg(
+ path,
+ QString::number(version.majorVersion()));
+ findNewQmlLibraryInPath(
+ libraryPath, snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
+
+ findNewQmlLibraryInPath(
+ path, snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
+}
+
static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snapshot,
ModelManager *modelManager,
QStringList *importedFiles, QSet<QString> *scannedPaths, QSet<QString> *newLibraries)
{
- // scan library imports
+ // scan current dir
+ findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
+
+ // scan dir and lib imports
const QStringList importPaths = modelManager->importPaths();
foreach (const Interpreter::ImportInfo &import, doc->bind()->imports()) {
+ if (import.type() == Interpreter::ImportInfo::DirectoryImport) {
+ const QString targetPath = import.name();
+ findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
+ }
+
if (import.type() == Interpreter::ImportInfo::LibraryImport) {
+ if (!import.version().isValid())
+ continue;
foreach (const QString &importPath, importPaths) {
const QString targetPath = QDir(importPath).filePath(import.name());
-
- if (findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
- importedFiles, scannedPaths, newLibraries))
- break;
+ findNewQmlLibrary(targetPath, import.version(), snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries);
}
- } else if (import.type() == Interpreter::ImportInfo::DirectoryImport) {
- const QString targetPath = import.name();
- findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
- importedFiles, scannedPaths, newLibraries);
}
}
-
- findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
- importedFiles, scannedPaths, newLibraries);
}
static bool suffixMatches(const QString &fileName, const Core::MimeType &mimeType)
@@ -451,8 +491,6 @@ void ModelManager::parse(QFutureInterface<void> &future,
int progressRange = files.size();
future.setProgressRange(0, progressRange);
- Snapshot snapshot = modelManager->_snapshot;
-
// paths we have scanned for files and added to the files list
QSet<QString> scannedPaths;
// libraries we've found while scanning imports
@@ -499,6 +537,10 @@ void ModelManager::parse(QFutureInterface<void> &future,
doc->setSource(contents);
doc->parse();
+ // update snapshot. requires synchronization, but significantly reduces amount of file
+ // system queries for library imports because queries are cached in libraryInfo
+ const Snapshot snapshot = modelManager->snapshot();
+
// get list of referenced files not yet in snapshot or in directories already scanned
QStringList importedFiles;
findNewImplicitImports(doc, snapshot, &importedFiles, &scannedPaths);