forked from qt-creator/qt-creator
QmlJS editor: Simplify document/semInfo updating significantly.
* Instead of having SemanticInfoUpdater reparse documents itself, it now relies on the ModelManager doing that. * SemanticInfoUpdater now takes a doc and snapshot to generate the convenience Context / ScopeChain. Could be converted into a future to avoid having a (99% idle) thread per editor. * Renamed several functions in QmlJSTextEditorWidget to better indicate their behavior. Change-Id: I8af6ccab099130fa7fa227e44864561ca2c3f9e0 Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
This commit is contained in:
committed by
Leandro Melo
parent
fa6c3cc1ec
commit
56bf0e3023
@@ -43,9 +43,8 @@ namespace QmlJSEditor {
|
||||
namespace Internal {
|
||||
|
||||
SemanticInfoUpdater::SemanticInfoUpdater(QObject *parent)
|
||||
: QThread(parent),
|
||||
m_done(false),
|
||||
m_modelManager(0)
|
||||
: QThread(parent)
|
||||
, m_wasCancelled(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -56,7 +55,7 @@ SemanticInfoUpdater::~SemanticInfoUpdater()
|
||||
void SemanticInfoUpdater::abort()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_done = true;
|
||||
m_wasCancelled = true;
|
||||
m_condition.wakeOne();
|
||||
}
|
||||
|
||||
@@ -67,13 +66,6 @@ void SemanticInfoUpdater::update(const SemanticInfoUpdaterSource &source)
|
||||
m_condition.wakeOne();
|
||||
}
|
||||
|
||||
bool SemanticInfoUpdater::isOutdated()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const bool outdated = ! m_source.fileName.isEmpty() || m_done;
|
||||
return outdated;
|
||||
}
|
||||
|
||||
void SemanticInfoUpdater::run()
|
||||
{
|
||||
setPriority(QThread::LowestPriority);
|
||||
@@ -81,10 +73,10 @@ void SemanticInfoUpdater::run()
|
||||
forever {
|
||||
m_mutex.lock();
|
||||
|
||||
while (! (m_done || ! m_source.fileName.isEmpty()))
|
||||
while (! (m_wasCancelled || m_source.isValid()))
|
||||
m_condition.wait(&m_mutex);
|
||||
|
||||
const bool done = m_done;
|
||||
const bool done = m_wasCancelled;
|
||||
const SemanticInfoUpdaterSource source = m_source;
|
||||
m_source.clear();
|
||||
|
||||
@@ -93,73 +85,42 @@ void SemanticInfoUpdater::run()
|
||||
if (done)
|
||||
break;
|
||||
|
||||
const SemanticInfo info = semanticInfo(source);
|
||||
const SemanticInfo info = makeNewSemanticInfo(source);
|
||||
|
||||
if (! isOutdated()) {
|
||||
m_mutex.lock();
|
||||
m_mutex.lock();
|
||||
const bool cancelledOrNewData = m_wasCancelled || m_source.isValid();
|
||||
m_mutex.unlock();
|
||||
|
||||
if (! cancelledOrNewData) {
|
||||
m_lastSemanticInfo = info;
|
||||
m_mutex.unlock();
|
||||
|
||||
emit updated(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SemanticInfo SemanticInfoUpdater::semanticInfo(const SemanticInfoUpdaterSource &source)
|
||||
SemanticInfo SemanticInfoUpdater::makeNewSemanticInfo(const SemanticInfoUpdaterSource &source)
|
||||
{
|
||||
m_mutex.lock();
|
||||
const int revision = m_lastSemanticInfo.revision();
|
||||
m_mutex.unlock();
|
||||
|
||||
QmlJS::Snapshot snapshot;
|
||||
QmlJS::Document::Ptr doc;
|
||||
|
||||
if (! source.force && revision == source.revision) {
|
||||
m_mutex.lock();
|
||||
snapshot = m_lastSemanticInfo.snapshot;
|
||||
doc = m_lastSemanticInfo.document;
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
if (! doc) {
|
||||
snapshot = source.snapshot;
|
||||
QmlJS::Document::Language language;
|
||||
if (m_lastSemanticInfo.document)
|
||||
language = m_lastSemanticInfo.document->language();
|
||||
else
|
||||
language = QmlJSTools::languageOfFile(source.fileName);
|
||||
QmlJS::Document::MutablePtr newDoc = snapshot.documentFromSource(
|
||||
source.code, source.fileName, language);
|
||||
newDoc->setEditorRevision(source.revision);
|
||||
newDoc->parse();
|
||||
snapshot.insert(newDoc);
|
||||
doc = newDoc;
|
||||
}
|
||||
using namespace QmlJS;
|
||||
|
||||
SemanticInfo semanticInfo;
|
||||
semanticInfo.snapshot = snapshot;
|
||||
semanticInfo.document = doc;
|
||||
const Document::Ptr &doc = semanticInfo.document = source.document;
|
||||
semanticInfo.snapshot = source.snapshot;
|
||||
|
||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||
|
||||
QmlJS::Link link(snapshot, modelManager->importPaths(), modelManager->builtins(doc));
|
||||
Link link(semanticInfo.snapshot, modelManager->importPaths(), modelManager->builtins(doc));
|
||||
semanticInfo.context = link(doc, &semanticInfo.semanticMessages);
|
||||
|
||||
QmlJS::ScopeChain *scopeChain = new QmlJS::ScopeChain(doc, semanticInfo.context);
|
||||
semanticInfo.m_rootScopeChain = QSharedPointer<const QmlJS::ScopeChain>(scopeChain);
|
||||
ScopeChain *scopeChain = new ScopeChain(doc, semanticInfo.context);
|
||||
semanticInfo.m_rootScopeChain = QSharedPointer<const ScopeChain>(scopeChain);
|
||||
|
||||
if (doc->language() != QmlJS::Document::JsonLanguage) {
|
||||
QmlJS::Check checker(doc, semanticInfo.context);
|
||||
if (doc->language() != Document::JsonLanguage) {
|
||||
Check checker(doc, semanticInfo.context);
|
||||
semanticInfo.staticAnalysisMessages = checker();
|
||||
}
|
||||
|
||||
return semanticInfo;
|
||||
}
|
||||
|
||||
void SemanticInfoUpdater::setModelManager(QmlJS::ModelManagerInterface *modelManager)
|
||||
{
|
||||
m_modelManager = modelManager;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlJSEditor
|
||||
|
||||
Reference in New Issue
Block a user