summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
diff options
context:
space:
mode:
authorGerhard Gappmeier <gerhard.gappmeier@ascolab.com>2012-07-02 13:01:32 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-19 17:36:55 +0100
commit9bbebb914422262b7b585b6d1dab9d21c4238c44 (patch)
tree65a87988bb8d2d8bae3e81bbff2dce480f436435 /src/tools/moc
parent6f225b0b5d774828df310948435f1cc3a4720104 (diff)
Add support for defining properties from member variables.
This associates properties with member variables and avoids writing getter and setter methods manually. The metaCall() method directly accesses the member variable, so additional method calls can be avoided. The metaCall() setter code also supports NOTIFY signals, which means the according signal is emitted when the property gets written. Task-number: QTBUG-16852 Change-Id: I88a1f237ea53a1e9cf65fc9ef2e207718eb8b6c3 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/tools/moc')
-rw-r--r--src/tools/moc/generator.cpp37
-rw-r--r--src/tools/moc/moc.cpp12
-rw-r--r--src/tools/moc/moc.h2
3 files changed, 40 insertions, 11 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 06efd77adc..083b095094 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -719,7 +719,9 @@ void Generator::generateProperties()
uint flags = Invalid;
if (!isBuiltinType(p.type))
flags |= EnumOrFlag;
- if (!p.read.isEmpty())
+ if (!p.member.isEmpty() && !p.constant)
+ flags |= Writable;
+ if (!p.read.isEmpty() || !p.member.isEmpty())
flags |= Readable;
if (!p.write.isEmpty()) {
flags |= Writable;
@@ -893,12 +895,12 @@ void Generator::generateMetacall()
bool needUser = false;
for (int i = 0; i < cdef->propertyList.size(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
- needGet |= !p.read.isEmpty();
+ needGet |= !p.read.isEmpty() || !p.member.isEmpty();
if (!p.read.isEmpty())
needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec
&& p.gspec != PropertyDef::ReferenceSpec);
- needSet |= !p.write.isEmpty();
+ needSet |= !p.write.isEmpty() || (!p.member.isEmpty() && !p.constant);
needReset |= !p.reset.isEmpty();
needDesignable |= p.designable.endsWith(')');
needScriptable |= p.scriptable.endsWith(')');
@@ -917,7 +919,7 @@ void Generator::generateMetacall()
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
- if (p.read.isEmpty())
+ if (p.read.isEmpty() && p.member.isEmpty())
continue;
QByteArray prefix;
if (p.inPrivateClass.size()) {
@@ -933,9 +935,12 @@ void Generator::generateMetacall()
else if (cdef->enumDeclarations.value(p.type, false))
fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
propindex, prefix.constData(), p.read.constData());
- else
+ else if (!p.read.isEmpty())
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
propindex, p.type.constData(), prefix.constData(), p.read.constData());
+ else
+ fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n",
+ propindex, p.type.constData(), prefix.constData(), p.member.constData());
}
fprintf(out, " }\n");
}
@@ -952,7 +957,9 @@ void Generator::generateMetacall()
fprintf(out, " switch (_id) {\n");
for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
const PropertyDef &p = cdef->propertyList.at(propindex);
- if (p.write.isEmpty())
+ if (p.constant)
+ continue;
+ if (p.write.isEmpty() && p.member.isEmpty())
continue;
QByteArray prefix;
if (p.inPrivateClass.size()) {
@@ -962,9 +969,25 @@ void Generator::generateMetacall()
if (cdef->enumDeclarations.value(p.type, false)) {
fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
propindex, prefix.constData(), p.write.constData());
- } else {
+ } else if (!p.write.isEmpty()) {
fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
propindex, prefix.constData(), p.write.constData(), p.type.constData());
+ } else {
+ fprintf(out, " case %d:\n", propindex);
+ fprintf(out, " if (%s%s != *reinterpret_cast< %s*>(_v)) {\n",
+ prefix.constData(), p.member.constData(), p.type.constData());
+ fprintf(out, " %s%s = *reinterpret_cast< %s*>(_v);\n",
+ prefix.constData(), p.member.constData(), p.type.constData());
+ if (!p.notify.isEmpty() && p.notifyId != -1) {
+ const FunctionDef &f = cdef->signalList.at(p.notifyId);
+ if (f.arguments.size() == 0)
+ fprintf(out, " emit %s();\n", p.notify.constData());
+ else if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type)
+ fprintf(out, " emit %s(%s%s);\n",
+ p.notify.constData(), prefix.constData(), p.member.constData());
+ }
+ fprintf(out, " }\n");
+ fprintf(out, " break;\n");
}
}
fprintf(out, " }\n");
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 5fbbd57c22..788033800f 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -1059,6 +1059,12 @@ void Moc::createPropertyDef(PropertyDef &propDef)
v2 = "()";
}
switch (l[0]) {
+ case 'M':
+ if (l == "MEMBER")
+ propDef.member = v;
+ else
+ error(2);
+ break;
case 'R':
if (l == "READ")
propDef.read = v;
@@ -1099,11 +1105,11 @@ void Moc::createPropertyDef(PropertyDef &propDef)
error(2);
}
}
- if (propDef.read.isNull()) {
+ if (propDef.read.isNull() && propDef.member.isNull()) {
QByteArray msg;
msg += "Property declaration ";
msg += propDef.name;
- msg += " has no READ accessor function. The property will be invalid.";
+ msg += " has no READ accessor function or associated MEMBER variable. The property will be invalid.";
warning(msg.constData());
}
if (propDef.constant && !propDef.write.isNull()) {
@@ -1515,7 +1521,7 @@ void Moc::checkProperties(ClassDef *cdef)
//
for (int i = 0; i < cdef->propertyList.count(); ++i) {
PropertyDef &p = cdef->propertyList[i];
- if (p.read.isEmpty())
+ if (p.read.isEmpty() && p.member.isEmpty())
continue;
for (int j = 0; j < cdef->publicList.count(); ++j) {
const FunctionDef &f = cdef->publicList.at(j);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 07f8c7c620..cfa56c4da2 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -127,7 +127,7 @@ struct FunctionDef
struct PropertyDef
{
PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){}
- QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
+ QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
int notifyId;
bool constant;
bool final;