summaryrefslogtreecommitdiffstats
path: root/src/tools/moc/moc.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-11-08 16:20:44 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2020-03-18 15:42:58 +0100
commitd4f044533111fcfb34fe3a785eeb7af7fdbefbdd (patch)
tree1b2ef0c8695655e6ee4c1ae5f13a731738d1da96 /src/tools/moc/moc.cpp
parentb5f6a85d2745ab6ac97f593664d255906923e737 (diff)
Add support for exposing public QProperty members in the meta-object system
At the moment this makes the type as well as the setter/getter available through the meta-call as well as the ability to register observers and bindings. Only QProperty members that are annotated with Q_PROPERTY(type name) are made public through the meta-object. Change-Id: I16b98fd318122c722b85ce61e39975284e0c2404 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r--src/tools/moc/moc.cpp69
1 files changed, 63 insertions, 6 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 03976771e5..56db54b457 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -564,6 +564,32 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
return true;
}
+
+// Try to parse QProperty<MyType> propertName; members
+bool Moc::parseMaybeQProperty(ClassDef *def)
+{
+ if (!test(IDENTIFIER))
+ return false;
+
+ if (lexem() != "QProperty")
+ return false;
+
+ if (!test(LANGLE))
+ return false;
+
+ until(RANGLE);
+
+ next();
+ const auto propName = lexem();
+
+ if (!test(SEMIC))
+ return false;
+
+ def->qPropertyMembers.insert(propName);
+
+ return true;
+}
+
void Moc::parse()
{
QVector<NamespaceDef> namespaceList;
@@ -909,7 +935,9 @@ void Moc::parse()
}
}
} else {
- index = rewind;
+ index = rewind - 1;
+ if (!parseMaybeQProperty(&def))
+ index = rewind;
}
}
}
@@ -1198,11 +1226,14 @@ void Moc::parseSignals(ClassDef *def)
void Moc::createPropertyDef(PropertyDef &propDef)
{
+ propDef.location = index;
+
QByteArray type = parseType().name;
if (type.isEmpty())
error();
propDef.designable = propDef.scriptable = propDef.stored = "true";
propDef.user = "false";
+
/*
The Q_PROPERTY construct cannot contain any commas, since
commas separate macro arguments. We therefore expect users
@@ -1234,6 +1265,17 @@ void Moc::createPropertyDef(PropertyDef &propDef)
next();
propDef.name = lexem();
+
+ // Could be Q_PROPERTY(type field) and later QProperty<int> field; -- to be resolved later.
+ if (lookup() == RPAREN) {
+ propDef.isQProperty = true;
+ propDef.designable = propDef.scriptable = propDef.stored = "true";
+ propDef.user = "false";
+ propDef.read = propDef.name + ".value";
+ propDef.write = propDef.name + ".setValue";
+ return;
+ }
+
while (test(IDENTIFIER)) {
const QByteArray l = lexem();
if (l[0] == 'C' && l == "CONSTANT") {
@@ -1320,11 +1362,6 @@ void Moc::createPropertyDef(PropertyDef &propDef)
error(2);
}
}
- if (propDef.read.isNull() && propDef.member.isNull()) {
- const QByteArray msg = "Property declaration " + propDef.name
- + " has no READ accessor function or associated MEMBER variable. The property will be invalid.";
- warning(msg.constData());
- }
if (propDef.constant && !propDef.write.isNull()) {
const QByteArray msg = "Property declaration " + propDef.name
+ " is both WRITEable and CONSTANT. CONSTANT will be ignored.";
@@ -1777,6 +1814,25 @@ void Moc::checkProperties(ClassDef *cdef)
}
definedProperties.insert(p.name);
+ const auto skipProperty = [&](const QByteArray &msg) {
+ const int rewind = index;
+ if (p.location >= 0)
+ index = p.location;
+ warning(msg.constData());
+ index = rewind;
+ cdef->propertyList.removeAt(i);
+ --i;
+ };
+
+ if (p.isQProperty) {
+ if (!cdef->qPropertyMembers.contains(p.name)) {
+ QByteArray msg = "Property declaration " + p.name + " has neither an associated QProperty<> member"
+ ", nor a READ accessor function nor an associated MEMBER variable. The property will be invalid.";
+ skipProperty(msg);
+ break;
+ }
+ }
+
for (int j = 0; j < cdef->publicList.count(); ++j) {
const FunctionDef &f = cdef->publicList.at(j);
if (f.name != p.read)
@@ -1989,6 +2045,7 @@ QJsonObject PropertyDef::toJson() const
prop[QLatin1String("constant")] = constant;
prop[QLatin1String("final")] = final;
prop[QLatin1String("required")] = required;
+ prop[QLatin1String("isQProperty")] = isQProperty;
if (revision > 0)
prop[QLatin1String("revision")] = revision;