Do not execute overwritten bindings
During the construction of an object, internal bindings can be overwritten by the initialization of objects with outer scope. Task-number: QTBUG-23138 Change-Id: I46a187d9cdc41f4dd96d068f39788a2255b8888d Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
parent
03a6db7fc1
commit
8b0831f0b0
|
@ -205,13 +205,19 @@ inline bool fastHasBinding(QObject *o, int index)
|
|||
{
|
||||
QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(o)->declarativeData);
|
||||
|
||||
index &= 0xFFFFFF; // To handle value types
|
||||
|
||||
return ddata && (ddata->bindingBitsSize > index) &&
|
||||
(ddata->bindingBits[index / 32] & (1 << (index % 32)));
|
||||
}
|
||||
|
||||
static void removeBindingOnProperty(QObject *o, int index)
|
||||
{
|
||||
QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, index, -1, 0);
|
||||
int coreIndex = index & 0xFFFFFF;
|
||||
int valueTypeIndex = index & 0xFF000000;
|
||||
if (!valueTypeIndex) valueTypeIndex = -1;
|
||||
|
||||
QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, coreIndex, valueTypeIndex, 0);
|
||||
if (binding) binding->destroy();
|
||||
}
|
||||
|
||||
|
@ -782,6 +788,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
Q_ASSERT(bind->propertyIndex() == QDPP::bindingIndex(instr.property));
|
||||
Q_ASSERT(bind->object() == target);
|
||||
|
||||
CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property));
|
||||
|
||||
bind->addToObject();
|
||||
}
|
||||
QML_END_INSTR(StoreBinding)
|
||||
|
@ -805,6 +813,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
Q_ASSERT(binding->propertyIndex() == (property & 0xFF00FFFF));
|
||||
Q_ASSERT(binding->object() == target);
|
||||
|
||||
CLEAN_PROPERTY(target, property & 0xFF00FFFF);
|
||||
|
||||
binding->addToObject();
|
||||
QML_END_INSTR(StoreV4Binding)
|
||||
|
||||
|
@ -835,6 +845,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
Q_ASSERT(binding->propertyIndex() == QDPP::bindingIndex(instr.property));
|
||||
Q_ASSERT(binding->object() == target);
|
||||
|
||||
CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property));
|
||||
|
||||
binding->addToObject();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
QtObject {
|
||||
property int foo1: 100
|
||||
property int foo2: 100
|
||||
property int foo3: { return 100; }
|
||||
property int foo4: { return 100; }
|
||||
|
||||
property string bar1: 'Hello'
|
||||
property string bar2: 'Hello'
|
||||
property string bar3: { return 'Hello'; }
|
||||
property string bar4: { return 'Hello'; }
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
property InnerObject inner: InnerObject {}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
OuterObject {
|
||||
property bool success: false
|
||||
|
||||
inner.foo1: 200
|
||||
inner.foo2: { return 200; }
|
||||
inner.foo3: 200
|
||||
inner.foo4: { return 200; }
|
||||
|
||||
inner.bar1: 'Goodbye'
|
||||
inner.bar2: { return 'Goodbye' }
|
||||
inner.bar3: 'Goodbye'
|
||||
inner.bar4: { return 'Goodbye' }
|
||||
|
||||
Component.onCompleted: {
|
||||
success = (inner.foo1 == 200 &&
|
||||
inner.foo2 == 200 &&
|
||||
inner.foo3 == 200 &&
|
||||
inner.foo4 == 200 &&
|
||||
inner.bar1 == 'Goodbye' &&
|
||||
inner.bar2 == 'Goodbye' &&
|
||||
inner.bar3 == 'Goodbye' &&
|
||||
inner.bar4 == 'Goodbye');
|
||||
}
|
||||
}
|
|
@ -252,6 +252,7 @@ private slots:
|
|||
void switchStatement();
|
||||
void withStatement();
|
||||
void tryStatement();
|
||||
void replaceBinding();
|
||||
|
||||
private:
|
||||
static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
|
||||
|
@ -6416,6 +6417,18 @@ void tst_qqmlecmascript::registeredFlagMethod()
|
|||
delete object;
|
||||
}
|
||||
|
||||
// QTBUG-23138
|
||||
void tst_qqmlecmascript::replaceBinding()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, testFileUrl("replaceBinding.qml"));
|
||||
QObject *obj = c.create();
|
||||
QVERIFY(obj != 0);
|
||||
|
||||
QVERIFY(obj->property("success").toBool());
|
||||
delete obj;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmlecmascript)
|
||||
|
||||
#include "tst_qqmlecmascript.moc"
|
||||
|
|
Loading…
Reference in New Issue