QmlJS: Add semantic errors to task window.

Task-number: QTCREATORBUG-4103
Reviewed-by: Leandro Melo
This commit is contained in:
Christian Kamm
2011-04-21 11:09:29 +02:00
parent e21311132b
commit c504d28eb5
11 changed files with 203 additions and 51 deletions

View File

@@ -33,11 +33,21 @@
#include "qmltaskmanager.h"
#include "qmljseditorconstants.h"
#include <coreplugin/ifile.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/taskhub.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/qmljsinterpreter.h>
#include <qmljs/qmljslink.h>
#include <qmljs/qmljscheck.h>
#include <qmljseditor/qmljseditor.h>
#include <qmljseditor/qmljseditoreditable.h>
#include <QtCore/QDebug>
#include <QtCore/QtConcurrentRun>
#include <qtconcurrent/runextensions.h>
using namespace QmlJS;
namespace QmlJSEditor {
namespace Internal {
@@ -47,35 +57,103 @@ QmlTaskManager::QmlTaskManager(QObject *parent) :
m_taskHub(0)
{
m_taskHub = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::TaskHub>();
// displaying results incrementally leads to flickering
// connect(&m_messageCollector, SIGNAL(resultsReadyAt(int,int)),
// SLOT(displayResults(int,int)));
connect(&m_messageCollector, SIGNAL(finished()),
SLOT(displayAllResults()));
m_updateDelay.setInterval(100);
m_updateDelay.setSingleShot(true);
connect(&m_updateDelay, SIGNAL(timeout()),
SLOT(updateMessagesNow()));
}
void QmlTaskManager::documentChangedOnDisk(QmlJS::Document::Ptr doc)
void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future,
Snapshot snapshot, QStringList files, QStringList importPaths)
{
const QString fileName = doc->fileName();
removeTasksForFile(fileName);
Interpreter::Context ctx;
QHash<QString, QList<DiagnosticMessage> > linkMessages;
Link link(&ctx, snapshot, importPaths, &linkMessages);
foreach (const QmlJS::DiagnosticMessage &msg, doc->diagnosticMessages()) {
ProjectExplorer::Task::TaskType type
= msg.isError() ? ProjectExplorer::Task::Error
: ProjectExplorer::Task::Warning;
foreach (const QString &fileName, files) {
Document::Ptr document = snapshot.document(fileName);
if (!document)
continue;
ProjectExplorer::Task task(type, msg.message, fileName, msg.loc.startLine,
Constants::TASK_CATEGORY_QML);
insertTask(fileName, task);
FileErrorMessages result;
result.fileName = fileName;
result.messages = document->diagnosticMessages();
result.messages += linkMessages.value(fileName);
Check checker(document, snapshot, &ctx);
result.messages.append(checker());
future.reportResult(result);
if (future.isCanceled())
break;
}
}
void QmlTaskManager::updateMessages()
{
m_updateDelay.start();
}
void QmlTaskManager::updateMessagesNow()
{
// abort any update that's going on already
m_messageCollector.cancel();
removeAllTasks();
// collect all the source files in open projects
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
QStringList sourceFiles;
foreach (const ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) {
sourceFiles += info.sourceFiles;
}
// process them
QFuture<FileErrorMessages> future =
QtConcurrent::run<FileErrorMessages>(
&collectMessages, modelManager->snapshot(), sourceFiles,
modelManager->importPaths());
m_messageCollector.setFuture(future);
}
void QmlTaskManager::documentsRemoved(const QStringList path)
{
foreach (const QString &item, path)
removeTasksForFile(item);
}
void QmlTaskManager::insertTask(const QString &fileName, const ProjectExplorer::Task &task)
void QmlTaskManager::displayResults(int begin, int end)
{
QList<ProjectExplorer::Task> tasks = m_docsWithTasks.value(fileName);
for (int i = begin; i < end; ++i) {
FileErrorMessages result = m_messageCollector.resultAt(i);
foreach (const DiagnosticMessage &msg, result.messages) {
ProjectExplorer::Task::TaskType type
= msg.isError() ? ProjectExplorer::Task::Error
: ProjectExplorer::Task::Warning;
ProjectExplorer::Task task(type, msg.message, result.fileName, msg.loc.startLine,
Constants::TASK_CATEGORY_QML);
insertTask(task);
}
}
}
void QmlTaskManager::displayAllResults()
{
displayResults(0, m_messageCollector.future().resultCount());
}
void QmlTaskManager::insertTask(const ProjectExplorer::Task &task)
{
QList<ProjectExplorer::Task> tasks = m_docsWithTasks.value(task.file);
tasks.append(task);
m_docsWithTasks.insert(fileName, tasks);
m_docsWithTasks.insert(task.file, tasks);
m_taskHub->addTask(task);
}
@@ -89,5 +167,16 @@ void QmlTaskManager::removeTasksForFile(const QString &fileName)
}
}
void QmlTaskManager::removeAllTasks()
{
QMapIterator<QString, QList<ProjectExplorer::Task> > it(m_docsWithTasks);
while (it.hasNext()) {
it.next();
foreach (const ProjectExplorer::Task &task, it.value())
m_taskHub->removeTask(task);
}
m_docsWithTasks.clear();
}
} // Internal
} // QmlProjectManager