diff options
author | Glenn Watson <glenn.watson@nokia.com> | 2012-07-02 09:10:49 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-07-04 03:31:04 +0200 |
commit | f18b66ac6cfc734d217ec9d44876774f25e5d900 (patch) | |
tree | 7d8dffc65886f87a88c76d1ec29adca00d23b167 /src/qml/qml/qqmlcompiler.cpp | |
parent | ac9b09d4299bae22f6aa4b5423092167761d1c8d (diff) |
Make Behaviors work correctly with value types.
When a value type is referenced by sub-component a grouped
property is built. This code path did not handle behaviors being
declared on the entire value type. Add support for value interceptors
in this code path. Also issue an additional write to the value
type property before calling the interceptor on components
that are not being intercepted, so that the other
sub-components don't get stale values during write back.
Task-number: QTBUG-22625
Change-Id: I3365f422dfa1ab2e536e19575efcceceffb85e10
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlcompiler.cpp')
-rw-r--r-- | src/qml/qml/qqmlcompiler.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index fd42ab8382..e17163528c 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -1413,6 +1413,8 @@ void QQmlCompiler::genValueTypeProperty(QQmlScript::Object *obj,QQmlScript::Prop pop.type = prop->type; pop.bindingSkipList = 0; output->addInstruction(pop); + + genPropertyAssignment(prop, obj); } void QQmlCompiler::genComponent(QQmlScript::Object *obj) @@ -2106,10 +2108,15 @@ bool QQmlCompiler::buildGroupedProperty(QQmlScript::Property *prop, if (prop->type >= 0 && enginePrivate->valueTypes[prop->type]) { if (!prop->values.isEmpty()) { - if (prop->values.first()->location < prop->value->location) { - COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value")); - } else { - COMPILE_EXCEPTION(prop->values.first(), tr( "Property has already been assigned a value")); + // Only error if we are assigning values, and not e.g. a property interceptor + for (Property *dotProp = prop->value->properties.first(); dotProp; dotProp = prop->value->properties.next(dotProp)) { + if (!dotProp->values.isEmpty()) { + if (prop->values.first()->location < prop->value->location) { + COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value")); + } else { + COMPILE_EXCEPTION(prop->values.first(), tr( "Property has already been assigned a value")); + } + } } } @@ -2117,7 +2124,6 @@ bool QQmlCompiler::buildGroupedProperty(QQmlScript::Property *prop, COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); } - if (prop->isAlias) { for (Property *vtProp = prop->value->properties.first(); vtProp; vtProp = prop->value->properties.next(vtProp)) { vtProp->isAlias = true; @@ -2126,7 +2132,26 @@ bool QQmlCompiler::buildGroupedProperty(QQmlScript::Property *prop, COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type], prop->value, obj, ctxt.incr())); + + // When building a value type where sub components are declared, this + // code path is followed from buildProperty, even if there is a previous + // assignment to the value type as a whole. Therefore we need to look + // for (and build) assignments to the entire value type before looking + // for any onValue assignments. + for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) { + if (v->object) { + COMPILE_EXCEPTION(v->object, tr("Objects cannot be assigned to value types")); + } + COMPILE_CHECK(buildPropertyLiteralAssignment(prop, obj, v, ctxt)); + } + + for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) { + Q_ASSERT(v->object); + COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, obj, v, ctxt)); + } + obj->addValueTypeProperty(prop); + } else { COMPILE_EXCEPTION(prop, tr("Invalid grouped property access")); } |