From 7ebd2024f49bdaf798f0beaaa35946dfa890f276 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 16 Jul 2009 12:35:08 +1000 Subject: Add FINAL attribute to Q_PROPERTY() This will be used by the declarative module to optimize property bindings. Reviewed-by: Roberto Raggi --- doc/src/properties.qdoc | 5 +++++ doc/src/snippets/code/doc_src_properties.qdoc | 3 ++- src/corelib/kernel/qmetaobject.cpp | 17 ++++++++++++++++- src/corelib/kernel/qmetaobject.h | 1 + src/tools/moc/generator.cpp | 5 ++++- src/tools/moc/moc.cpp | 3 +++ src/tools/moc/moc.h | 3 ++- tests/auto/qmetaobject/tst_qmetaobject.cpp | 17 +++++++++++++++++ 8 files changed, 50 insertions(+), 4 deletions(-) diff --git a/doc/src/properties.qdoc b/doc/src/properties.qdoc index cac5016..2d03e91 100644 --- a/doc/src/properties.qdoc +++ b/doc/src/properties.qdoc @@ -128,6 +128,11 @@ constant value may be different for different instances of the object. A constant property cannot have a WRTE method or a NOTIFY signal. + \o The presence of the \c FINAL attribute indicates that the property + will not be overridden by a derived class. This can be used for performance + optimizations in some cases, but is not enforced by moc. Care must be taken + never to override a \c FINAL property. + \endlist The \c READ, \c WRITE, and \c RESET functions can be inherited. diff --git a/doc/src/snippets/code/doc_src_properties.qdoc b/doc/src/snippets/code/doc_src_properties.qdoc index 64e5377..3c9109f 100644 --- a/doc/src/snippets/code/doc_src_properties.qdoc +++ b/doc/src/snippets/code/doc_src_properties.qdoc @@ -8,7 +8,8 @@ Q_PROPERTY(type name [SCRIPTABLE bool] [STORED bool] [USER bool] - [CONSTANT]) + [CONSTANT] + [FINAL]) //! [0] diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index fee2da9..3b09061 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -161,7 +161,8 @@ enum PropertyFlags { ResolveUser = 0x00200000, Notify = 0x00400000, Dynamic = 0x00800000, - Constant = 0x00000400 + Constant = 0x00000400, + Final = 0x00000800 }; enum MethodFlags { @@ -2466,6 +2467,20 @@ bool QMetaProperty::isConstant() const } /*! + Returns true if the property is final; otherwise returns false. + + A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute + is set. +*/ +bool QMetaProperty::isFinal() const +{ + if (!mobj) + return false; + int flags = mobj->d.data[handle + 2]; + return flags & Final; +} + +/*! \obsolete Returns true if the property is editable for the given \a object; diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 73b52a9..bd47582 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -189,6 +189,7 @@ public: bool isUser(const QObject *obj = 0) const; bool isDynamic() const; bool isConstant() const; + bool isFinal() const; bool isFlagType() const; bool isEnumType() const; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index e4086e6..fbc434d 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -68,7 +68,8 @@ enum PropertyFlags { ResolveUser = 0x00200000, Notify = 0x00400000, Dynamic = 0x00800000, - Constant = 0x00000400 + Constant = 0x00000400, + Final = 0x00000800 }; enum MethodFlags { AccessPrivate = 0x00, @@ -601,6 +602,8 @@ void Generator::generateProperties() if (p.constant) flags |= Constant; + if (p.final) + flags |= Final; fprintf(out, " %4d, %4d, ", strreg(p.name), diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 66012ca..aa11d0e 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -912,6 +912,9 @@ void Moc::parseProperty(ClassDef *def) if (l[0] == 'C' && l == "CONSTANT") { propDef.constant = true; continue; + } else if(l[0] == 'F' && l == "FINAL") { + propDef.final = true; + continue; } QByteArray v, v2; diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 494d53e..767f84e 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -115,10 +115,11 @@ struct FunctionDef struct PropertyDef { - PropertyDef():notifyId(-1), constant(false), gspec(ValueSpec){} + PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){} QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify; int notifyId; bool constant; + bool final; enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; Specification gspec; bool stdCppSet() const { diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index f4cff2b..ac2858c 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -109,6 +109,7 @@ class tst_QMetaObject : public QObject Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed) Q_PROPERTY(int value8 READ value8 NOTIFY value8Changed) Q_PROPERTY(int value9 READ value9 CONSTANT) + Q_PROPERTY(int value10 READ value10 FINAL) public: enum EnumType { EnumType1 }; @@ -140,6 +141,8 @@ public: int value9() const { return 1; } + int value10() const { return 1; } + QList value4; QVariantList value5; @@ -163,6 +166,7 @@ private slots: void checkScope(); void propertyNotify(); void propertyConstant(); + void propertyFinal(); void stdSet(); void classInfo(); @@ -802,6 +806,19 @@ void tst_QMetaObject::propertyConstant() QVERIFY(prop.isConstant()); } +void tst_QMetaObject::propertyFinal() +{ + const QMetaObject *mo = metaObject(); + + QMetaProperty prop = mo->property(mo->indexOfProperty("value10")); + QVERIFY(prop.isValid()); + QVERIFY(prop.isFinal()); + + prop = mo->property(mo->indexOfProperty("value9")); + QVERIFY(prop.isValid()); + QVERIFY(!prop.isFinal()); +} + class ClassInfoTestObjectA : public QObject { Q_OBJECT -- cgit v0.12