QML: Introduce QQmlPropertyIndex

This helps in making it clear when an index is a plain old number and
when it consists of an encoded value type index.

Change-Id: Ic50d95caf244ed0ee2d62bdba53910a371cfee04
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Erik Verbruggen 2016-07-22 10:08:17 +02:00
parent fdc3dcd43f
commit 1534dd6d97
22 changed files with 283 additions and 138 deletions

View File

@ -576,8 +576,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie
const QQmlPropertyCache *targetCache = propertyCaches->at(targetObjectIndex); const QQmlPropertyCache *targetCache = propertyCaches->at(targetObjectIndex);
Q_ASSERT(targetCache); Q_ASSERT(targetCache);
int coreIndex; int coreIndex = QQmlPropertyIndex::fromEncoded(alias->encodedMetaPropertyIndex).coreIndex();
QQmlPropertyData::decodeValueTypePropertyIndex(alias->encodedMetaPropertyIndex, &coreIndex);
QQmlPropertyData *targetProperty = targetCache->property(coreIndex); QQmlPropertyData *targetProperty = targetCache->property(coreIndex);
if (!targetProperty) if (!targetProperty)
return false; return false;
@ -655,8 +654,8 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
*propertyFlags |= QQmlPropertyData::IsQObjectDerived; *propertyFlags |= QQmlPropertyData::IsQObjectDerived;
} else { } else {
int coreIndex; int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex();
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(alias.encodedMetaPropertyIndex, &coreIndex); int valueTypeIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).valueTypeIndex();
QQmlPropertyCache *targetCache = propertyCaches->at(targetObjectIndex); QQmlPropertyCache *targetCache = propertyCaches->at(targetObjectIndex);
Q_ASSERT(targetCache); Q_ASSERT(targetCache);

View File

@ -1078,7 +1078,7 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
} else } else
property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length()); property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length());
int propIdx = -1; QQmlPropertyIndex propIdx;
if (property.isEmpty()) { if (property.isEmpty()) {
alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject;
@ -1121,7 +1121,7 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
break; break;
} }
propIdx = targetProperty->coreIndex; propIdx = QQmlPropertyIndex(targetProperty->coreIndex);
if (!subProperty.isEmpty()) { if (!subProperty.isEmpty()) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType); const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType);
@ -1138,14 +1138,14 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
} }
Q_ASSERT(valueTypeIndex <= 0x0000FFFF); Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
propIdx = QQmlPropertyData::encodeValueTypePropertyIndex(propIdx, valueTypeIndex); propIdx = QQmlPropertyIndex(propIdx.coreIndex(), valueTypeIndex);
} else { } else {
if (targetProperty->isQObject()) if (targetProperty->isQObject())
alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject;
} }
} }
alias->encodedMetaPropertyIndex = propIdx; alias->encodedMetaPropertyIndex = propIdx.toEncoded();
alias->flags |= QV4::CompiledData::Alias::Resolved; alias->flags |= QV4::CompiledData::Alias::Resolved;
numResolvedAliases++; numResolvedAliases++;
} }

View File

