diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-03-04 15:26:18 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-04 16:55:43 +0100 |
commit | 51f00a212c9414533010a47f6482d4f7ab0a75d9 (patch) | |
tree | 7cfa9f4469029ceae9f72fa873a7dc84911e4695 /src/qml/compiler/qqmltypecompiler.cpp | |
parent | dc9bf8ecdcc2ee59006c7ce2d57faadd755e9557 (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.cpp | 61 |
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 |