Commit 16b4e4e9 authored by Christian Kamm's avatar Christian Kamm
Browse files

QmlJS: Fix import path handling in the model manager.

Previously, the model manager always had exactly one import path - but
you can open more than one Qml project at once. Now, we store the union
of all import paths in the model manager.

Reviewed-by: Roberto Raggi
parent eba91574
......@@ -36,6 +36,11 @@
#include <QObject>
#include <QStringList>
#include <QSharedPointer>
#include <QPointer>
namespace ProjectExplorer {
class Project;
}
namespace QmlJS {
......@@ -45,6 +50,32 @@ class QMLJS_EXPORT ModelManagerInterface: public QObject
{
Q_OBJECT
public:
class ProjectInfo
{
public:
ProjectInfo()
{ }
ProjectInfo(QPointer<ProjectExplorer::Project> project)
: project(project)
{ }
operator bool() const
{ return ! project.isNull(); }
bool isValid() const
{ return ! project.isNull(); }
bool isNull() const
{ return project.isNull(); }
public: // attributes
QPointer<ProjectExplorer::Project> project;
QStringList sourceFiles;
QStringList importPaths;
};
public:
ModelManagerInterface(QObject *parent = 0);
virtual ~ModelManagerInterface();
......@@ -55,7 +86,10 @@ public:
virtual void fileChangedOnDisk(const QString &path) = 0;
virtual void removeFiles(const QStringList &files) = 0;
virtual void setProjectImportPaths(const QStringList &importPaths) = 0;
virtual QList<ProjectInfo> projectInfos() const = 0;
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;
virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0;
virtual QStringList importPaths() const = 0;
signals:
......
......@@ -39,6 +39,7 @@
#include <qmljs/qmljsbind.h>
#include <qmljs/parser/qmldirparser_p.h>
#include <texteditor/itexteditor.h>
#include <projectexplorer/project.h>
#include <QDir>
#include <QFile>
......@@ -180,6 +181,33 @@ void ModelManager::removeFiles(const QStringList &files)
_snapshot.remove(file);
}
QList<ModelManager::ProjectInfo> ModelManager::projectInfos() const
{
QMutexLocker locker(&m_mutex);
return m_projects.values();
}
ModelManager::ProjectInfo ModelManager::projectInfo(ProjectExplorer::Project *project) const
{
QMutexLocker locker(&m_mutex);
return m_projects.value(project, ProjectInfo(project));
}
void ModelManager::updateProjectInfo(const ProjectInfo &pinfo)
{
if (! pinfo.isValid())
return;
{
QMutexLocker locker(&m_mutex);
m_projects.insert(pinfo.project, pinfo);
}
updateImportPaths();
}
void ModelManager::emitDocumentChangedOnDisk(Document::Ptr doc)
{ emit documentChangedOnDisk(doc); }
......@@ -400,26 +428,9 @@ bool ModelManager::matchesMimeType(const Core::MimeType &fileMimeType, const Cor
return false;
}
void ModelManager::setProjectImportPaths(const QStringList &importPaths)
{
m_projectImportPaths = importPaths;
// check if any file in the snapshot imports something new in the new paths
Snapshot snapshot = _snapshot;
QStringList importedFiles;
QSet<QString> scannedPaths;
foreach (const Document::Ptr &doc, snapshot)
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths);
updateSourceFiles(importedFiles, true);
}
QStringList ModelManager::importPaths() const
{
QStringList paths;
paths << m_projectImportPaths;
paths << m_defaultImportPaths;
return paths;
return m_allImportPaths;
}
static QStringList environmentImportPaths()
......@@ -471,6 +482,25 @@ void ModelManager::loadQmlPluginTypes(const QString &pluginPath)
m_runningQmldumps.insert(process, pluginPath);
}
void ModelManager::updateImportPaths()
{
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
while (it.hasNext()) {
it.next();
m_allImportPaths += it.value().importPaths;
}
m_allImportPaths += m_defaultImportPaths;
// check if any file in the snapshot imports something new in the new paths
Snapshot snapshot = _snapshot;
QStringList importedFiles;
QSet<QString> scannedPaths;
foreach (const Document::Ptr &doc, snapshot)
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths);
updateSourceFiles(importedFiles, true);
}
void ModelManager::qmlPluginTypeDumpDone(int exitCode)
{
QProcess *process = qobject_cast<QProcess *>(sender());
......
......@@ -59,11 +59,14 @@ public:
virtual void fileChangedOnDisk(const QString &path);
virtual void removeFiles(const QStringList &files);
virtual QList<ProjectInfo> projectInfos() const;
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
virtual void updateProjectInfo(const ProjectInfo &pinfo);
void emitDocumentUpdated(QmlJS::Document::Ptr doc);
void emitLibraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc);
virtual void setProjectImportPaths(const QStringList &importPaths);
virtual QStringList importPaths() const;
Q_SIGNALS:
......@@ -97,17 +100,22 @@ protected:
void loadQmlTypeDescriptions();
void loadQmlPluginTypes(const QString &pluginPath);
void updateImportPaths();
private:
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
mutable QMutex m_mutex;
Core::ICore *m_core;
QmlJS::Snapshot _snapshot;
QStringList m_projectImportPaths;
QStringList m_allImportPaths;
QStringList m_defaultImportPaths;
QHash<QProcess *, QString> m_runningQmldumps;
QFutureSynchronizer<void> m_synchronizer;
// project integration
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
};
} // namespace Internal
......
......@@ -96,8 +96,6 @@ void QmlProject::parseProject(RefreshOptions options)
m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
connect(m_projectItem.data(), SIGNAL(qmlFilesChanged(QSet<QString>, QSet<QString>)),
this, SLOT(refreshFiles(QSet<QString>, QSet<QString>)));
connect(m_projectItem.data(), SIGNAL(importPathsChanged()), this, SLOT(refreshImportPaths()));
refreshImportPaths();
} else {
Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
messageManager->printToOutputPane(tr("Error while loading project file!"));
......@@ -126,6 +124,11 @@ void QmlProject::refresh(RefreshOptions options)
if (options & Files)
m_rootNode->refresh();
QmlJS::ModelManagerInterface::ProjectInfo pinfo(this);
pinfo.sourceFiles = files();
pinfo.importPaths = importPaths();
m_modelManager->updateProjectInfo(pinfo);
}
QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
......@@ -186,11 +189,6 @@ void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString
m_modelManager->removeFiles(removed.toList());
}
void QmlProject::refreshImportPaths()
{
m_modelManager->setProjectImportPaths(importPaths());
}
QString QmlProject::displayName() const
{
return m_projectName;
......
......@@ -104,7 +104,6 @@ public:
private slots:
void refreshProjectFile();
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
void refreshImportPaths();
protected:
bool fromMap(const QVariantMap &map);
......
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