@ -328,7 +328,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired) ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired)
{ {
QQmlData::flushPendingBinding(object, property->coreIndex); QQmlData::flushPendingBinding(object, property->encodedIndex());
if (property->isFunction() && !property->isVarProperty()) { if (property->isFunction() && !property->isVarProperty()) {
if (property->isVMEFunction()) { if (property->isVMEFunction()) {

View File

@ -90,6 +90,7 @@ HEADERS += \
$$PWD/qqmlxmlhttprequest_p.h \ $$PWD/qqmlxmlhttprequest_p.h \
$$PWD/qqmlcleanup_p.h \ $$PWD/qqmlcleanup_p.h \
$$PWD/qqmlpropertycache_p.h \ $$PWD/qqmlpropertycache_p.h \
$$PWD/qqmlpropertyindex_p.h \
$$PWD/qqmlnotifier_p.h \ $$PWD/qqmlnotifier_p.h \
$$PWD/qqmltypenotavailable_p.h \ $$PWD/qqmltypenotavailable_p.h \
$$PWD/qqmltypenamecache_p.h \ $$PWD/qqmltypenamecache_p.h \

View File

@ -78,24 +78,26 @@ void QQmlAbstractBinding::addToObject()
QQmlData *data = QQmlData::get(obj, true); QQmlData *data = QQmlData::get(obj, true);
int coreIndex; int coreIndex = targetPropertyIndex().coreIndex();
if (QQmlPropertyData::decodeValueTypePropertyIndex(targetPropertyIndex(), &coreIndex) != -1) { if (targetPropertyIndex().hasValueTypeIndex()) {
// Value type // Value type
// Find the value type proxy (if there is one) // Find the value type proxy (if there is one)
QQmlValueTypeProxyBinding *proxy = 0; QQmlValueTypeProxyBinding *proxy = 0;
if (data->hasBindingBit(coreIndex)) { if (data->hasBindingBit(coreIndex)) {
QQmlAbstractBinding *b = data->bindings; QQmlAbstractBinding *b = data->bindings;
while (b && b->targetPropertyIndex() != coreIndex) while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
b->targetPropertyIndex().hasValueTypeIndex()))
b = b->nextBinding(); b = b->nextBinding();
Q_ASSERT(b && b->isValueTypeProxy()); Q_ASSERT(b && b->isValueTypeProxy());
proxy = static_cast<QQmlValueTypeProxyBinding *>(b); proxy = static_cast<QQmlValueTypeProxyBinding *>(b);
} }
if (!proxy) { if (!proxy) {
proxy = new QQmlValueTypeProxyBinding(obj, coreIndex); proxy = new QQmlValueTypeProxyBinding(obj, QQmlPropertyIndex(coreIndex));
Q_ASSERT(proxy->targetPropertyIndex() == coreIndex); Q_ASSERT(proxy->targetPropertyIndex().coreIndex() == coreIndex);
Q_ASSERT(!proxy->targetPropertyIndex().hasValueTypeIndex());
Q_ASSERT(proxy->targetObject() == obj); Q_ASSERT(proxy->targetObject() == obj);
proxy->addToObject(); proxy->addToObject();
@ -137,12 +139,13 @@ void QQmlAbstractBinding::removeFromObject()
next = nextBinding(); next = nextBinding();
setNextBinding(0); setNextBinding(0);
int coreIndex; int coreIndex = targetPropertyIndex().coreIndex();
if (QQmlPropertyData::decodeValueTypePropertyIndex(targetPropertyIndex(), &coreIndex) != -1) { if (targetPropertyIndex().hasValueTypeIndex()) {
// Find the value type binding // Find the value type binding
QQmlAbstractBinding *vtbinding = data->bindings; QQmlAbstractBinding *vtbinding = data->bindings;
while (vtbinding->targetPropertyIndex() != coreIndex) { while (vtbinding && (vtbinding->targetPropertyIndex().coreIndex() != coreIndex ||
vtbinding->targetPropertyIndex().hasValueTypeIndex())) {
vtbinding = vtbinding->nextBinding(); vtbinding = vtbinding->nextBinding();
Q_ASSERT(vtbinding); Q_ASSERT(vtbinding);
} }

View File

@ -76,7 +76,7 @@ public:
// Should return the encoded property index for the binding. Should return this value // Should return the encoded property index for the binding. Should return this value
// even if the binding is not enabled or added to an object. // even if the binding is not enabled or added to an object.
// Encoding is: coreIndex | (valueTypeIndex << 16) // Encoding is: coreIndex | (valueTypeIndex << 16)
int targetPropertyIndex() const { return m_targetIndex; } QQmlPropertyIndex targetPropertyIndex() const { return m_targetIndex; }
// Should return the object for the binding. Should return this object even if the // Should return the object for the binding. Should return this object even if the
// binding is not enabled or added to the object. // binding is not enabled or added to the object.
@ -113,7 +113,7 @@ protected:
inline void setNextBinding(QQmlAbstractBinding *); inline void setNextBinding(QQmlAbstractBinding *);
int m_targetIndex; QQmlPropertyIndex m_targetIndex;
// Pointer is the target object to which the binding binds // Pointer is the target object to which the binding binds
// flag1 is the updating flag // flag1 is the updating flag

View File

@ -465,8 +465,7 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags)
m_nextBinding.setFlag2(); // Always use accessors, only not when: m_nextBinding.setFlag2(); // Always use accessors, only not when:
if (auto interceptorMetaObject = QQmlInterceptorMetaObject::get(targetObject())) { if (auto interceptorMetaObject = QQmlInterceptorMetaObject::get(targetObject())) {
int coreIndex = getPropertyCoreIndex(); if (!m_targetIndex.isValid() || interceptorMetaObject->intercepts(m_targetIndex))
if (coreIndex == -1 || interceptorMetaObject->intercepts(coreIndex))
m_nextBinding.clearFlag2(); m_nextBinding.clearFlag2();
} }
@ -491,7 +490,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
m_target = object; m_target = object;
if (!object) { if (!object) {
m_targetIndex = -1; m_targetIndex = QQmlPropertyIndex();
return; return;
} }
@ -505,7 +504,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
int aValueTypeIndex; int aValueTypeIndex;
if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) { if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
m_target = 0; m_target = 0;
m_targetIndex = -1; m_targetIndex = QQmlPropertyIndex();
return; return;
} }
if (valueTypeIndex == -1) if (valueTypeIndex == -1)
@ -514,7 +513,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
QQmlData *data = QQmlData::get(object, false); QQmlData *data = QQmlData::get(object, false);
if (!data || !data->propertyCache) { if (!data || !data->propertyCache) {
m_target = 0; m_target = 0;
m_targetIndex = -1; m_targetIndex = QQmlPropertyIndex();
return; return;
} }
QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
@ -543,39 +542,25 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
QQmlPropertyData QQmlBinding::getPropertyData() const QQmlPropertyData QQmlBinding::getPropertyData() const
{ {
int coreIndex;
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(m_targetIndex, &coreIndex);
QQmlData *data = QQmlData::get(*m_target, false); QQmlData *data = QQmlData::get(*m_target, false);
Q_ASSERT(data && data->propertyCache); Q_ASSERT(data && data->propertyCache);
QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); QQmlPropertyData *propertyData = data->propertyCache->property(m_targetIndex.coreIndex());
Q_ASSERT(propertyData); Q_ASSERT(propertyData);
QQmlPropertyData d = *propertyData; QQmlPropertyData d = *propertyData;
if (Q_UNLIKELY(valueTypeIndex != -1)) { if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex())) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d.propType); const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d.propType);
Q_ASSERT(valueTypeMetaObject); Q_ASSERT(valueTypeMetaObject);
QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex); QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex());
d.setFlags(d.getFlags() | QQmlPropertyData::IsValueTypeVirtual); d.setFlags(d.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
d.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp); d.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp);
d.valueTypePropType = vtProp.userType(); d.valueTypePropType = vtProp.userType();
d.valueTypeCoreIndex = valueTypeIndex; d.valueTypeCoreIndex = m_targetIndex.valueTypeIndex();
} }
return d; return d;
} }
Q_ALWAYS_INLINE int QQmlBinding::getPropertyCoreIndex() const
{
int coreIndex;
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(m_targetIndex, &coreIndex);
if (valueTypeIndex != -1) {
return -1;
} else {
return coreIndex;
}
}
class QObjectPointerBinding: public QQmlNonbindingBinding class QObjectPointerBinding: public QQmlNonbindingBinding
{ {
QQmlMetaObject targetMetaObject; QQmlMetaObject targetMetaObject;

View File

@ -107,7 +107,6 @@ protected:
const QV4::ScopedFunctionObject &f) = 0; const QV4::ScopedFunctionObject &f) = 0;
QQmlPropertyData getPropertyData() const; QQmlPropertyData getPropertyData() const;
int getPropertyCoreIndex() const;
int getPropertyType() const; int getPropertyType() const;
bool slowWrite(const QQmlPropertyData &core, const QV4::Value &result, bool isUndefined, bool slowWrite(const QQmlPropertyData &core, const QV4::Value &result, bool isUndefined,

View File

@ -53,7 +53,7 @@
#include <private/qtqmlglobal_p.h> #include <private/qtqmlglobal_p.h>
#include <private/qobject_p.h> #include <private/qobject_p.h>
#include <private/qqmlpropertyindex_p.h>
#include <private/qv4value_p.h> #include <private/qv4value_p.h>
#include <private/qv4persistent_p.h> #include <private/qv4persistent_p.h>
#include <qjsengine.h> #include <qjsengine.h>
@ -174,7 +174,7 @@ public:
void clearBindingBit(int); void clearBindingBit(int);
void setBindingBit(QObject *obj, int); void setBindingBit(QObject *obj, int);
inline bool hasPendingBindingBit(int) const; inline bool hasPendingBindingBit(int index) const;
void setPendingBindingBit(QObject *obj, int); void setPendingBindingBit(QObject *obj, int);
void clearPendingBindingBit(int); void clearPendingBindingBit(int);
@ -227,7 +227,7 @@ public:
static void markAsDeleted(QObject *); static void markAsDeleted(QObject *);
static void setQueuedForDeletion(QObject *); static void setQueuedForDeletion(QObject *);
static inline void flushPendingBinding(QObject *, int coreIndex); static inline void flushPendingBinding(QObject *, QQmlPropertyIndex propertyIndex);
static QQmlPropertyCache *ensurePropertyCache(QJSEngine *engine, QObject *object); static QQmlPropertyCache *ensurePropertyCache(QJSEngine *engine, QObject *object);
@ -235,7 +235,7 @@ private:
// For attachedProperties // For attachedProperties
mutable QQmlDataExtended *extendedData; mutable QQmlDataExtended *extendedData;
void flushPendingBindingImpl(int coreIndex); void flushPendingBindingImpl(QQmlPropertyIndex index);
}; };
bool QQmlData::wasDeleted(QObject *object) bool QQmlData::wasDeleted(QObject *object)
@ -288,20 +288,20 @@ bool QQmlData::hasBindingBit(int coreIndex) const
(bindingBits[bit / 32] & (1 << (bit % 32)))); (bindingBits[bit / 32] & (1 << (bit % 32))));
} }
bool QQmlData::hasPendingBindingBit(int coreIndex) const bool QQmlData::hasPendingBindingBit(int index) const
{ {
int bit = coreIndex * 2 + 1; int bit = index * 2 + 1;
return bindingBitsSize > bit && return bindingBitsSize > bit &&
((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) : ((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) :
(bindingBits[bit / 32] & (1 << (bit % 32)))); (bindingBits[bit / 32] & (1 << (bit % 32))));
} }
void QQmlData::flushPendingBinding(QObject *o, int coreIndex) void QQmlData::flushPendingBinding(QObject *o, QQmlPropertyIndex propertyIndex)
{ {
QQmlData *data = QQmlData::get(o, false); QQmlData *data = QQmlData::get(o, false);
if (data && data->hasPendingBindingBit(coreIndex)) if (data && data->hasPendingBindingBit(propertyIndex.coreIndex()))
data->flushPendingBindingImpl(coreIndex); data->flushPendingBindingImpl(propertyIndex);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -837,16 +837,18 @@ void QQmlData::setQueuedForDeletion(QObject *object)
} }
} }
void QQmlData::flushPendingBindingImpl(int coreIndex) void QQmlData::flushPendingBindingImpl(QQmlPropertyIndex index)
{ {
clearPendingBindingBit(coreIndex); clearPendingBindingBit(index.coreIndex());
// Find the binding // Find the binding
QQmlAbstractBinding *b = bindings; QQmlAbstractBinding *b = bindings;
while (b && b->targetPropertyIndex() != coreIndex) while (b && (b->targetPropertyIndex().coreIndex() != index.coreIndex() ||
b->targetPropertyIndex().hasValueTypeIndex()))
b = b->nextBinding(); b = b->nextBinding();
if (b && b->targetPropertyIndex() == coreIndex) if (b && b->targetPropertyIndex().coreIndex() == index.coreIndex() &&
!b->targetPropertyIndex().hasValueTypeIndex())
b->setEnabled(true, QQmlPropertyData::BypassInterceptor | b->setEnabled(true, QQmlPropertyData::BypassInterceptor |
QQmlPropertyData::DontRemoveBinding); QQmlPropertyData::DontRemoveBinding);
} }
@ -1788,21 +1790,29 @@ static void QQmlData_clearBit(QQmlData *data, int bit)
void QQmlData::clearBindingBit(int coreIndex) void QQmlData::clearBindingBit(int coreIndex)
{ {
Q_ASSERT(coreIndex >= 0);
Q_ASSERT(coreIndex <= 0xffff);
QQmlData_clearBit(this, coreIndex * 2); QQmlData_clearBit(this, coreIndex * 2);
} }
void QQmlData::setBindingBit(QObject *obj, int coreIndex) void QQmlData::setBindingBit(QObject *obj, int coreIndex)
{ {
Q_ASSERT(coreIndex >= 0);
Q_ASSERT(coreIndex <= 0xffff);
QQmlData_setBit(this, obj, coreIndex * 2); QQmlData_setBit(this, obj, coreIndex * 2);
} }
void QQmlData::clearPendingBindingBit(int coreIndex) void QQmlData::clearPendingBindingBit(int coreIndex)
{ {
Q_ASSERT(coreIndex >= 0);
Q_ASSERT(coreIndex <= 0xffff);
QQmlData_clearBit(this, coreIndex * 2 + 1); QQmlData_clearBit(this, coreIndex * 2 + 1);
} }
void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex) void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex)
{ {
Q_ASSERT(coreIndex >= 0);
Q_ASSERT(coreIndex <= 0xffff);
QQmlData_setBit(this, obj, coreIndex * 2 + 1); QQmlData_setBit(this, obj, coreIndex * 2 + 1);
} }

