From 65c11b6446ab78d6c6d1aa6c009f5c03e858fca3 Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Thu, 15 Mar 2018 09:57:55 +0100 Subject: [PATCH] qmldesigner: avoid reloading document when not needed Creating a new ReadingContext is an expensive operation as it creates and call a Link object. This operation is needed only when the document is actually changed, in all the other cases it is not needed. Change-Id: Ia368122d60d2c7de86d10e169dd7f20a19f01115 Reviewed-by: Thomas Hartmann --- .../designercore/metainfo/nodemetainfo.cpp | 24 ++++++++------- .../designercore/model/texttomodelmerger.cpp | 30 +++++++++++++------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 46801cf0e0d..94c192b34fd 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -739,16 +739,20 @@ const CppComponentValue *NodeMetaInfoPrivate::getCppComponentValue() const } // get the qml object value that's available in the document - foreach (const QmlJS::Import &import, context()->imports(document())->all()) { - if (import.info.path() != QString::fromUtf8(module)) - continue; - const Value *lookupResult = import.object->lookupMember(QString::fromUtf8(type), context()); - const CppComponentValue *cppValue = value_cast(lookupResult); - if (cppValue - && (m_majorVersion == -1 || m_majorVersion == cppValue->componentVersion().majorVersion()) - && (m_minorVersion == -1 || m_minorVersion == cppValue->componentVersion().minorVersion()) - ) - return cppValue; + const QmlJS::Imports *importsPtr = context()->imports(document()); + if (importsPtr) { + const QList imports = importsPtr->all(); + foreach (const QmlJS::Import &import, imports) { + if (import.info.path() != QString::fromUtf8(module)) + continue; + const Value *lookupResult = import.object->lookupMember(QString::fromUtf8(type), context()); + const CppComponentValue *cppValue = value_cast(lookupResult); + if (cppValue + && (m_majorVersion == -1 || m_majorVersion == cppValue->componentVersion().majorVersion()) + && (m_minorVersion == -1 || m_minorVersion == cppValue->componentVersion().minorVersion()) + ) + return cppValue; + } } const CppComponentValue *value = value_cast(getObjectValue()); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 56023ee2bf5..cb2032046e1 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -59,6 +59,8 @@ #include #include +#include + using namespace LanguageUtils; using namespace QmlJS; @@ -357,11 +359,10 @@ class ReadingContext public: ReadingContext(const Snapshot &snapshot, const Document::Ptr &doc, const ViewerContext &vContext) - : m_snapshot(snapshot) - , m_doc(doc) - , m_link(snapshot, vContext, - ModelManagerInterface::instance()->builtins(doc)) - , m_context(m_link(doc, &m_diagnosticLinkMessages)) + : m_doc(doc) + , m_context( + Link(snapshot, vContext, ModelManagerInterface::instance()->builtins(doc)) + (doc, &m_diagnosticLinkMessages)) , m_scopeChain(doc, m_context) , m_scopeBuilder(&m_scopeChain) { @@ -675,9 +676,7 @@ public: { return m_diagnosticLinkMessages; } private: - Snapshot m_snapshot; Document::Ptr m_doc; - Link m_link; QList m_diagnosticLinkMessages; ContextPtr m_context; ScopeChain m_scopeChain; @@ -889,7 +888,9 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co QHash filteredPossibleImportKeys = filterPossibleImportKeys(snapshot.importDependencies()->libraryImports(viewContext), m_rewriterView->model()); - removeUsedImports(filteredPossibleImportKeys, m_scopeChain->context()->imports(m_document.data())->all()); + const QmlJS::Imports *imports = m_scopeChain->context()->imports(m_document.data()); + if (imports) + removeUsedImports(filteredPossibleImportKeys, imports->all()); QList possibleImports = generatePossibleLibraryImports(filteredPossibleImportKeys); @@ -901,7 +902,11 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co void TextToModelMerger::setupUsedImports() { - const QList allImports = m_scopeChain->context()->imports(m_document.data())->all(); + const QmlJS::Imports *imports = m_scopeChain->context()->imports(m_document.data()); + if (!imports) + return; + + const QList allImports = imports->all(); QList usedImports; @@ -942,6 +947,7 @@ Document::MutablePtr TextToModelMerger::createParsedDocument(const QUrl &url, co return doc; } + bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceHandler) { qCInfo(rewriterBenchmark) << Q_FUNC_INFO; @@ -969,7 +975,10 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH QList errors; QList warnings; + if (Document::MutablePtr doc = createParsedDocument(url, data, &errors)) { + if (m_document && (m_document->fingerprint() == doc->fingerprint())) + return true; snapshot.insert(doc); m_document = doc; qCInfo(rewriterBenchmark) << "parsed correctly: " << time.elapsed(); @@ -979,6 +988,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH setActive(false); return false; } + + m_vContext = ModelManagerInterface::instance()->defaultVContext(Dialect::Qml, m_document); ReadingContext ctxt(snapshot, m_document, m_vContext); m_scopeChain = QSharedPointer( @@ -1017,6 +1028,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH qCInfo(rewriterBenchmark) << "synced nodes:" << time.elapsed(); setActive(false); + return true; } catch (Exception &e) { DocumentMessage error(&e);