aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
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.