View File

@ -636,10 +636,10 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
// ### this is best done through type-compile-time binding skip lists. // ### this is best done through type-compile-time binding skip lists.
if (_valueTypeProperty) { if (_valueTypeProperty) {
QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex); QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex));
if (binding && !binding->isValueTypeProxy()) { if (binding && !binding->isValueTypeProxy()) {
QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex); QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex));
} else if (binding) { } else if (binding) {
QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding); QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding);
@ -788,7 +788,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
&& !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment)
&& !_valueTypeProperty) && !_valueTypeProperty)
QQmlPropertyPrivate::removeBinding(_bindingTarget, property->coreIndex); QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(property->coreIndex));
if (binding->type == QV4::CompiledData::Binding::Type_Script) { if (binding->type == QV4::CompiledData::Binding::Type_Script) {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
@ -857,14 +857,16 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QObject *target = createdSubObject->parent(); QObject *target = createdSubObject->parent();
if (targetCorePropertyData.isAlias()) { if (targetCorePropertyData.isAlias()) {
int propIndex; QQmlPropertyIndex propIndex;
QQmlPropertyPrivate::findAliasTarget(target, targetCorePropertyData.coreIndex, &target, &propIndex); QQmlPropertyPrivate::findAliasTarget(target, QQmlPropertyIndex(targetCorePropertyData.coreIndex), &target, &propIndex);
QQmlData *data = QQmlData::get(target); QQmlData *data = QQmlData::get(target);
if (!data || !data->propertyCache) { if (!data || !data->propertyCache) {
qWarning() << "can't resolve property alias for 'on' assignment"; qWarning() << "can't resolve property alias for 'on' assignment";
return false; return false;
} }
targetCorePropertyData = *data->propertyCache->property(propIndex);
// we can't have aliasses on subproperties of value types, so:
targetCorePropertyData = *data->propertyCache->property(propIndex.coreIndex());
} }
QQmlProperty prop = QQmlProperty prop =
@ -874,7 +876,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QQmlInterceptorMetaObject *mo = QQmlInterceptorMetaObject::get(target); QQmlInterceptorMetaObject *mo = QQmlInterceptorMetaObject::get(target);
if (!mo) if (!mo)
mo = new QQmlInterceptorMetaObject(target, QQmlData::get(target)->propertyCache); mo = new QQmlInterceptorMetaObject(target, QQmlData::get(target)->propertyCache);
mo->registerInterceptor(prop.index(), QQmlPropertyPrivate::valueTypeCoreIndex(prop), vi); mo->registerInterceptor(QQmlPropertyPrivate::propertyIndex(prop), vi);
return true; return true;
} }
return false; return false;
@ -1191,7 +1193,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
continue; continue;
QQmlData *data = QQmlData::get(b->targetObject()); QQmlData *data = QQmlData::get(b->targetObject());
Q_ASSERT(data); Q_ASSERT(data);
data->clearPendingBindingBit(b->targetPropertyIndex()); data->clearPendingBindingBit(b->targetPropertyIndex().coreIndex());
b->setEnabled(true, QQmlPropertyData::BypassInterceptor | b->setEnabled(true, QQmlPropertyData::BypassInterceptor |
QQmlPropertyData::DontRemoveBinding); QQmlPropertyData::DontRemoveBinding);

