QQmlType *attachedType = tr->type;
const int id = attachedType->attachedPropertiesId();
QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject);
- QQmlRefPointer<QQmlPropertyCache> cache = QQmlEnginePrivate::get(engine)->cache(attachedType->attachedPropertiesType());
- Q_ASSERT(!cache.isNull());
- if (!populateInstance(binding->value.objectIndex, qmlObject, cache, qmlObject, /*value type property*/0))
+ if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/0))
return false;
return true;
}
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(binding->value.objectIndex);
if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
- QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlRefPointer<QQmlPropertyCache> groupObjectPropertyCache;
QObject *groupObject = 0;
QQmlValueType *valueType = 0;
QQmlPropertyData *valueTypeProperty = 0;
valueType->read(_qobject, property->coreIndex);
- groupObjectPropertyCache = enginePrivate->cache(valueType);
groupObject = valueType;
valueTypeProperty = property;
} else {
return false;
}
- if (QQmlData *groupDeclarativeData = QQmlData::get(groupObject))
- groupObjectPropertyCache = groupDeclarativeData->propertyCache;
- if (!groupObjectPropertyCache)
- groupObjectPropertyCache = enginePrivate->propertyCacheForType(property->propType);
- if (!groupObjectPropertyCache) {
- recordError(binding->location, tr("Invalid grouped property access"));
- return false;
- }
-
-
bindingTarget = groupObject;
}
- if (!populateInstance(binding->value.objectIndex, groupObject, groupObjectPropertyCache, bindingTarget, valueTypeProperty))
+ if (!populateInstance(binding->value.objectIndex, groupObject, bindingTarget, valueTypeProperty))
return false;
if (valueType)
QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
Q_ASSERT(!cache.isNull());
+ if (installPropertyCache) {
+ if (ddata->propertyCache)
+ ddata->propertyCache->release();;
+ ddata->propertyCache = cache;
+ ddata->propertyCache->addref();
+ }
QObject *scopeObject = instance;
qSwap(_scopeObject, scopeObject);
qSwap(_qmlContext, qmlContext);
- bool result = populateInstance(index, instance, cache, /*binding target*/instance, /*value type property*/0, installPropertyCache, bindingsToSkip);
+ bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0, bindingsToSkip);
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
phase = Done;
}
-bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, bool installPropertyCache, const QBitArray &bindingsToSkip)
+bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, const QBitArray &bindingsToSkip)
{
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
Q_QML_VME_PROFILE(sharedState->profiler, push());
QQmlData *declarativeData = QQmlData::get(instance, /*create*/true);
- qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
qSwap(_valueTypeProperty, valueTypeProperty);
qSwap(_compiledObject, obj);
QV4::Scope valueScope(v4);
QV4::ScopedValue scopeObjectProtector(valueScope);
+ QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
+
QQmlVMEMetaObject *vmeMetaObject = 0;
const QByteArray data = vmeMetaObjectData.value(index);
if (!data.isEmpty()) {
+ Q_ASSERT(!cache.isNull());
// install on _object
- vmeMetaObject = new QQmlVMEMetaObject(_qobject, _propertyCache, reinterpret_cast<const QQmlVMEMetaData*>(data.constData()));
+ vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, reinterpret_cast<const QQmlVMEMetaData*>(data.constData()));
if (_ddata->propertyCache)
_ddata->propertyCache->release();
- Q_ASSERT(installPropertyCache);
+ _ddata->propertyCache = cache;
+ _ddata->propertyCache->addref();
scopeObjectProtector = _ddata->jsWrapper.value();
} else {
vmeMetaObject = QQmlVMEMetaObject::get(_qobject);
}
- if (installPropertyCache) {
- Q_ASSERT(_propertyCache);
- _ddata->propertyCache = _propertyCache;
- _ddata->propertyCache->addref();
- }
-
+ qSwap(_propertyCache, cache);
qSwap(_vmeMetaObject, vmeMetaObject);
- QVector<QQmlAbstractBinding*> createdBindings(_compiledObject->nBindings, 0);
-
QBitArray bindingSkipList = bindingsToSkip;
{
QHash<int, QBitArray>::ConstIterator deferredBindings = compiledData->deferredBindingsPerObject.find(index);
#include <private/qqmlmetatype_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlscriptstring_p.h>
+#include <private/qqmlvmemetaobject_p.h>
#include "testtypes.h"
#include "testhttpserver.h"
void customParserEvaluateEnum();
void preservePropertyCacheOnGroupObjects();
+ void propertyCacheInSync();
private:
QQmlEngine engine;
QCOMPARE(pd->propType, qMetaTypeId<int>());
}
+void tst_qqmllanguage::propertyCacheInSync()
+{
+ QQmlComponent component(&engine, testFile("propertyCacheInSync.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+ QObject *anchors = qvariant_cast<QObject*>(o->property("anchors"));
+ QVERIFY(anchors);
+ QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(anchors);
+ QVERIFY(vmemo);
+ QQmlPropertyCache *vmemoCache = vmemo->propertyCache();
+ QVERIFY(vmemoCache);
+ QQmlData *ddata = QQmlData::get(anchors);
+ QVERIFY(ddata);
+ QVERIFY(ddata->propertyCache);
+ // Those always have to be in sync and correct.
+ QVERIFY(ddata->propertyCache == vmemoCache);
+ QCOMPARE(anchors->property("margins").toInt(), 50);
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"