Introduce Q_PROPERTY attribute REQUIRED
This is meant to correspond to required properties in QML. Change-Id: I2645981e13f7423bc86b48370c165b3cfe2aaa62 Task-number: QTBUG-81561 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
49f143e19c
commit
cb3152086c
@ -61,6 +61,7 @@ Q_PROPERTY(type name
|
||||
[USER bool]
|
||||
[CONSTANT]
|
||||
[FINAL])
|
||||
[REQUIRED]
|
||||
//! [0]
|
||||
|
||||
|
||||
|
@ -144,6 +144,12 @@
|
||||
optimizations in some cases, but is not enforced by moc. Care must be taken
|
||||
never to override a \c FINAL property.
|
||||
|
||||
\li The presence of the \c REQUIRED attribute indicates that the property
|
||||
should be set by a user of the class. This is not enforced by moc, and is
|
||||
mostly useful for classes exposed to QML. In QML, classes with REQUIRED
|
||||
properties cannot be instantiated unless all REQUIRED properties have
|
||||
been set.
|
||||
|
||||
\endlist
|
||||
|
||||
The \c READ, \c WRITE, and \c RESET functions can be inherited.
|
||||
|
@ -3572,6 +3572,21 @@ bool QMetaProperty::isFinal() const
|
||||
return flags & Final;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.15
|
||||
Returns \c true if the property is required; otherwise returns \c false.
|
||||
|
||||
A property is final if the \c{Q_PROPERTY()}'s \c REQUIRED attribute
|
||||
is set.
|
||||
*/
|
||||
bool QMetaProperty::isRequired() const
|
||||
{
|
||||
if (!mobj)
|
||||
return false;
|
||||
int flags = mobj->d.data[handle + 2];
|
||||
return flags & Required;
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
|
||||
|
@ -266,6 +266,7 @@ public:
|
||||
bool isUser(const QObject *obj = nullptr) const;
|
||||
bool isConstant() const;
|
||||
bool isFinal() const;
|
||||
bool isRequired() const;
|
||||
|
||||
bool isFlagType() const;
|
||||
bool isEnumType() const;
|
||||
|
@ -85,7 +85,8 @@ enum PropertyFlags {
|
||||
User = 0x00100000,
|
||||
ResolveUser = 0x00200000,
|
||||
Notify = 0x00400000,
|
||||
Revisioned = 0x00800000
|
||||
Revisioned = 0x00800000,
|
||||
Required = 0x01000000,
|
||||
};
|
||||
|
||||
enum MethodFlags {
|
||||
|
@ -864,6 +864,8 @@ void Generator::generateProperties()
|
||||
flags |= Constant;
|
||||
if (p.final)
|
||||
flags |= Final;
|
||||
if (p.required)
|
||||
flags |= Required;
|
||||
|
||||
fprintf(out, " %4d, ", stridx(p.name));
|
||||
generateTypeInfo(p.type);
|
||||
|
@ -1238,6 +1238,9 @@ void Moc::createPropertyDef(PropertyDef &propDef)
|
||||
} else if(l[0] == 'F' && l == "FINAL") {
|
||||
propDef.final = true;
|
||||
continue;
|
||||
} else if (l[0] == 'R' && l == "REQUIRED") {
|
||||
propDef.required = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray v, v2;
|
||||
@ -1960,6 +1963,7 @@ QJsonObject PropertyDef::toJson() const
|
||||
|
||||
prop[QLatin1String("constant")] = constant;
|
||||
prop[QLatin1String("final")] = final;
|
||||
prop[QLatin1String("required")] = required;
|
||||
|
||||
if (revision > 0)
|
||||
prop[QLatin1String("revision")] = revision;
|
||||
|
@ -137,6 +137,7 @@ struct PropertyDef
|
||||
int revision = 0;
|
||||
bool constant = false;
|
||||
bool final = false;
|
||||
bool required = false;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
};
|
||||
|
@ -275,6 +275,7 @@
|
||||
"final": false,
|
||||
"name": "flags",
|
||||
"read": "flags",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Flags",
|
||||
@ -299,6 +300,7 @@
|
||||
"final": false,
|
||||
"name": "flags",
|
||||
"read": "flags",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Foo::Bar::Flags",
|
||||
@ -311,6 +313,7 @@
|
||||
"final": false,
|
||||
"name": "flagsList",
|
||||
"read": "flagsList",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "QList<Foo::Bar::Flags>",
|
||||
@ -1988,6 +1991,7 @@
|
||||
"final": false,
|
||||
"name": "blah",
|
||||
"read": "blah",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "A::SomeEnum",
|
||||
@ -2088,6 +2092,7 @@
|
||||
"final": false,
|
||||
"name": "blah",
|
||||
"read": "blah",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "A::SomeEnum",
|
||||
@ -2257,6 +2262,7 @@
|
||||
"final": false,
|
||||
"name": "gadgetPoperty",
|
||||
"read": "gadgetPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Gadget::SomeEnum",
|
||||
@ -2268,6 +2274,7 @@
|
||||
"final": false,
|
||||
"name": "objectPoperty",
|
||||
"read": "objectPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Object::SomeEnum",
|
||||
@ -2291,6 +2298,7 @@
|
||||
"final": false,
|
||||
"name": "nestedGadgetPoperty",
|
||||
"read": "nestedGadgetPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Nested::Gadget::SomeEnum",
|
||||
@ -2314,6 +2322,7 @@
|
||||
"final": false,
|
||||
"name": "nestedObjectPoperty",
|
||||
"read": "nestedObjectPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Nested::Object::SomeEnum",
|
||||
@ -2442,6 +2451,7 @@
|
||||
"final": false,
|
||||
"name": "gadgetPoperty",
|
||||
"read": "gadgetPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Gadget::SomeEnum",
|
||||
@ -2453,6 +2463,7 @@
|
||||
"final": false,
|
||||
"name": "objectPoperty",
|
||||
"read": "objectPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Object::SomeEnum",
|
||||
@ -2476,6 +2487,7 @@
|
||||
"final": false,
|
||||
"name": "nestedGadgetPoperty",
|
||||
"read": "nestedGadgetPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Nested::Gadget::SomeEnum",
|
||||
@ -2499,6 +2511,7 @@
|
||||
"final": false,
|
||||
"name": "nestedObjectPoperty",
|
||||
"read": "nestedObjectPoperty",
|
||||
"required": false,
|
||||
"scriptable": true,
|
||||
"stored": true,
|
||||
"type": "Nested::Object::SomeEnum",
|
||||
|
@ -719,6 +719,7 @@ private slots:
|
||||
void cxx17Namespaces();
|
||||
void cxxAttributes();
|
||||
void mocJsonOutput();
|
||||
void requiredProperties();
|
||||
|
||||
signals:
|
||||
void sigWithUnsignedArg(unsigned foo);
|
||||
@ -4025,6 +4026,29 @@ void tst_Moc::mocJsonOutput()
|
||||
QVERIFY2(actualOutput == expectedOutput, showPotentialDiff(actualOutput, expectedOutput).constData());
|
||||
}
|
||||
|
||||
class RequiredTest :public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int required MEMBER m_required REQUIRED)
|
||||
Q_PROPERTY(int notRequired MEMBER m_notRequired)
|
||||
|
||||
private:
|
||||
int m_required;
|
||||
int m_notRequired;
|
||||
};
|
||||
|
||||
void tst_Moc::requiredProperties()
|
||||
{
|
||||
QMetaObject mo = RequiredTest::staticMetaObject;
|
||||
QMetaProperty required = mo.property(mo.indexOfProperty("required"));
|
||||
QVERIFY(required.isValid());
|
||||
QVERIFY(required.isRequired());
|
||||
QMetaProperty notRequired = mo.property(mo.indexOfProperty("notRequired"));
|
||||
QVERIFY(notRequired.isValid());
|
||||
QVERIFY(!notRequired.isRequired());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Moc)
|
||||
|
||||
// the generated code must compile with QT_NO_KEYWORDS
|
||||
|
Loading…
Reference in New Issue
Block a user