summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/snippets/code/doc_src_properties.cpp1
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc6
-rw-r--r--src/corelib/kernel/qmetaobject.cpp15
-rw-r--r--src/corelib/kernel/qmetaobject.h1
-rw-r--r--src/corelib/kernel/qmetaobject_p.h3
-rw-r--r--src/tools/moc/generator.cpp2
-rw-r--r--src/tools/moc/moc.cpp4
-rw-r--r--src/tools/moc/moc.h1
-rw-r--r--tests/auto/tools/moc/allmocs_baseline_in.json13
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp24
10 files changed, 69 insertions, 1 deletions
diff --git a/src/corelib/doc/snippets/code/doc_src_properties.cpp b/src/corelib/doc/snippets/code/doc_src_properties.cpp
index b72c9d13e1..a67945bbcf 100644
--- a/src/corelib/doc/snippets/code/doc_src_properties.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_properties.cpp
@@ -61,6 +61,7 @@ Q_PROPERTY(type name
[USER bool]
[CONSTANT]
[FINAL])
+ [REQUIRED]
//! [0]
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index 9ef08cce07..680e5598f0 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -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.
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 347fb1eb87..37f5acc5c5 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -3573,6 +3573,21 @@ bool QMetaProperty::isFinal() const
}
/*!
+ \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
Returns \c 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 fcd92afd89..beb85becae 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -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;
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 56e3d6cb44..277109dac4 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -85,7 +85,8 @@ enum PropertyFlags {
User = 0x00100000,
ResolveUser = 0x00200000,
Notify = 0x00400000,
- Revisioned = 0x00800000
+ Revisioned = 0x00800000,
+ Required = 0x01000000,
};
enum MethodFlags {
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 034e846918..8d4fb2efc6 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -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);
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index d7a1af0a18..b562416c31 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -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;
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 5d1ae0ad6d..04814b85a1 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -137,6 +137,7 @@ struct PropertyDef
int revision = 0;
bool constant = false;
bool final = false;
+ bool required = false;
QJsonObject toJson() const;
};
diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json
index 8cb397190c..48cac07012 100644
--- a/tests/auto/tools/moc/allmocs_baseline_in.json
+++ b/tests/auto/tools/moc/allmocs_baseline_in.json
@@ -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",
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 6b202f79a6..0f801fe902 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -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