View File

@ -741,10 +741,10 @@ QQmlPropertyPrivate::setBinding(const QQmlProperty &that, QQmlAbstractBinding *n
setBinding(newBinding); setBinding(newBinding);
} }
static void removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::BindingFlags flags = QQmlPropertyPrivate::None) static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPropertyPrivate::BindingFlags flags = QQmlPropertyPrivate::None)
{ {
int coreIndex; int coreIndex = index.coreIndex();
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); int valueTypeIndex = index.valueTypeIndex();
QQmlData *data = QQmlData::get(object, false); QQmlData *data = QQmlData::get(object, false);
@ -754,7 +754,8 @@ static void removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::Bi
QQmlAbstractBinding::Ptr oldBinding; QQmlAbstractBinding::Ptr oldBinding;
oldBinding = data->bindings; oldBinding = data->bindings;
while (oldBinding && oldBinding->targetPropertyIndex() != coreIndex) while (oldBinding && (oldBinding->targetPropertyIndex().coreIndex() != coreIndex ||
oldBinding->targetPropertyIndex().hasValueTypeIndex()))
oldBinding = oldBinding->nextBinding(); oldBinding = oldBinding->nextBinding();
if (!oldBinding) if (!oldBinding)
@ -776,12 +777,12 @@ void QQmlPropertyPrivate::removeBinding(QQmlAbstractBinding *b)
removeBinding(b->targetObject(), b->targetPropertyIndex()); removeBinding(b->targetObject(), b->targetPropertyIndex());
} }
void QQmlPropertyPrivate::removeBinding(QObject *o, int index) void QQmlPropertyPrivate::removeBinding(QObject *o, QQmlPropertyIndex index)
{ {
Q_ASSERT(o); Q_ASSERT(o);
QObject *target; QObject *target;
int targetIndex; QQmlPropertyIndex targetIndex;
findAliasTarget(o, index, &target, &targetIndex); findAliasTarget(o, index, &target, &targetIndex);
removeOldBinding(target, targetIndex); removeOldBinding(target, targetIndex);
} }
@ -795,7 +796,7 @@ void QQmlPropertyPrivate::removeBinding(const QQmlProperty &that)
} }
QQmlAbstractBinding * QQmlAbstractBinding *
QQmlPropertyPrivate::binding(QObject *object, int index) QQmlPropertyPrivate::binding(QObject *object, QQmlPropertyIndex index)
{ {
QQmlData *data = QQmlData::get(object); QQmlData *data = QQmlData::get(object);
if (!data) if (!data)
@ -803,19 +804,19 @@ QQmlPropertyPrivate::binding(QObject *object, int index)
findAliasTarget(object, index, &object, &index); findAliasTarget(object, index, &object, &index);
int coreIndex; const int coreIndex = index.coreIndex();
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); const int valueTypeIndex = index.valueTypeIndex();
if (!data->hasBindingBit(coreIndex)) if (!data->hasBindingBit(coreIndex))
return 0; return 0;
QQmlAbstractBinding *binding = data->bindings; QQmlAbstractBinding *binding = data->bindings;
while (binding && binding->targetPropertyIndex() != coreIndex) while (binding && (binding->targetPropertyIndex().coreIndex() != coreIndex ||
binding->targetPropertyIndex().hasValueTypeIndex()))
binding = binding->nextBinding(); binding = binding->nextBinding();
if (binding && valueTypeIndex != -1) { if (binding && valueTypeIndex != -1) {
if (binding->isValueTypeProxy()) { if (binding->isValueTypeProxy()) {
int index = QQmlPropertyData::encodeValueTypePropertyIndex(coreIndex, valueTypeIndex);
binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index); binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
} }
} }
@ -823,13 +824,14 @@ QQmlPropertyPrivate::binding(QObject *object, int index)
return binding; return binding;
} }
void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, void QQmlPropertyPrivate::findAliasTarget(QObject *object, QQmlPropertyIndex bindingIndex,
QObject **targetObject, int *targetBindingIndex) QObject **targetObject,
QQmlPropertyIndex *targetBindingIndex)
{ {
QQmlData *data = QQmlData::get(object, false); QQmlData *data = QQmlData::get(object, false);
if (data) { if (data) {
int coreIndex; int coreIndex = bindingIndex.coreIndex();
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex); int valueTypeIndex = bindingIndex.valueTypeIndex();
QQmlPropertyData *propertyData = QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0; data->propertyCache?data->propertyCache->property(coreIndex):0;
@ -841,11 +843,12 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
// This will either be a value type sub-reference or an alias to a value-type sub-reference not both // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
int aBindingIndex = aCoreIndex; QQmlPropertyIndex aBindingIndex(aCoreIndex);
if (aValueTypeIndex != -1) if (aValueTypeIndex != -1) {
aBindingIndex = QQmlPropertyData::encodeValueTypePropertyIndex(aBindingIndex, aValueTypeIndex); aBindingIndex = QQmlPropertyIndex(aCoreIndex, aValueTypeIndex);
else if (valueTypeIndex != -1) } else if (valueTypeIndex != -1) {
aBindingIndex = QQmlPropertyData::encodeValueTypePropertyIndex(aBindingIndex, valueTypeIndex); aBindingIndex = QQmlPropertyIndex(aCoreIndex, valueTypeIndex);
}
findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex); findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex);
return; return;
@ -863,11 +866,10 @@ void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags
Q_ASSERT(binding); Q_ASSERT(binding);
QObject *object = binding->targetObject(); QObject *object = binding->targetObject();
int index = binding->targetPropertyIndex(); const QQmlPropertyIndex index = binding->targetPropertyIndex();
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
int coreIndex; int coreIndex = index.coreIndex();
QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
QQmlData *data = QQmlData::get(object, true); QQmlData *data = QQmlData::get(object, true);
if (data->propertyCache) { if (data->propertyCache) {
QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
@ -1600,9 +1602,9 @@ int QQmlProperty::index() const
return d ? d->core.coreIndex : -1; return d ? d->core.coreIndex : -1;
} }
int QQmlPropertyPrivate::valueTypeCoreIndex(const QQmlProperty &that) QQmlPropertyIndex QQmlPropertyPrivate::propertyIndex(const QQmlProperty &that)
{ {
return that.d ? that.d->core.getValueTypeCoreIndex() : -1; return that.d ? that.d->core.encodedIndex() : QQmlPropertyIndex();
} }
/*! /*!

View File

@ -101,7 +101,7 @@ public:
QQmlPropertyData::WriteFlags flags = 0); QQmlPropertyData::WriteFlags flags = 0);
static bool write(QObject *, const QQmlPropertyData &, const QVariant &, static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
QQmlContextData *, QQmlPropertyData::WriteFlags flags = 0); QQmlContextData *, QQmlPropertyData::WriteFlags flags = 0);
static void findAliasTarget(QObject *, int, QObject **, int *); static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *);
enum BindingFlag { enum BindingFlag {
None = 0, None = 0,
@ -112,9 +112,9 @@ public:
static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, QQmlPropertyData::WriteFlags writeFlags = QQmlPropertyData::DontRemoveBinding); static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, QQmlPropertyData::WriteFlags writeFlags = QQmlPropertyData::DontRemoveBinding);
static void removeBinding(const QQmlProperty &that); static void removeBinding(const QQmlProperty &that);
static void removeBinding(QObject *o, int index); static void removeBinding(QObject *o, QQmlPropertyIndex index);
static void removeBinding(QQmlAbstractBinding *b); static void removeBinding(QQmlAbstractBinding *b);
static QQmlAbstractBinding *binding(QObject *, int index); static QQmlAbstractBinding *binding(QObject *, QQmlPropertyIndex index);
static QQmlPropertyData saveValueType(const QQmlPropertyData &, static QQmlPropertyData saveValueType(const QQmlPropertyData &,
const QMetaObject *, int, const QMetaObject *, int,
@ -138,7 +138,7 @@ public:
static void takeSignalExpression(const QQmlProperty &that, static void takeSignalExpression(const QQmlProperty &that,
QQmlBoundSignalExpression *); QQmlBoundSignalExpression *);
static bool write(const QQmlProperty &that, const QVariant &, QQmlPropertyData::WriteFlags); static bool write(const QQmlProperty &that, const QVariant &, QQmlPropertyData::WriteFlags);
static int valueTypeCoreIndex(const QQmlProperty &that); static QQmlPropertyIndex propertyIndex(const QQmlProperty &that);
static int bindingIndex(const QQmlProperty &that); static int bindingIndex(const QQmlProperty &that);
static int bindingIndex(const QQmlPropertyData &that); static int bindingIndex(const QQmlPropertyData &that);
static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &); static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &);

View File

@ -55,6 +55,7 @@
#include <private/qflagpointer_p.h> #include <private/qflagpointer_p.h>
#include "qqmlcleanup_p.h" #include "qqmlcleanup_p.h"
#include "qqmlnotifier_p.h" #include "qqmlnotifier_p.h"
#include <private/qqmlpropertyindex_p.h>
#include <private/qhashedstring_p.h> #include <private/qhashedstring_p.h>
#include <QtCore/qvarlengtharray.h> #include <QtCore/qvarlengtharray.h>
@ -174,13 +175,7 @@ public:
// Returns the "encoded" index for use with bindings. Encoding is: // Returns the "encoded" index for use with bindings. Encoding is:
// coreIndex | ((valueTypeCoreIndex + 1) << 16) // coreIndex | ((valueTypeCoreIndex + 1) << 16)
inline int encodedIndex() const; inline QQmlPropertyIndex encodedIndex() const;
static int encodeValueTypePropertyIndex(int coreIndex, int valueTypeCoreIndex)
{ return coreIndex | ((valueTypeCoreIndex + 1) << 16); }
static int decodeValueTypePropertyIndex(int index, int *coreIndex = 0) {
if (coreIndex) *coreIndex = index & 0xffff;
return (index >> 16) - 1;
}
union { union {
int propType; // When !NotFullyResolved int propType; // When !NotFullyResolved
@ -557,9 +552,10 @@ int QQmlPropertyRawData::getValueTypeCoreIndex() const
return isValueTypeVirtual()?valueTypeCoreIndex:-1; return isValueTypeVirtual()?valueTypeCoreIndex:-1;
} }
int QQmlPropertyRawData::encodedIndex() const QQmlPropertyIndex QQmlPropertyRawData::encodedIndex() const
{ {
return isValueTypeVirtual()?QQmlPropertyData::encodeValueTypePropertyIndex(coreIndex, valueTypeCoreIndex):coreIndex; return isValueTypeVirtual() ? QQmlPropertyIndex(coreIndex, valueTypeCoreIndex)
: QQmlPropertyIndex(coreIndex);
} }
inline QQmlPropertyData *QQmlPropertyCache::ensureResolved(QQmlPropertyData *p) const inline QQmlPropertyData *QQmlPropertyCache::ensureResolved(QQmlPropertyData *p) const

View File

@ -0,0 +1,133 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QQMLPROPERTYINDEX_P_H
#define QQMLPROPERTYINDEX_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <private/qglobal_p.h>
QT_BEGIN_NAMESPACE
class QQmlPropertyIndex
{
qint32 index;
public:
QQmlPropertyIndex()
{ index = -1; }
static QQmlPropertyIndex fromEncoded(qint32 encodedIndex)
{
QQmlPropertyIndex idx;
idx.index = encodedIndex;
return idx;
}
explicit QQmlPropertyIndex(int coreIndex)
{ index = encode(coreIndex, -1); }
explicit QQmlPropertyIndex(int coreIndex, int valueTypeIndex)
: index(encode(coreIndex, valueTypeIndex))
{}
bool isValid() const
{ return index != -1; }
int coreIndex() const
{
if (index == -1)
return -1;
return index & 0xffff;
}
int valueTypeIndex() const
{
if (index == -1)
return -1;
return (index >> 16) - 1;
}
bool hasValueTypeIndex() const
{
if (index == -1)
return false;
return index >> 16;
}
qint32 toEncoded() const
{ return index; }
int intValue() const
{ return index; }
bool operator==(const QQmlPropertyIndex &other) const
{ return index == other.index; }
bool operator!=(const QQmlPropertyIndex &other) const
{ return !operator==(other); }
private:
static qint32 encode(int coreIndex, int valueTypeIndex)
{
Q_ASSERT(coreIndex >= -1);
Q_ASSERT(coreIndex <= 0xffff);
Q_ASSERT(valueTypeIndex >= -1);
Q_ASSERT(valueTypeIndex < 0xffff);
if (coreIndex == -1)
return -1;
else
return coreIndex | ((valueTypeIndex + 1) << 16);
}
};
QT_END_NAMESPACE
#endif // QQMLPROPERTYINDEX_P_H

View File

@ -52,6 +52,7 @@
// //
#include <private/qtqmlglobal_p.h> #include <private/qtqmlglobal_p.h>
#include <private/qqmlpropertyindex_p.h>
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -68,8 +69,7 @@ public:
private: private:
friend class QQmlInterceptorMetaObject; friend class QQmlInterceptorMetaObject;
int m_coreIndex; QQmlPropertyIndex m_propertyIndex;
int m_valueTypeCoreIndex;
QQmlPropertyValueInterceptor *m_next; QQmlPropertyValueInterceptor *m_next;
}; };

View File

@ -41,7 +41,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, int index) QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, QQmlPropertyIndex index)
: QQmlAbstractBinding(), : QQmlAbstractBinding(),
m_bindings(0) m_bindings(0)
{ {
@ -72,7 +72,7 @@ bool QQmlValueTypeProxyBinding::isValueTypeProxy() const
return true; return true;
} }
QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(int propertyIndex) QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(QQmlPropertyIndex propertyIndex)
{ {
QQmlAbstractBinding *binding = m_bindings.data(); QQmlAbstractBinding *binding = m_bindings.data();
@ -91,7 +91,7 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
QQmlAbstractBinding *lastBinding = 0; QQmlAbstractBinding *lastBinding = 0;
while (binding) { while (binding) {
int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(binding->targetPropertyIndex()); const int valueTypeIndex = binding->targetPropertyIndex().valueTypeIndex();
if (valueTypeIndex != -1 && (mask & (1 << valueTypeIndex))) { if (valueTypeIndex != -1 && (mask & (1 << valueTypeIndex))) {
QQmlAbstractBinding *remove = binding; QQmlAbstractBinding *remove = binding;
remove->setAddedToObject(false); remove->setAddedToObject(false);

View File

@ -58,9 +58,9 @@ QT_BEGIN_NAMESPACE
class QQmlValueTypeProxyBinding : public QQmlAbstractBinding class QQmlValueTypeProxyBinding : public QQmlAbstractBinding
{ {
public: public:
QQmlValueTypeProxyBinding(QObject *o, int coreIndex); QQmlValueTypeProxyBinding(QObject *o, QQmlPropertyIndex coreIndex);
QQmlAbstractBinding *binding(int targetPropertyIndex); QQmlAbstractBinding *binding(QQmlPropertyIndex targetPropertyIndex);
void removeBindings(quint32 mask); void removeBindings(quint32 mask);
virtual void setEnabled(bool, QQmlPropertyData::WriteFlags); virtual void setEnabled(bool, QQmlPropertyData::WriteFlags);

View File

@ -464,7 +464,7 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
QQmlPropertyPrivate::setBinding(newBinding); QQmlPropertyPrivate::setBinding(newBinding);
return; return;
} else { } else {
QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyData::encodeValueTypePropertyIndex(reference->d()->property, pd->coreIndex)); QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyIndex(reference->d()->property, pd->coreIndex));
} }
} }

View File

@ -159,8 +159,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
QQmlData *targetDData = QQmlData::get(target, /*create*/false); QQmlData *targetDData = QQmlData::get(target, /*create*/false);
if (!targetDData) if (!targetDData)
return; return;
int coreIndex; int coreIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex).coreIndex();
QQmlPropertyData::decodeValueTypePropertyIndex(aliasData->encodedMetaPropertyIndex, &coreIndex);
const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
if (!pd) if (!pd)
return; return;
@ -199,10 +198,9 @@ QQmlInterceptorMetaObject::~QQmlInterceptorMetaObject()
} }
void QQmlInterceptorMetaObject::registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor) void QQmlInterceptorMetaObject::registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor)
{ {
interceptor->m_coreIndex = index; interceptor->m_propertyIndex = index;
interceptor->m_valueTypeCoreIndex = valueIndex;
interceptor->m_next = interceptors; interceptor->m_next = interceptors;
interceptors = interceptor; interceptors = interceptor;
} }
@ -223,10 +221,10 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
!(*reinterpret_cast<int*>(a[3]) & QQmlPropertyData::BypassInterceptor)) { !(*reinterpret_cast<int*>(a[3]) & QQmlPropertyData::BypassInterceptor)) {
for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) { for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) {
if (vi->m_coreIndex != id) if (vi->m_propertyIndex.coreIndex() != id)
continue; continue;
int valueIndex = vi->m_valueTypeCoreIndex; const int valueIndex = vi->m_propertyIndex.valueTypeIndex();
int type = QQmlData::get(object)->propertyCache->property(id)->propType; int type = QQmlData::get(object)->propertyCache->property(id)->propType;
if (type != QVariant::Invalid) { if (type != QVariant::Invalid) {
@ -866,8 +864,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (!targetDData) if (!targetDData)
return -1; return -1;
int coreIndex; QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex);
const int valueTypePropertyIndex = QQmlPropertyData::decodeValueTypePropertyIndex(aliasData->encodedMetaPropertyIndex, &coreIndex); int coreIndex = encodedIndex.coreIndex();
const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
// Remove binding (if any) on write // Remove binding (if any) on write
if(c == QMetaObject::WriteProperty) { if(c == QMetaObject::WriteProperty) {
@ -875,7 +874,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) { if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
QQmlData *targetData = QQmlData::get(target); QQmlData *targetData = QQmlData::get(target);
if (targetData && targetData->hasBindingBit(coreIndex)) if (targetData && targetData->hasBindingBit(coreIndex))
QQmlPropertyPrivate::removeBinding(target, aliasData->encodedMetaPropertyIndex); QQmlPropertyPrivate::removeBinding(target, encodedIndex);
} }
} }
@ -1189,8 +1188,11 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex,
if (!*target) if (!*target)
return false; return false;
if (!aliasData->isObjectAlias()) if (!aliasData->isObjectAlias()) {
*valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(aliasData->encodedMetaPropertyIndex, coreIndex); QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex);
*coreIndex = encodedIndex.coreIndex();
*valueTypeIndex = encodedIndex.valueTypeIndex();
}
return true; return true;
} }

