aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-06-16 10:08:13 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-06-17 07:38:49 +0000
commitd18026b00713de93bc3bd8f7e85f1ff0cf128185 (patch)
treec5245cd134a15179bccdc1cda835773168d3291a /src/qml
parent6b60de934bef14b17c05e726cea05b0bef8b8004 (diff)
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 <lars.knoll@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp52
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h4
-rw-r--r--src/qml/compiler/qv4compileddata_p.h3
-rw-r--r--src/qml/qml/qqmltypeloader.cpp78
-rw-r--r--src/qml/qml/qqmltypeloader_p.h8
5 files changed, 79 insertions, 66 deletions
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<QQmlTypeNameCache> &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<int, QQmlTypeData::TypeReference> &resolvedTypeRefs = typeData->resolvedTypeRefs();
- for (QHash<int, QQmlTypeData::TypeReference>::ConstIterator resolvedType = resolvedTypeRefs.constBegin(), end = resolvedTypeRefs.constEnd();
- resolvedType != end; ++resolvedType) {
- QScopedPointer<QV4::CompiledData::CompilationUnit::ResolvedTypeReference> 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<QQmlTypeNameCache> &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<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
- QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> 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<int, ResolvedTypeReference*> resolvedTypes;
+ typedef QHash<int, ResolvedTypeReference*> 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<QQmlError> &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::ScriptReference> &QQmlTypeData::resolvedScripts() cons
return m_scripts;
}
-const QSet<QString> &QQmlTypeData::namespaces() const
-{
- return m_namespaces;
-}
-
-const QList<QQmlTypeData::TypeReference> &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<QQmlTypeNameCache> 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<QQmlTypeNameCache> *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<QV4::CompiledData::CompilationUnit::ResolvedTypeReference> 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<QQmlError> &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<int, TypeReference> &resolvedTypeRefs() const { return m_resolvedTypes; }
-
const QList<ScriptReference> &resolvedScripts() const;
- const QSet<QString> &namespaces() const;
- const QList<TypeReference> &compositeSingletons() const;
QV4::CompiledData::CompilationUnit *compilationUnit() const;
@@ -451,6 +450,7 @@ protected:
private:
void continueLoadFromIR();
void resolveTypes();
+ QQmlCompileError buildTypeResolutionCaches(QQmlRefPointer<QQmlTypeNameCache> *importCache, QV4::CompiledData::CompilationUnit::ResolvedTypeReferenceMap *resolvedTypeCache) const;
void compile();
bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref);