aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qqmltypecompiler.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-03-04 15:26:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-04 16:55:43 +0100
commit51f00a212c9414533010a47f6482d4f7ab0a75d9 (patch)
tree7cfa9f4469029ceae9f72fa873a7dc84911e4695 /src/qml/compiler/qqmltypecompiler.cpp
parentdc9bf8ecdcc2ee59006c7ce2d57faadd755e9557 (diff)
[new compiler] Fix property initialization order for mixed list and default property setups
Get a little closer to replicating the old compiler's behavior without introducing a new nested data structure for lists: * List property assignments should happen in declaration order for the items. Instead of doing magic in QmlObject::appendBinding, simply traverse the UiArrayBinding members in reverse order. Within a list, the items remain in order then, due to QmlObject::appendItem prepending. In the overall picture for the entire object, the reverse initialization order for properties is also preserved this way. * When an object has property bindings to the default property and also bindings to a named property that - after meta-object determination - turns out to be the default property, then we need to merge the bindings and preserve the declaration order. (tst_qqmlecmascript::defaultPropertyListOrder checks that) Fixes tst_qqmlenginedebugservice that expects bindings to an entire list to happen in reverse order (like other properties). Change-Id: I7408c97cdb971e06b1ee43a2a85f8cc6f008c444 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qqmltypecompiler.cpp')
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 780b3dae36..dfea506c8f 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -143,6 +143,11 @@ bool QQmlTypeCompiler::compile()
}
{
+ QQmlDefaultPropertyMerger merger(this);
+ merger.mergeDefaultProperties();
+ }
+
+ {
SignalHandlerConverter converter(this);
if (!converter.convertSignalHandlerExpressionsToFunctionDeclarations())
return false;
@@ -2358,4 +2363,60 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn
return true;
}
+QQmlDefaultPropertyMerger::QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , qmlObjects(*typeCompiler->qmlObjects())
+ , propertyCaches(typeCompiler->propertyCaches())
+{
+
+}
+
+void QQmlDefaultPropertyMerger::mergeDefaultProperties()
+{
+ for (int i = 0; i < qmlObjects.count(); ++i)
+ mergeDefaultProperties(i);
+}
+
+void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex)
+{
+ QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex);
+ if (!propertyCache)
+ return;
+
+ QmlObject *object = qmlObjects.at(objectIndex);
+
+ QString defaultProperty = object->indexOfDefaultProperty != -1 ? propertyCache->parent()->defaultPropertyName() : propertyCache->defaultPropertyName();
+ Binding *bindingsToReinsert = 0;
+ Binding *tail = 0;
+
+ Binding *previousBinding = 0;
+ Binding *binding = object->firstBinding();
+ while (binding) {
+ if (binding->propertyNameIndex == 0 || stringAt(binding->propertyNameIndex) != defaultProperty) {
+ previousBinding = binding;
+ binding = binding->next;
+ continue;
+ }
+
+ Binding *toReinsert = binding;
+ binding = object->unlinkBinding(previousBinding, binding);
+
+ if (!tail) {
+ bindingsToReinsert = toReinsert;
+ tail = toReinsert;
+ } else {
+ tail->next = toReinsert;
+ tail = tail->next;
+ }
+ tail->next = 0;
+ }
+
+ binding = bindingsToReinsert;
+ while (binding) {
+ Binding *toReinsert = binding;
+ binding = binding->next;
+ object->insertSorted(toReinsert);
+ }
+}
+
QT_END_NAMESPACE