From d18026b00713de93bc3bd8f7e85f1ff0cf128185 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 16 Jun 2016 10:08:13 +0200 Subject: Moved import cache and type resolution cache code The code reads mostly from QQmlTypeData internal data structures, so it's cleaner to move it there - we can remove the getters for these internal fields. And it also allows for re-use later when not using the type compiler. Change-Id: I36cfaf3f1cecd6c8b223ee08516884a07bc60d6c Reviewed-by: Lars Knoll --- src/qml/compiler/qqmltypecompiler.cpp | 52 ++--------------------- src/qml/compiler/qqmltypecompiler_p.h | 4 +- src/qml/compiler/qv4compileddata_p.h | 3 +- src/qml/qml/qqmltypeloader.cpp | 78 ++++++++++++++++++++++++++++++----- src/qml/qml/qqmltypeloader_p.h | 8 ++-- 5 files changed, 79 insertions(+), 66 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 357307fcea..add330d5ce 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -57,61 +57,17 @@ QT_BEGIN_NAMESPACE -QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *parsedQML) - : engine(engine) +QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *parsedQML, const QQmlRefPointer &importCache, const QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap &resolvedTypeCache) + : resolvedTypes(resolvedTypeCache) + , engine(engine) , typeData(typeData) + , importCache(importCache) , document(parsedQML) { } QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() { - importCache.adopt(new QQmlTypeNameCache); - - foreach (const QString &ns, typeData->namespaces()) - importCache->add(ns); - - // Add any Composite Singletons that were used to the import cache - foreach (const QQmlTypeData::TypeReference &singleton, typeData->compositeSingletons()) - importCache->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix); - - typeData->imports().populateCache(importCache.data()); - - const QHash &resolvedTypeRefs = typeData->resolvedTypeRefs(); - for (QHash::ConstIterator resolvedType = resolvedTypeRefs.constBegin(), end = resolvedTypeRefs.constEnd(); - resolvedType != end; ++resolvedType) { - QScopedPointer ref(new QV4::CompiledData::CompilationUnit::ResolvedTypeReference); - QQmlType *qmlType = resolvedType->type; - if (resolvedType->typeData) { - if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) { - recordError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName())); - return nullptr; - } - ref->compilationUnit = resolvedType->typeData->compilationUnit(); - } else if (qmlType) { - ref->type = qmlType; - Q_ASSERT(ref->type); - - if (resolvedType->needsCreation && !ref->type->isCreatable()) { - QQmlError error; - QString reason = ref->type->noCreationReason(); - if (reason.isEmpty()) - reason = tr("Element is not creatable."); - recordError(resolvedType->location, reason); - return nullptr; - } - - if (ref->type->containsRevisionedAttributes()) { - ref->typePropertyCache = engine->cache(ref->type, - resolvedType->minorVersion); - } - } - ref->majorVersion = resolvedType->majorVersion; - ref->minorVersion = resolvedType->minorVersion; - ref->doDynamicTypeCheck(); - resolvedTypes.insert(resolvedType.key(), ref.take()); - } - // Build property caches and VME meta object data for (auto it = resolvedTypes.constBegin(), end = resolvedTypes.constEnd(); diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index b2494212fa..1692e05450 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -89,7 +89,7 @@ struct QQmlTypeCompiler { Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler) public: - QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document); + QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer &importCache, const QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap &resolvedTypeCache); // --- interface used by QQmlPropertyCacheCreator typedef QmlIR::Object CompiledObject; @@ -98,7 +98,7 @@ public: QString stringAt(int idx) const; QmlIR::PoolList::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); } QmlIR::PoolList::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); } - QHash resolvedTypes; + QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap resolvedTypes; // --- QV4::CompiledData::CompilationUnit *compile(); diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index fb82b2bcbb..36103a7b37 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -791,7 +791,8 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount void doDynamicTypeCheck(); }; // map from name index - QHash resolvedTypes; + typedef QHash ResolvedTypeReferenceMap; + ResolvedTypeReferenceMap resolvedTypes; int metaTypeId; int listMetaTypeId; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 847e138c5a..01201e66e7 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -434,6 +434,16 @@ void QQmlDataBlob::setError(const QList &errors) tryDone(); } +void QQmlDataBlob::setError(const QQmlCompileError &error) +{ + QQmlError e; + e.setColumn(error.location.column); + e.setLine(error.location.line); + e.setDescription(error.description); + e.setUrl(url()); + setError(e); +} + /*! Wait for \a blob to become complete or to error. If \a blob is already complete or in error, or this blob is already complete, this has no effect. @@ -2033,16 +2043,6 @@ const QList &QQmlTypeData::resolvedScripts() cons return m_scripts; } -const QSet &QQmlTypeData::namespaces() const -{ - return m_namespaces; -} - -const QList &QQmlTypeData::compositeSingletons() const -{ - return m_compositeSingletons; -} - QV4::CompiledData::CompilationUnit *QQmlTypeData::compilationUnit() const { return m_compiledData.data(); @@ -2301,7 +2301,15 @@ void QQmlTypeData::compile() { Q_ASSERT(m_compiledData.isNull()); - QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), this, m_document.data()); + QQmlRefPointer importCache; + QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap resolvedTypeCache; + QQmlCompileError error = buildTypeResolutionCaches(&importCache, &resolvedTypeCache); + if (error.isSet()) { + setError(error); + return; + } + + QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), this, m_document.data(), importCache, resolvedTypeCache); m_compiledData = compiler.compile(); if (!m_compiledData) { setError(compiler.compilationErrors()); @@ -2428,6 +2436,54 @@ void QQmlTypeData::resolveTypes() } } +QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(QQmlRefPointer *importCache, QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap *resolvedTypeCache) const +{ + importCache->adopt(new QQmlTypeNameCache); + + for (const QString &ns: m_namespaces) + (*importCache)->add(ns); + + // Add any Composite Singletons that were used to the import cache + for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons) + (*importCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix); + + m_importCache.populateCache(*importCache); + + QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); + + for (auto resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); resolvedType != end; ++resolvedType) { + QScopedPointer ref(new QV4::CompiledData::CompilationUnit::ResolvedTypeReference); + QQmlType *qmlType = resolvedType->type; + if (resolvedType->typeData) { + if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) { + return QQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName())); + } + ref->compilationUnit = resolvedType->typeData->compilationUnit(); + } else if (qmlType) { + ref->type = qmlType; + Q_ASSERT(ref->type); + + if (resolvedType->needsCreation && !ref->type->isCreatable()) { + QString reason = ref->type->noCreationReason(); + if (reason.isEmpty()) + reason = tr("Element is not creatable."); + return QQmlCompileError(resolvedType->location, reason); + } + + if (ref->type->containsRevisionedAttributes()) { + ref->typePropertyCache = engine->cache(ref->type, + resolvedType->minorVersion); + } + } + ref->majorVersion = resolvedType->majorVersion; + ref->minorVersion = resolvedType->minorVersion; + ref->doDynamicTypeCheck(); + resolvedTypeCache->insert(resolvedType.key(), ref.take()); + } + QQmlCompileError noError; + return noError; +} + bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref) { QQmlImportNamespace *typeNamespace = 0; diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 68b4d18a14..20f701514a 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -81,6 +81,7 @@ class QQmlComponentPrivate; class QQmlTypeData; class QQmlTypeLoader; class QQmlExtensionInterface; +struct QQmlCompileError; namespace QmlIR { struct Document; @@ -151,6 +152,7 @@ protected: // Can be called from within callbacks void setError(const QQmlError &); void setError(const QList &errors); + void setError(const QQmlCompileError &error); void addDependency(QQmlDataBlob *); // Callbacks made in load thread @@ -390,6 +392,7 @@ private: class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob { + Q_DECLARE_TR_FUNCTIONS(QQmlTypeData) public: struct TypeReference { @@ -421,11 +424,7 @@ private: public: ~QQmlTypeData(); - const QHash &resolvedTypeRefs() const { return m_resolvedTypes; } - const QList &resolvedScripts() const; - const QSet &namespaces() const; - const QList &compositeSingletons() const; QV4::CompiledData::CompilationUnit *compilationUnit() const; @@ -451,6 +450,7 @@ protected: private: void continueLoadFromIR(); void resolveTypes(); + QQmlCompileError buildTypeResolutionCaches(QQmlRefPointer *importCache, QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap *resolvedTypeCache) const; void compile(); bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref); -- cgit v1.2.3