Fix composite type registration in the new compiler
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 30 Sep 2013 03:52:31 +0000 (05:52 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 30 Sep 2013 16:21:39 +0000 (18:21 +0200)
When setting a property of a composite type like this

    property MyType foo: MyType {}

and MyType.qml defines the new type, we test for assignability of MyType to the
property foo. This test happens before MyType is instantiated and it relies on
the meta-type in the CompiledData being set. Therefore this patch makes sure
that the meta-type and the list meta-type are set accordingly at type
compilation time, not instantiation time, similar to how it's done in the VME.

Change-Id: Id7231e0a0113fa63ba6508bfbb1565dd554c5e56
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/qqmlcompiler_p.h
src/qml/qml/qqmlobjectcreator.cpp
src/qml/qml/qqmltypeloader.cpp

index 9e63ecb..475e438 100644 (file)
@@ -145,6 +145,7 @@ public:
     QHash<int, int> objectIndexToIdForRoot;
 
     bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
+    bool isCompositeType() const { return !datas.at(qmlUnit->indexOfRootObject).isEmpty(); }
     // ---
 
     struct Instruction {
index 55858e0..c320ca9 100644 (file)
@@ -542,8 +542,6 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
         ddata->compiledData->addref();
 
         context->contextObject = instance;
-
-        QQmlEnginePrivate::get(engine)->registerInternalCompositeType(compiledData);
     }
     return instance;
 }
index 849f0f4..63dff01 100644 (file)
@@ -2408,6 +2408,23 @@ void QQmlTypeData::compile()
                 errors << resolver.errors;
         }
 
+        if (errors.isEmpty()) {
+            // Add to type registry of composites
+            if (m_compiledData->isCompositeType())
+                QQmlEnginePrivate::get(engine)->registerInternalCompositeType(m_compiledData);
+            else {
+                const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
+                QQmlCompiledData::TypeReference typeRef = m_compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
+                if (typeRef.component) {
+                    m_compiledData->metaTypeId = typeRef.component->metaTypeId;
+                    m_compiledData->listMetaTypeId = typeRef.component->listMetaTypeId;
+                } else {
+                    m_compiledData->metaTypeId = typeRef.type->typeId();
+                    m_compiledData->listMetaTypeId = typeRef.type->qListTypeId();
+                }
+            }
+        }
+
         if (!errors.isEmpty()) {
             setError(errors);
             m_compiledData->release();