diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-03-04 20:48:11 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-05 15:01:07 +0100 |
commit | c8889fbb5561d75a7a383b86daa89c1b264c6f6e (patch) | |
tree | 4393600dc118c8fa9bbd3b518d23ca12d75f67e9 /src/qml/compiler | |
parent | e4e4a7912b03499a20f25e261e1c515aab17e5a8 (diff) |
[new compiler] Add support for deferred properties
Change-Id: I592518444ef353cfcf153df0e6afa2fbac613560
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 53 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 4 |
2 files changed, 50 insertions, 7 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 0cab2c4397..fd3d8a92e3 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -376,6 +376,11 @@ void QQmlTypeCompiler::setCustomParserBindings(const QVector<int> &bindings) compiledData->customParserBindings = bindings; } +void QQmlTypeCompiler::setDeferredBindingsPerObject(const QHash<int, QBitArray> &deferredBindingsPerObject) +{ + compiledData->deferredBindingsPerObject = deferredBindingsPerObject; +} + QQmlCompilePass::QQmlCompilePass(QQmlTypeCompiler *typeCompiler) : compiler(typeCompiler) { @@ -1603,6 +1608,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler) , propertyCaches(typeCompiler->propertyCaches()) , objectIndexToIdPerComponent(*typeCompiler->objectIndexToIdPerComponent()) , customParserData(typeCompiler->customParserData()) + , _seenObjectWithId(false) { } @@ -1611,6 +1617,7 @@ bool QQmlPropertyValidator::validate() if (!validateObject(qmlUnit->indexOfRootObject, /*instantiatingBinding*/0)) return false; compiler->setCustomParserBindings(customParserBindings); + compiler->setDeferredBindingsPerObject(deferredBindingsPerObject); return true; } @@ -1642,6 +1649,8 @@ typedef QVarLengthArray<const QV4::CompiledData::Binding *, 8> GroupPropertyVect bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty) { const QV4::CompiledData::Object *obj = qmlUnit->objectAt(objectIndex); + if (obj->idIndex != 0) + _seenObjectWithId = true; if (isComponent(objectIndex)) { Q_ASSERT(obj->nBindings == 1); @@ -1654,6 +1663,16 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD if (!propertyCache) return true; + QStringList deferredPropertyNames; + { + const QMetaObject *mo = propertyCache->firstCppMetaObject(); + const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames"); + if (namesIndex != -1) { + QMetaClassInfo classInfo = mo->classInfo(namesIndex); + deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(QLatin1Char(',')); + } + } + QQmlCustomParser *customParser = 0; QQmlCompiledData::TypeReference *objectType = resolvedTypes.value(obj->inheritedTypeNameIndex); if (objectType && objectType->type) @@ -1687,6 +1706,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } QBitArray customParserBindings(obj->nBindings); + QBitArray deferredBindings; PropertyResolver propertyResolver(propertyCache); @@ -1769,16 +1789,32 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD bindingToDefaultProperty = true; } + bool seenSubObjectWithId = false; + if (binding->type >= QV4::CompiledData::Binding::Type_Object) { - if (!validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::valueType(pd->propType))) + qSwap(_seenObjectWithId, seenSubObjectWithId); + const bool subObjectValid = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::valueType(pd->propType)); + qSwap(_seenObjectWithId, seenSubObjectWithId); + if (!subObjectValid) + return false; + _seenObjectWithId |= seenSubObjectWithId; + } + + if (!seenSubObjectWithId + && !deferredPropertyNames.isEmpty() && deferredPropertyNames.contains(name)) { + + if (deferredBindings.isEmpty()) + deferredBindings.resize(obj->nBindings); + + deferredBindings.setBit(i); + } + + if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + if (instantiatingBinding && (instantiatingBinding->isAttachedProperty() || instantiatingBinding->isGroupProperty())) { + recordError(binding->location, tr("Attached properties cannot be used here")); return false; - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { - if (instantiatingBinding && (instantiatingBinding->isAttachedProperty() || instantiatingBinding->isGroupProperty())) { - recordError(binding->location, tr("Attached properties cannot be used here")); - return false; - } - continue; } + continue; } if (pd) { @@ -1877,6 +1913,9 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } } + if (!deferredBindings.isEmpty()) + deferredBindingsPerObject.insert(objectIndex, deferredBindings); + return true; } diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 405438c0ab..73ca9de8b8 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -98,6 +98,7 @@ public: QStringRef newStringRef(const QString &string); const QStringList &stringPool() const; void setCustomParserBindings(const QVector<int> &bindings); + void setDeferredBindingsPerObject(const QHash<int, QBitArray> &deferredBindingsPerObject); private: QList<QQmlError> errors; @@ -264,6 +265,9 @@ private: const QHash<int, QHash<int, int> > objectIndexToIdPerComponent; QHash<int, QQmlCompiledData::CustomParserData> *customParserData; QVector<int> customParserBindings; + QHash<int, QBitArray> deferredBindingsPerObject; + + bool _seenObjectWithId; }; // ### merge with QtQml::JSCodeGen and operate directly on object->functionsAndExpressions once old compiler is gone. |