forked from qt-creator/qt-creator
QmlJS: Fix semantic and non-semantic QML error reporting.
The QML snapshot only ever contains valid Documents; to compile a list of parser problems we need to get at the invalid documents. To do that, the model manager now provides a Snapshot with up to date, but potentially invalid documents. That should also be useful for other things. Change-Id: I67892f63771c221bf2fe2c2bf0240a0f4e523227 Reviewed-on: http://codereview.qt.nokia.com/3012 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
This commit is contained in:
@@ -389,9 +389,9 @@ Snapshot::~Snapshot()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Snapshot::insert(const Document::Ptr &document)
|
void Snapshot::insert(const Document::Ptr &document, bool allowInvalid)
|
||||||
{
|
{
|
||||||
if (document && (document->qmlProgram() || document->jsProgram())) {
|
if (document && (allowInvalid || document->qmlProgram() || document->jsProgram())) {
|
||||||
const QString fileName = document->fileName();
|
const QString fileName = document->fileName();
|
||||||
const QString path = document->path();
|
const QString path = document->path();
|
||||||
|
|
||||||
|
@@ -198,7 +198,7 @@ public:
|
|||||||
const_iterator begin() const { return _documents.begin(); }
|
const_iterator begin() const { return _documents.begin(); }
|
||||||
const_iterator end() const { return _documents.end(); }
|
const_iterator end() const { return _documents.end(); }
|
||||||
|
|
||||||
void insert(const Document::Ptr &document);
|
void insert(const Document::Ptr &document, bool allowInvalid = false);
|
||||||
void insertLibraryInfo(const QString &path, const LibraryInfo &info);
|
void insertLibraryInfo(const QString &path, const LibraryInfo &info);
|
||||||
void remove(const QString &fileName);
|
void remove(const QString &fileName);
|
||||||
|
|
||||||
|
@@ -119,7 +119,7 @@ public:
|
|||||||
static ModelManagerInterface *instance();
|
static ModelManagerInterface *instance();
|
||||||
|
|
||||||
virtual WorkingCopy workingCopy() const = 0;
|
virtual WorkingCopy workingCopy() const = 0;
|
||||||
virtual QmlJS::Snapshot snapshot() const = 0;
|
virtual QmlJS::Snapshot snapshot(bool preferValid = true) const = 0;
|
||||||
|
|
||||||
virtual void updateSourceFiles(const QStringList &files,
|
virtual void updateSourceFiles(const QStringList &files,
|
||||||
bool emitDocumentOnDiskChanged) = 0;
|
bool emitDocumentOnDiskChanged) = 0;
|
||||||
|
@@ -119,6 +119,7 @@ void QmlTaskManager::collectMessages(
|
|||||||
fileName, Constants::TASK_CATEGORY_QML_ANALYSIS);
|
fileName, Constants::TASK_CATEGORY_QML_ANALYSIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.tasks.isEmpty())
|
||||||
future.reportResult(result);
|
future.reportResult(result);
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
@@ -145,16 +146,15 @@ void QmlTaskManager::updateMessagesNow(bool updateSemantic)
|
|||||||
|
|
||||||
// abort any update that's going on already
|
// abort any update that's going on already
|
||||||
m_messageCollector.cancel();
|
m_messageCollector.cancel();
|
||||||
removeAllTasks();
|
removeAllTasks(updateSemantic);
|
||||||
|
|
||||||
// collect all the source files in open projects
|
|
||||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||||
|
|
||||||
// process them
|
// process them
|
||||||
QFuture<FileErrorMessages> future =
|
QFuture<FileErrorMessages> future =
|
||||||
QtConcurrent::run<FileErrorMessages>(
|
QtConcurrent::run<FileErrorMessages>(
|
||||||
&collectMessages, modelManager->snapshot(), modelManager->projectInfos(),
|
&collectMessages, modelManager->snapshot(false), modelManager->projectInfos(),
|
||||||
modelManager->importPaths(), !updateSemantic);
|
modelManager->importPaths(), updateSemantic);
|
||||||
m_messageCollector.setFuture(future);
|
m_messageCollector.setFuture(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,14 +198,11 @@ void QmlTaskManager::removeTasksForFile(const QString &fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlTaskManager::removeAllTasks()
|
void QmlTaskManager::removeAllTasks(bool clearSemantic)
|
||||||
{
|
{
|
||||||
QMapIterator<QString, QList<ProjectExplorer::Task> > it(m_docsWithTasks);
|
m_taskHub->clearTasks(Constants::TASK_CATEGORY_QML);
|
||||||
while (it.hasNext()) {
|
if (clearSemantic)
|
||||||
it.next();
|
m_taskHub->clearTasks(Constants::TASK_CATEGORY_QML_ANALYSIS);
|
||||||
foreach (const ProjectExplorer::Task &task, it.value())
|
|
||||||
m_taskHub->removeTask(task);
|
|
||||||
}
|
|
||||||
m_docsWithTasks.clear();
|
m_docsWithTasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,7 +76,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void insertTask(const ProjectExplorer::Task &task);
|
void insertTask(const ProjectExplorer::Task &task);
|
||||||
void removeTasksForFile(const QString &fileName);
|
void removeTasksForFile(const QString &fileName);
|
||||||
void removeAllTasks();
|
void removeAllTasks(bool clearSemantic);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class FileErrorMessages
|
class FileErrorMessages
|
||||||
|
@@ -169,11 +169,14 @@ ModelManagerInterface::WorkingCopy ModelManager::workingCopy() const
|
|||||||
return workingCopy;
|
return workingCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
Snapshot ModelManager::snapshot() const
|
Snapshot ModelManager::snapshot(bool preferValid) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
return _snapshot;
|
if (preferValid)
|
||||||
|
return _validSnapshot;
|
||||||
|
else
|
||||||
|
return _newestSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManager::updateSourceFiles(const QStringList &files,
|
void ModelManager::updateSourceFiles(const QStringList &files,
|
||||||
@@ -228,8 +231,10 @@ void ModelManager::removeFiles(const QStringList &files)
|
|||||||
|
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
foreach (const QString &file, files)
|
foreach (const QString &file, files) {
|
||||||
_snapshot.remove(file);
|
_validSnapshot.remove(file);
|
||||||
|
_newestSnapshot.remove(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ModelManager::ProjectInfo> ModelManager::projectInfos() const
|
QList<ModelManager::ProjectInfo> ModelManager::projectInfos() const
|
||||||
@@ -257,7 +262,7 @@ void ModelManager::updateProjectInfo(const ProjectInfo &pinfo)
|
|||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
oldInfo = m_projects.value(pinfo.project);
|
oldInfo = m_projects.value(pinfo.project);
|
||||||
m_projects.insert(pinfo.project, pinfo);
|
m_projects.insert(pinfo.project, pinfo);
|
||||||
snapshot = _snapshot;
|
snapshot = _validSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldInfo.qmlDumpPath != pinfo.qmlDumpPath
|
if (oldInfo.qmlDumpPath != pinfo.qmlDumpPath
|
||||||
@@ -302,7 +307,8 @@ void ModelManager::updateDocument(Document::Ptr doc)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
_snapshot.insert(doc);
|
_validSnapshot.insert(doc);
|
||||||
|
_newestSnapshot.insert(doc, true);
|
||||||
}
|
}
|
||||||
emit documentUpdated(doc);
|
emit documentUpdated(doc);
|
||||||
}
|
}
|
||||||
@@ -311,7 +317,8 @@ void ModelManager::updateLibraryInfo(const QString &path, const LibraryInfo &inf
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
_snapshot.insertLibraryInfo(path, info);
|
_validSnapshot.insertLibraryInfo(path, info);
|
||||||
|
_newestSnapshot.insertLibraryInfo(path, info);
|
||||||
}
|
}
|
||||||
// only emit if we got new useful information
|
// only emit if we got new useful information
|
||||||
if (info.isValid())
|
if (info.isValid())
|
||||||
@@ -650,7 +657,7 @@ void ModelManager::updateImportPaths()
|
|||||||
m_allImportPaths.removeDuplicates();
|
m_allImportPaths.removeDuplicates();
|
||||||
|
|
||||||
// check if any file in the snapshot imports something new in the new paths
|
// check if any file in the snapshot imports something new in the new paths
|
||||||
Snapshot snapshot = _snapshot;
|
Snapshot snapshot = _validSnapshot;
|
||||||
QStringList importedFiles;
|
QStringList importedFiles;
|
||||||
QSet<QString> scannedPaths;
|
QSet<QString> scannedPaths;
|
||||||
QSet<QString> newLibraries;
|
QSet<QString> newLibraries;
|
||||||
@@ -724,7 +731,7 @@ LibraryInfo ModelManager::builtins(const Document::Ptr &doc) const
|
|||||||
if (!info.isValid())
|
if (!info.isValid())
|
||||||
return LibraryInfo();
|
return LibraryInfo();
|
||||||
|
|
||||||
return _snapshot.libraryInfo(info.qtImportsPath);
|
return _validSnapshot.libraryInfo(info.qtImportsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManager::joinAllThreads()
|
void ModelManager::joinAllThreads()
|
||||||
@@ -741,11 +748,12 @@ void ModelManager::resetCodeModel()
|
|||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
// find all documents currently in the code model
|
// find all documents currently in the code model
|
||||||
foreach (Document::Ptr doc, _snapshot)
|
foreach (Document::Ptr doc, _validSnapshot)
|
||||||
documents.append(doc->fileName());
|
documents.append(doc->fileName());
|
||||||
|
|
||||||
// reset the snapshot
|
// reset the snapshot
|
||||||
_snapshot = Snapshot();
|
_validSnapshot = Snapshot();
|
||||||
|
_newestSnapshot = Snapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a reparse thread
|
// start a reparse thread
|
||||||
|
@@ -69,7 +69,7 @@ public:
|
|||||||
void delayedInitialization();
|
void delayedInitialization();
|
||||||
|
|
||||||
virtual WorkingCopy workingCopy() const;
|
virtual WorkingCopy workingCopy() const;
|
||||||
virtual QmlJS::Snapshot snapshot() const;
|
virtual QmlJS::Snapshot snapshot(bool preferValid = true) const;
|
||||||
|
|
||||||
virtual void updateSourceFiles(const QStringList &files,
|
virtual void updateSourceFiles(const QStringList &files,
|
||||||
bool emitDocumentOnDiskChanged);
|
bool emitDocumentOnDiskChanged);
|
||||||
@@ -126,7 +126,8 @@ private:
|
|||||||
|
|
||||||
mutable QMutex m_mutex;
|
mutable QMutex m_mutex;
|
||||||
Core::ICore *m_core;
|
Core::ICore *m_core;
|
||||||
QmlJS::Snapshot _snapshot;
|
QmlJS::Snapshot _validSnapshot;
|
||||||
|
QmlJS::Snapshot _newestSnapshot;
|
||||||
QStringList m_allImportPaths;
|
QStringList m_allImportPaths;
|
||||||
QStringList m_defaultImportPaths;
|
QStringList m_defaultImportPaths;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user