diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-08-04 12:27:02 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-08-05 07:51:51 +0000 |
commit | edb1c204c3bc9ad01ccf7a8abb0e8a02fd89ed72 (patch) | |
tree | 0531a08e8a6df7af2a49b794852eb3023e82634f | |
parent | 48deab9b69afc8d613e2b22dacd138be7c8c51a8 (diff) |
QML: Change the property data flags into a bit field
This will make it easier in follow-up patches to add or remove flags. It
also shrinks the flags, because each type doesn't need its own bit (as
those are mutually exclusive).
Change-Id: I5ba6de5f330eb20c82aa16b4467ed6c952725979
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator_p.h | 57 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 147 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 259 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 5 |
7 files changed, 274 insertions, 209 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h index fe10085829..557a1364f1 100644 --- a/src/qml/compiler/qqmlpropertycachecreator_p.h +++ b/src/qml/compiler/qqmlpropertycachecreator_p.h @@ -341,8 +341,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj // Set up notify signals for properties - first normal, then alias for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p) { - quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | - QQmlPropertyData::IsVMESignal; + auto flags = QQmlPropertyData::defaultSignalFlags(); QString changedSigName = stringAt(p->nameIndex) + QLatin1String("Changed"); seenSignals.insert(changedSigName); @@ -351,8 +350,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj } for (auto a = obj->aliasesBegin(), end = obj->aliasesEnd(); a != end; ++a) { - quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | - QQmlPropertyData::IsVMESignal; + auto flags = QQmlPropertyData::defaultSignalFlags(); QString changedSigName = stringAt(a->nameIndex) + QLatin1String("Changed"); seenSignals.insert(changedSigName); @@ -402,10 +400,9 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj } } - quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | - QQmlPropertyData::IsVMESignal; + auto flags = QQmlPropertyData::defaultSignalFlags(); if (paramCount) - flags |= QQmlPropertyData::HasArguments; + flags.hasArguments = true; QString signalName = stringAt(s->nameIndex); if (seenSignals.contains(signalName)) @@ -419,7 +416,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj // Dynamic slots for (auto function = objectContainer->objectFunctionsBegin(obj), end = objectContainer->objectFunctionsEnd(obj); function != end; ++function) { - quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction; + auto flags = QQmlPropertyData::defaultSlotFlags(); const QString slotName = stringAt(function->nameIndex); if (seenSignals.contains(slotName)) @@ -429,7 +426,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj QList<QByteArray> parameterNames; for (auto formal = function->formalsBegin(), end = function->formalsEnd(); formal != end; ++formal) { - flags |= QQmlPropertyData::HasArguments; + flags.hasArguments = true; parameterNames << stringAt(*formal).toUtf8(); } @@ -442,16 +439,16 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj int propertyIdx = 0; for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p, ++propertyIdx) { int propertyType = 0; - quint32 propertyFlags = 0; + QQmlPropertyData::Flags propertyFlags; if (p->type == QV4::CompiledData::Property::Var) { propertyType = QMetaType::QVariant; - propertyFlags = QQmlPropertyData::IsVarProperty; + propertyFlags.type = QQmlPropertyData::Flags::VarPropertyType; } else if (p->type < builtinTypeCount) { propertyType = builtinTypes[p->type].metaType; if (p->type == QV4::CompiledData::Property::Variant) - propertyFlags |= QQmlPropertyData::IsQVariant; + propertyFlags.type = QQmlPropertyData::Flags::QVariantType; } else { Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList || p->type == QV4::CompiledData::Property::Custom); @@ -485,13 +482,13 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj } if (p->type == QV4::CompiledData::Property::Custom) - propertyFlags |= QQmlPropertyData::IsQObjectDerived; + propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType; else - propertyFlags |= QQmlPropertyData::IsQList; + propertyFlags.type = QQmlPropertyData::Flags::QListType; } if (!(p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList) - propertyFlags |= QQmlPropertyData::IsWritable; + propertyFlags.isWritable = true; QString propertyName = stringAt(p->nameIndex); @@ -521,7 +518,7 @@ public: private: void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex); - void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, quint32 *propertyFlags); + void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags); void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; @@ -623,7 +620,9 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl } template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, quint32 *propertyFlags) +inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias( + const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, + QQmlPropertyData::Flags *propertyFlags) { const int targetObjectIndex = objectForId(component, alias.targetObjectId); Q_ASSERT(targetObjectIndex >= 0); @@ -634,7 +633,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias bool writable = false; bool resettable = false; - *propertyFlags = QQmlPropertyData::IsAlias; + propertyFlags->isAlias = true; if (alias.aliasToLocalAlias) { auto targetAlias = targetObject.aliasesBegin(); @@ -652,7 +651,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias else *type = typeRef->compilationUnit->metaTypeId; - *propertyFlags |= QQmlPropertyData::IsQObjectDerived; + propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType; } else { int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex(); int valueTypeIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).valueTypeIndex(); @@ -678,27 +677,21 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias *type = QVariant::Int; } else { // Copy type flags - *propertyFlags |= targetProperty->getFlags() & QQmlPropertyData::PropTypeFlagMask; + propertyFlags->copyPropertyTypeFlags(targetProperty->getFlags()); if (targetProperty->isVarProperty()) - *propertyFlags |= QQmlPropertyData::IsQVariant; + propertyFlags->type = QQmlPropertyData::Flags::QVariantType; } } } - if (!(alias.flags & QV4::CompiledData::Property::IsReadOnly) && writable) - *propertyFlags |= QQmlPropertyData::IsWritable; - else - *propertyFlags &= ~QQmlPropertyData::IsWritable; - - if (resettable) - *propertyFlags |= QQmlPropertyData::IsResettable; - else - *propertyFlags &= ~QQmlPropertyData::IsResettable; + propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Property::IsReadOnly) && writable; + propertyFlags->isResettable = resettable; } template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex) +inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache( + const CompiledObject &component, int objectIndex) { const CompiledObject &object = *objectContainer->objectAt(objectIndex); if (!object.aliasCount()) @@ -715,7 +708,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPrope Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); int type = 0; - quint32 propertyFlags = 0; + QQmlPropertyData::Flags propertyFlags; propertyDataForAlias(component, *alias, &type, &propertyFlags); const QString propertyName = objectContainer->stringAt(alias->nameIndex); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index ce0c7bc04a..074d3bf866 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1344,7 +1344,7 @@ static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object, QByteArray methodName = method.name(); for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) { if (methodName == mo->method(ii).name()) { - dummy.setFlags(dummy.getFlags() | QQmlPropertyData::IsOverload); + dummy.setOverload(true); dummy.overrideIndexIsProperty = 0; dummy.overrideIndex = ii; return &dummy; @@ -1865,7 +1865,7 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const const int methodOffset = mo->methodOffset(); for (int ii = d()->index - 1; ii >= methodOffset; --ii) { if (methodName == mo->method(ii).name()) { - method.setFlags(method.getFlags() | QQmlPropertyData::IsOverload); + method.setOverload(true); method.overrideIndexIsProperty = 0; method.overrideIndex = ii; break; diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index c96e5b661d..d4a8b87aaa 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -525,7 +525,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core) const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(pd.propType); Q_ASSERT(valueTypeMetaObject); QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex); - pd.setFlags(pd.getFlags() | QQmlPropertyData::IsValueTypeVirtual); + pd.setAsValueTypeVirtual(); pd.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp); pd.valueTypePropType = vtProp.userType(); pd.valueTypeCoreIndex = valueTypeIndex; @@ -553,7 +553,7 @@ QQmlPropertyData QQmlBinding::getPropertyData() const const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d.propType); Q_ASSERT(valueTypeMetaObject); QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex()); - d.setFlags(d.getFlags() | QQmlPropertyData::IsValueTypeVirtual); + d.setAsValueTypeVirtual(); d.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp); d.valueTypePropType = vtProp.userType(); d.valueTypeCoreIndex = m_targetIndex.valueTypeIndex(); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 260cf9deaa..33f3b96389 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -301,13 +301,12 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) QMetaProperty vtProp = valueTypeMetaObject->property(idx); - Q_ASSERT(QQmlPropertyData::flagsForProperty(vtProp) <= QQmlPropertyData::ValueTypeFlagMask); Q_ASSERT(vtProp.userType() <= 0x0000FFFF); Q_ASSERT(idx <= 0x0000FFFF); object = currentObject; core = *property; - core.setFlags(core.getFlags() | QQmlPropertyData::IsValueTypeVirtual); + core.setAsValueTypeVirtual(); core.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp); core.valueTypePropType = vtProp.userType(); core.valueTypeCoreIndex = idx; @@ -1169,7 +1168,7 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, writeBack->read(object, core.coreIndex); QQmlPropertyData data = core; - data.setFlags(QQmlPropertyData::Flag(core.valueTypeFlags)); + data.setFlags(core.valueTypeFlags); data.coreIndex = core.valueTypeCoreIndex; data.propType = core.valueTypePropType; @@ -1634,7 +1633,7 @@ QQmlPropertyPrivate::saveValueType(const QQmlPropertyData &base, QMetaProperty subProp = subObject->property(subIndex); QQmlPropertyData core = base; - core.setFlags(core.getFlags() | QQmlPropertyData::IsValueTypeVirtual); + core.setAsValueTypeVirtual(); core.valueTypeFlags = QQmlPropertyData::flagsForProperty(subProp); core.valueTypeCoreIndex = subIndex; core.valueTypePropType = subProp.userType(); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index d0bdb1c54f..9ac137a315 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -86,51 +86,45 @@ static QQmlPropertyData::Flags fastFlagsForProperty(const QMetaProperty &p) { QQmlPropertyData::Flags flags; - if (p.isConstant()) - flags |= QQmlPropertyData::IsConstant; - if (p.isWritable()) - flags |= QQmlPropertyData::IsWritable; - if (p.isResettable()) - flags |= QQmlPropertyData::IsResettable; - if (p.isFinal()) - flags |= QQmlPropertyData::IsFinal; + flags.isConstant = p.isConstant(); + flags.isWritable = p.isWritable(); + flags.isResettable = p.isResettable(); + flags.isFinal = p.isFinal(); + if (p.isEnumType()) - flags |= QQmlPropertyData::IsEnumType; + flags.type = QQmlPropertyData::Flags::EnumType; return flags; } // Flags that do depend on the property's QMetaProperty::userType() and thus are slow to // load -static QQmlPropertyData::Flags flagsForPropertyType(int propType, QQmlEngine *engine) +static void flagsForPropertyType(int propType, QQmlEngine *engine, QQmlPropertyData::Flags &flags) { Q_ASSERT(propType != -1); - QQmlPropertyData::Flags flags; - if (propType == QMetaType::QObjectStar) { - flags |= QQmlPropertyData::IsQObjectDerived; + flags.type = QQmlPropertyData::Flags::QObjectDerivedType; } else if (propType == QMetaType::QVariant) { - flags |= QQmlPropertyData::IsQVariant; - } else if (propType < (int)QVariant::UserType) { + flags.type = QQmlPropertyData::Flags::QVariantType; + } else if (propType < static_cast<int>(QVariant::UserType)) { + // nothing to do } else if (propType == qMetaTypeId<QQmlBinding *>()) { - flags |= QQmlPropertyData::IsQmlBinding; + flags.type = QQmlPropertyData::Flags::QmlBindingType; } else if (propType == qMetaTypeId<QJSValue>()) { - flags |= QQmlPropertyData::IsQJSValue; + flags.type = QQmlPropertyData::Flags::QJSValueType; } else if (propType == qMetaTypeId<QQmlV4Handle>()) { - flags |= QQmlPropertyData::IsV4Handle; + flags.type = QQmlPropertyData::Flags::V4HandleType; } else { QQmlMetaType::TypeCategory cat = engine ? QQmlEnginePrivate::get(engine)->typeCategory(propType) : QQmlMetaType::typeCategory(propType); if (cat == QQmlMetaType::Object || QMetaType::typeFlags(propType) & QMetaType::PointerToQObject) - flags |= QQmlPropertyData::IsQObjectDerived; + flags.type = QQmlPropertyData::Flags::QObjectDerivedType; else if (cat == QQmlMetaType::List) - flags |= QQmlPropertyData::IsQList; + flags.type = QQmlPropertyData::Flags::QListType; } - - return flags; } static int metaObjectSignalCount(const QMetaObject *metaObject) @@ -144,7 +138,9 @@ static int metaObjectSignalCount(const QMetaObject *metaObject) QQmlPropertyData::Flags QQmlPropertyData::flagsForProperty(const QMetaProperty &p, QQmlEngine *engine) { - return fastFlagsForProperty(p) | flagsForPropertyType(p.userType(), engine); + auto flags = fastFlagsForProperty(p); + flagsForPropertyType(p.userType(), engine, flags); + return flags; } void QQmlPropertyData::lazyLoad(const QMetaProperty &p) @@ -156,16 +152,16 @@ void QQmlPropertyData::lazyLoad(const QMetaProperty &p) flags = fastFlagsForProperty(p); - int type = p.type(); + int type = static_cast<int>(p.type()); if (type == QMetaType::QObjectStar) { propType = type; - flags |= QQmlPropertyData::IsQObjectDerived; + flags.type = Flags::QObjectDerivedType; } else if (type == QMetaType::QVariant) { propType = type; - flags |= QQmlPropertyData::IsQVariant; + flags.type = Flags::QVariantType; } else if (type == QVariant::UserType || type == -1) { propTypeName = p.typeName(); - flags |= QQmlPropertyData::NotFullyResolved; + flags.notFullyResolved = true; } else { propType = type; } @@ -176,7 +172,8 @@ void QQmlPropertyData::load(const QMetaProperty &p, QQmlEngine *engine) propType = p.userType(); coreIndex = p.propertyIndex(); notifyIndex = QMetaObjectPrivate::signalIndex(p.notifySignal()); - flags = fastFlagsForProperty(p) | flagsForPropertyType(propType, engine); + flags = fastFlagsForProperty(p); + flagsForPropertyType(propType, engine, flags); Q_ASSERT(p.revision() <= Q_INT16_MAX); revision = p.revision(); } @@ -188,23 +185,23 @@ void QQmlPropertyData::load(const QMetaMethod &m) propType = m.returnType(); - flags |= IsFunction; + flags.type = Flags::FunctionType; if (m.methodType() == QMetaMethod::Signal) - flags |= IsSignal; + flags.isSignal = true; else if (m.methodType() == QMetaMethod::Constructor) { - flags |= IsConstructor; + flags.isConstructor = true; propType = QMetaType::QObjectStar; } if (m.parameterCount()) { - flags |= HasArguments; + flags.hasArguments = true; if ((m.parameterCount() == 1) && (m.parameterTypes().first() == "QQmlV4Function*")) { - flags |= IsV4Function; + flags.isV4Function = true; } } if (m.attributes() & QMetaMethod::Cloned) - flags |= IsCloned; + flags.isCloned = true; Q_ASSERT(m.revision() <= Q_INT16_MAX); revision = m.revision(); @@ -215,11 +212,11 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m) coreIndex = m.methodIndex(); propType = QMetaType::Void; arguments = 0; - flags |= IsFunction; + flags.type = Flags::FunctionType; if (m.methodType() == QMetaMethod::Signal) - flags |= IsSignal; + flags.isSignal = true; else if (m.methodType() == QMetaMethod::Constructor) { - flags |= IsConstructor; + flags.isConstructor = true; propType = QMetaType::QObjectStar; } @@ -228,19 +225,19 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m) returnType = "\0"; if ((*returnType != 'v') || (qstrcmp(returnType+1, "oid") != 0)) { propTypeName = returnType; - flags |= NotFullyResolved; + flags.notFullyResolved = true; } const int paramCount = m.parameterCount(); if (paramCount) { - flags |= HasArguments; + flags.hasArguments = true; if ((paramCount == 1) && (m.parameterTypes().first() == "QQmlV4Function*")) { - flags |= IsV4Function; + flags.isV4Function = true; } } if (m.attributes() & QMetaMethod::Cloned) - flags |= IsCloned; + flags.isCloned = true; Q_ASSERT(m.revision() <= Q_INT16_MAX); revision = m.revision(); @@ -342,8 +339,8 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth \a notifyIndex MUST be in the signal index range (see QObjectPrivate::signalIndex()). This is different from QMetaMethod::methodIndex(). */ -void QQmlPropertyCache::appendProperty(const QString &name, - quint32 flags, int coreIndex, int propType, int notifyIndex) +void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags, + int coreIndex, int propType, int notifyIndex) { QQmlPropertyData data; data.propType = propType; @@ -361,8 +358,9 @@ void QQmlPropertyCache::appendProperty(const QString &name, setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index, (old != 0)); } -void QQmlPropertyCache::appendSignal(const QString &name, quint32 flags, int coreIndex, - const int *types, const QList<QByteArray> &names) +void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flags flags, + int coreIndex, const int *types, + const QList<QByteArray> &names) { QQmlPropertyData data; data.propType = QVariant::Invalid; @@ -371,7 +369,7 @@ void QQmlPropertyCache::appendSignal(const QString &name, quint32 flags, int cor data.arguments = 0; QQmlPropertyData handler = data; - handler.flags |= QQmlPropertyData::IsSignalHandler; + handler.flags.isSignalHandler = true; if (types) { int argumentCount = *types; @@ -398,8 +396,8 @@ void QQmlPropertyCache::appendSignal(const QString &name, quint32 flags, int cor setNamedProperty(handlerName, signalHandlerIndex + signalOffset(), signalHandlerIndexCache.data() + signalHandlerIndex, (old != 0)); } -void QQmlPropertyCache::appendMethod(const QString &name, quint32 flags, int coreIndex, - const QList<QByteArray> &names) +void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flags flags, + int coreIndex, const QList<QByteArray> &names) { int argumentCount = names.count(); @@ -457,19 +455,19 @@ void QQmlPropertyCache::setParent(QQmlPropertyCache *newParent) QQmlPropertyCache * QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, - QQmlPropertyData::Flag propertyFlags, - QQmlPropertyData::Flag methodFlags, - QQmlPropertyData::Flag signalFlags) + QQmlPropertyData::Flags propertyFlags, + QQmlPropertyData::Flags methodFlags, + QQmlPropertyData::Flags signalFlags) { return copyAndAppend(metaObject, -1, propertyFlags, methodFlags, signalFlags); } QQmlPropertyCache * QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, - int revision, - QQmlPropertyData::Flag propertyFlags, - QQmlPropertyData::Flag methodFlags, - QQmlPropertyData::Flag signalFlags) + int revision, + QQmlPropertyData::Flags propertyFlags, + QQmlPropertyData::Flags methodFlags, + QQmlPropertyData::Flags signalFlags) { Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4); @@ -486,10 +484,10 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, } void QQmlPropertyCache::append(const QMetaObject *metaObject, - int revision, - QQmlPropertyData::Flag propertyFlags, - QQmlPropertyData::Flag methodFlags, - QQmlPropertyData::Flag signalFlags) + int revision, + QQmlPropertyData::Flags propertyFlags, + QQmlPropertyData::Flags methodFlags, + QQmlPropertyData::Flags signalFlags) { Q_UNUSED(revision); @@ -571,15 +569,13 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, QQmlPropertyData *data = &methodIndexCache[ii - methodIndexCacheStart]; QQmlPropertyData *sigdata = 0; - data->lazyLoad(m); - - if (data->isSignal()) - data->flags |= signalFlags; + if (m.methodType() == QMetaMethod::Signal) + data->flags = signalFlags; else - data->flags |= methodFlags; + data->flags = methodFlags; - if (!dynamicMetaObject) - data->flags |= QQmlPropertyData::IsDirect; + data->lazyLoad(m); + data->flags.isDirect = !dynamicMetaObject; Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX); data->metaObjectOffset = allowedRevisionCache.count() - 1; @@ -587,7 +583,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, if (data->isSignal()) { sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHandlerIndexCacheStart]; *sigdata = *data; - sigdata->flags |= QQmlPropertyData::IsSignalHandler; + sigdata->flags.isSignalHandler = true; } QQmlPropertyData *old = 0; @@ -629,7 +625,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, if (old) { // We only overload methods in the same class, exactly like C++ if (old->isFunction() && old->coreIndex >= methodOffset) - data->flags |= QQmlPropertyData::IsOverload; + data->flags.isOverload = true; data->markAsOverrideOf(old); } @@ -656,11 +652,10 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, QQmlPropertyData *data = &propertyIndexCache[ii - propertyIndexCacheStart]; + data->flags = propertyFlags; data->lazyLoad(p); - data->flags |= propertyFlags; - if (!dynamicMetaObject) - data->flags |= QQmlPropertyData::IsDirect; + data->flags.isDirect = !dynamicMetaObject; Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX); data->metaObjectOffset = allowedRevisionCache.count() - 1; @@ -685,7 +680,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, Q_ASSERT(accessorProperty == 0 || (old == 0 && data->revision == 0)); if (accessorProperty) { - data->flags |= QQmlPropertyData::HasAccessors; + data->flags.hasAccessors = true; data->accessors = accessorProperty->accessors; } else if (old) { data->markAsOverrideOf(old); @@ -721,10 +716,10 @@ void QQmlPropertyCache::resolve(QQmlPropertyData *data) const data->propType = registerResult == -1 ? QMetaType::UnknownType : registerResult; } } - data->flags |= flagsForPropertyType(data->propType, engine->qmlEngine()); + flagsForPropertyType(data->propType, engine->qmlEngine(), data->flags); } - data->flags &= ~QQmlPropertyData::NotFullyResolved; + data->flags.notFullyResolved = false; } void QQmlPropertyCache::updateRecur(const QMetaObject *metaObject) @@ -881,7 +876,7 @@ QString QQmlPropertyData::name(const QMetaObject *metaObject) const if (!metaObject || coreIndex == -1) return QString(); - if (flags & IsFunction) { + if (isFunction()) { QMetaMethod m = metaObject->method(coreIndex); return QString::fromUtf8(m.name().constData()); @@ -896,7 +891,7 @@ void QQmlPropertyData::markAsOverrideOf(QQmlPropertyData *predecessor) overrideIndexIsProperty = !predecessor->isFunction(); overrideIndex = predecessor->coreIndex; - predecessor->flags |= QQmlPropertyData::IsOverridden; + predecessor->flags.isOverridden = true; } QStringList QQmlPropertyCache::propertyNames() const diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 52e0fdc3bd..bc2e338348 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -84,91 +84,96 @@ template <typename T> class QQmlPropertyCacheAliasCreator; class QQmlPropertyRawData { public: - enum Flag { - NoFlags = 0x00000000, - ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask + struct Flags { + enum Types { + OtherType = 0, + FunctionType = 1, // Is an invokable + QObjectDerivedType = 2, // Property type is a QObject* derived type + EnumType = 3, // Property type is an enum + QListType = 4, // Property type is a QML list + QmlBindingType = 5, // Property type is a QQmlBinding* + QJSValueType = 6, // Property type is a QScriptValue + V4HandleType = 7, // Property type is a QQmlV4Handle + VarPropertyType = 8, // Property type is a "var" property of VMEMO + ValueTypeVirtualType = 9, // Property is a value type "virtual" property + QVariantType = 10 // Property is a QVariant + }; // Can apply to all properties, except IsFunction - IsConstant = 0x00000001, // Has CONST flag - IsWritable = 0x00000002, // Has WRITE function - IsResettable = 0x00000004, // Has RESET function - IsAlias = 0x00000008, // Is a QML alias to another property - IsFinal = 0x00000010, // Has FINAL flag - IsOverridden = 0x00000020, // Is overridden by a extension property - IsDirect = 0x00000040, // Exists on a C++ QMetaObject - HasAccessors = 0x00000080, // Has property accessors - - // These are mutualy exclusive - IsFunction = 0x00000100, // Is an invokable - IsQObjectDerived = 0x00000200, // Property type is a QObject* derived type - IsEnumType = 0x00000400, // Property type is an enum - IsQList = 0x00000800, // Property type is a QML list - IsQmlBinding = 0x00001000, // Property type is a QQmlBinding* - IsQJSValue = 0x00002000, // Property type is a QScriptValue - IsV4Handle = 0x00004000, // Property type is a QQmlV4Handle - IsVarProperty = 0x00008000, // Property type is a "var" property of VMEMO - IsValueTypeVirtual = 0x00010000, // Property is a value type "virtual" property - IsQVariant = 0x00020000, // Property is a QVariant + unsigned isConstant : 1; // Has CONST flag + unsigned isWritable : 1; // Has WRITE function + unsigned isResettable : 1; // Has RESET function + unsigned isAlias : 1; // Is a QML alias to another property + unsigned isFinal : 1; // Has FINAL flag + unsigned isOverridden : 1; // Is overridden by a extension property + unsigned isDirect : 1; // Exists on a C++ QMetaObject + unsigned hasAccessors : 1; // Has property accessors + + unsigned type : 4; // stores an entry of Types // Apply only to IsFunctions - IsVMEFunction = 0x00040000, // Function was added by QML - HasArguments = 0x00080000, // Function takes arguments - IsSignal = 0x00100000, // Function is a signal - IsVMESignal = 0x00200000, // Signal was added by QML - IsV4Function = 0x00400000, // Function takes QQmlV4Function* args - IsSignalHandler = 0x00800000, // Function is a signal handler - IsOverload = 0x01000000, // Function is an overload of another function - IsCloned = 0x02000000, // The function was marked as cloned - IsConstructor = 0x04000000, // The function was marked is a constructor + unsigned isVMEFunction : 1; // Function was added by QML + unsigned hasArguments : 1; // Function takes arguments + unsigned isSignal : 1; // Function is a signal + unsigned isVMESignal : 1; // Signal was added by QML + unsigned isV4Function : 1; // Function takes QQmlV4Function* args + unsigned isSignalHandler : 1; // Function is a signal handler + unsigned isOverload : 1; // Function is an overload of another function + unsigned isCloned : 1; // The function was marked as cloned + unsigned isConstructor : 1; // The function was marked is a constructor // Internal QQmlPropertyCache flags - NotFullyResolved = 0x08000000, // True if the type data is to be lazily resolved + unsigned notFullyResolved : 1; // True if the type data is to be lazily resolved - // Flags that are set based on the propType field - PropTypeFlagMask = IsQObjectDerived | IsEnumType | IsQList | IsQmlBinding | IsQJSValue | - IsV4Handle | IsQVariant, + unsigned _padding : 10; // align to 32 bits + + inline Flags(); + inline bool operator==(const Flags &other) const; + inline void copyPropertyTypeFlags(Flags from); }; - Q_DECLARE_FLAGS(Flags, Flag) - Flags getFlags() const { return Flag(flags); } + Flags getFlags() const { return flags; } void setFlags(Flags f) { flags = f; } bool isValid() const { return coreIndex != -1; } - bool isConstant() const { return flags & IsConstant; } - bool isWritable() const { return flags & IsWritable; } - bool isResettable() const { return flags & IsResettable; } - bool isAlias() const { return flags & IsAlias; } - bool isFinal() const { return flags & IsFinal; } - bool isOverridden() const { return flags & IsOverridden; } - bool isDirect() const { return flags & IsDirect; } - bool hasAccessors() const { return flags & HasAccessors; } - bool isFunction() const { return flags & IsFunction; } - bool isQObject() const { return flags & IsQObjectDerived; } - bool isEnum() const { return flags & IsEnumType; } - bool isQList() const { return flags & IsQList; } - bool isQmlBinding() const { return flags & IsQmlBinding; } - bool isQJSValue() const { return flags & IsQJSValue; } - bool isV4Handle() const { return flags & IsV4Handle; } - bool isVarProperty() const { return flags & IsVarProperty; } - bool isValueTypeVirtual() const { return flags & IsValueTypeVirtual; } - bool isQVariant() const { return flags & IsQVariant; } - bool isVMEFunction() const { return flags & IsVMEFunction; } - bool hasArguments() const { return flags & HasArguments; } - bool isSignal() const { return flags & IsSignal; } - bool isVMESignal() const { return flags & IsVMESignal; } - bool isV4Function() const { return flags & IsV4Function; } - bool isSignalHandler() const { return flags & IsSignalHandler; } - bool isOverload() const { return flags & IsOverload; } - bool isCloned() const { return flags & IsCloned; } - bool isConstructor() const { return flags & IsConstructor; } - - bool hasOverride() const { return !(flags & IsValueTypeVirtual) && - !(flags & HasAccessors) && + bool isConstant() const { return flags.isConstant; } + bool isWritable() const { return flags.isWritable; } + void setWritable(bool onoff) { flags.isWritable = onoff; } + bool isResettable() const { return flags.isResettable; } + bool isAlias() const { return flags.isAlias; } + bool isFinal() const { return flags.isFinal; } + bool isOverridden() const { return flags.isOverridden; } + bool isDirect() const { return flags.isDirect; } + bool hasAccessors() const { return flags.hasAccessors; } + bool isFunction() const { return flags.type == Flags::FunctionType; } + bool isQObject() const { return flags.type == Flags::QObjectDerivedType; } + bool isEnum() const { return flags.type == Flags::EnumType; } + bool isQList() const { return flags.type == Flags::QListType; } + bool isQmlBinding() const { return flags.type == Flags::QmlBindingType; } + bool isQJSValue() const { return flags.type == Flags::QJSValueType; } + bool isV4Handle() const { return flags.type == Flags::V4HandleType; } + bool isVarProperty() const { return flags.type == Flags::VarPropertyType; } + bool isValueTypeVirtual() const { return flags.type == Flags::ValueTypeVirtualType; } + void setAsValueTypeVirtual() { flags.type = Flags::ValueTypeVirtualType; } + bool isQVariant() const { return flags.type == Flags::QVariantType; } + bool isVMEFunction() const { return flags.isVMEFunction; } + bool hasArguments() const { return flags.hasArguments; } + bool isSignal() const { return flags.isSignal; } + bool isVMESignal() const { return flags.isVMESignal; } + bool isV4Function() const { return flags.isV4Function; } + bool isSignalHandler() const { return flags.isSignalHandler; } + bool isOverload() const { return flags.isOverload; } + void setOverload(bool onoff) { flags.isOverload = onoff; } + bool isCloned() const { return flags.isCloned; } + bool isConstructor() const { return flags.isConstructor; } + + bool hasOverride() const { return flags.type != Flags::ValueTypeVirtualType && + !(flags.hasAccessors) && overrideIndex >= 0; } - bool hasRevision() const { return !(flags & HasAccessors) && revision != 0; } + bool hasRevision() const { return !(flags.hasAccessors) && revision != 0; } - bool isFullyResolved() const { return !(flags & NotFullyResolved); } + bool isFullyResolved() const { return !flags.notFullyResolved; } // Returns -1 if not a value type virtual property inline int getValueTypeCoreIndex() const; @@ -195,8 +200,6 @@ public: union { struct { // When IsValueTypeVirtual - quint16 valueTypeFlags; // flags of the access property on the value type proxy - // object quint16 valueTypePropType; // The QVariant::Type of access property on the value // type proxy object quint16 valueTypeCoreIndex; // The prop index of the access property on the value @@ -215,12 +218,13 @@ public: }; int coreIndex; + Flags valueTypeFlags; // flags of the access property on the value type proxy + // object private: friend class QQmlPropertyData; friend class QQmlPropertyCache; - quint32 flags; + Flags flags; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags) class QQmlPropertyData : public QQmlPropertyRawData { @@ -272,11 +276,28 @@ public: return true; } + static Flags defaultSignalFlags() + { + Flags f; + f.isSignal = true; + f.type = Flags::FunctionType; + f.isVMESignal = true; + return f; + } + + static Flags defaultSlotFlags() + { + Flags f; + f.type = Flags::FunctionType; + f.isVMEFunction = true; + return f; + } + private: friend class QQmlPropertyCache; void lazyLoad(const QMetaProperty &); void lazyLoad(const QMetaMethod &); - bool notFullyResolved() const { return flags & NotFullyResolved; } + bool notFullyResolved() const { return flags.notFullyResolved; } }; class QQmlPropertyCacheMethodArguments; @@ -295,21 +316,21 @@ public: QQmlPropertyCache *copy(); QQmlPropertyCache *copyAndAppend(const QMetaObject *, - QQmlPropertyData::Flag propertyFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag methodFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag signalFlags = QQmlPropertyData::NoFlags); + QQmlPropertyRawData::Flags propertyFlags = QQmlPropertyData::Flags(), + QQmlPropertyRawData::Flags methodFlags = QQmlPropertyData::Flags(), + QQmlPropertyRawData::Flags signalFlags = QQmlPropertyData::Flags()); QQmlPropertyCache *copyAndAppend(const QMetaObject *, int revision, - QQmlPropertyData::Flag propertyFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag methodFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag signalFlags = QQmlPropertyData::NoFlags); + QQmlPropertyRawData::Flags propertyFlags = QQmlPropertyData::Flags(), + QQmlPropertyRawData::Flags methodFlags = QQmlPropertyData::Flags(), + QQmlPropertyRawData::Flags signalFlags = QQmlPropertyData::Flags()); QQmlPropertyCache *copyAndReserve(int propertyCount, int methodCount, int signalCount); - void appendProperty(const QString &, - quint32 flags, int coreIndex, int propType, int notifyIndex); - void appendSignal(const QString &, quint32, int coreIndex, const int *types = 0, - const QList<QByteArray> &names = QList<QByteArray>()); - void appendMethod(const QString &, quint32 flags, int coreIndex, + void appendProperty(const QString &, QQmlPropertyRawData::Flags flags, int coreIndex, + int propType, int notifyIndex); + void appendSignal(const QString &, QQmlPropertyRawData::Flags, int coreIndex, + const int *types = 0, const QList<QByteArray> &names = QList<QByteArray>()); + void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex, const QList<QByteArray> &names = QList<QByteArray>()); const QMetaObject *metaObject() const; @@ -382,9 +403,9 @@ private: inline QQmlPropertyCache *copy(int reserve); void append(const QMetaObject *, int revision, - QQmlPropertyData::Flag propertyFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag methodFlags = QQmlPropertyData::NoFlags, - QQmlPropertyData::Flag signalFlags = QQmlPropertyData::NoFlags); + QQmlPropertyRawData::Flags propertyFlags = QQmlPropertyRawData::Flags(), + QQmlPropertyRawData::Flags methodFlags = QQmlPropertyData::Flags(), + QQmlPropertyRawData::Flags signalFlags = QQmlPropertyData::Flags()); QQmlPropertyCacheMethodArguments *createArgumentsObject(int count, const QList<QByteArray> &names); @@ -518,6 +539,65 @@ public: int *constructorParameterTypes(int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const; }; +QQmlPropertyRawData::Flags::Flags() + : isConstant(false) + , isWritable(false) + , isResettable(false) + , isAlias(false) + , isFinal(false) + , isOverridden(false) + , isDirect(false) + , hasAccessors(false) + , type(OtherType) + , isVMEFunction(false) + , hasArguments(false) + , isSignal(false) + , isVMESignal(false) + , isV4Function(false) + , isSignalHandler(false) + , isOverload(false) + , isCloned(false) + , isConstructor(false) + , notFullyResolved(false) + , _padding(0) +{} + +bool QQmlPropertyRawData::Flags::operator==(const QQmlPropertyRawData::Flags &other) const +{ + return isConstant == other.isConstant && + isWritable == other.isWritable && + isResettable == other.isResettable && + isAlias == other.isAlias && + isFinal == other.isFinal && + isOverridden == other.isOverridden && + hasAccessors == other.hasAccessors && + type == other.type && + isVMEFunction == other.isVMEFunction && + hasArguments == other.hasArguments && + isSignal == other.isSignal && + isVMESignal == other.isVMESignal && + isV4Function == other.isV4Function && + isSignalHandler == other.isSignalHandler && + isOverload == other.isOverload && + isCloned == other.isCloned && + isConstructor == other.isConstructor && + notFullyResolved == other.notFullyResolved; +} + +void QQmlPropertyRawData::Flags::copyPropertyTypeFlags(QQmlPropertyRawData::Flags from) +{ + switch (from.type) { + case QObjectDerivedType: + case EnumType: + case QListType: + case QmlBindingType: + case QJSValueType: + case V4HandleType: + case QVariantType: + type = from.type; + } +} + QQmlPropertyData::QQmlPropertyData() { propType = 0; @@ -527,7 +607,6 @@ QQmlPropertyData::QQmlPropertyData() overrideIndex = -1; revision = 0; metaObjectOffset = -1; - flags = 0; } QQmlPropertyData::QQmlPropertyData(const QQmlPropertyRawData &d) diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index e39acaf168..a1bf692f19 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -448,11 +448,10 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) QQmlContextData *context = v4->callingQmlContext(); QQmlPropertyData cacheData; - cacheData.setFlags(QQmlPropertyData::IsWritable | - QQmlPropertyData::IsValueTypeVirtual); + cacheData.setWritable(true); + cacheData.setAsValueTypeVirtual(); cacheData.propType = writeBackPropertyType; cacheData.coreIndex = reference->d()->property; - cacheData.valueTypeFlags = 0; cacheData.valueTypeCoreIndex = pd->coreIndex; cacheData.valueTypePropType = property.userType(); |