aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-03-04 20:48:11 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-05 15:01:07 +0100
commitc8889fbb5561d75a7a383b86daa89c1b264c6f6e (patch)
tree4393600dc118c8fa9bbd3b518d23ca12d75f67e9 /src/qml/compiler
parente4e4a7912b03499a20f25e261e1c515aab17e5a8 (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.cpp53
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h4
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.