View File

@ -97,7 +97,7 @@ public:
QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache); QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache);
~QQmlInterceptorMetaObject(); ~QQmlInterceptorMetaObject();
void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor); void registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor);
static QQmlInterceptorMetaObject *get(QObject *obj); static QQmlInterceptorMetaObject *get(QObject *obj);
@ -106,10 +106,10 @@ public:
// Used by auto-tests for inspection // Used by auto-tests for inspection
QQmlPropertyCache *propertyCache() const { return cache; } QQmlPropertyCache *propertyCache() const { return cache; }
bool intercepts(int coreIndex) const bool intercepts(QQmlPropertyIndex propertyIndex) const
{ {
for (auto it = interceptors; it; it = it->m_next) { for (auto it = interceptors; it; it = it->m_next) {
if (it->m_coreIndex == coreIndex) if (it->m_propertyIndex == propertyIndex)
return true; return true;
} }
return false; return false;

View File

@ -194,7 +194,8 @@ void tst_qqmlproperty::qmlmetaproperty()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1); QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -445,7 +446,8 @@ void tst_qqmlproperty::qmlmetaproperty_object()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1); QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -495,7 +497,8 @@ void tst_qqmlproperty::qmlmetaproperty_object()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -548,7 +551,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1); QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -598,7 +602,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -647,7 +652,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QVERIFY(!sigExprWatcher.wasDeleted()); QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -696,7 +702,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QVERIFY(!sigExprWatcher.wasDeleted()); QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -749,7 +756,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1); QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -799,7 +807,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -852,7 +861,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1); QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -902,7 +912,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted()); QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -951,7 +962,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QVERIFY(!sigExprWatcher.wasDeleted()); QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }
@ -1000,7 +1012,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QVERIFY(!sigExprWatcher.wasDeleted()); QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj; delete obj;
} }