diff options
author | Albert Astals Cid <albert.astals@canonical.com> | 2017-03-10 13:14:19 +0100 |
---|---|---|
committer | Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> | 2017-05-23 11:11:52 +0000 |
commit | 2ca187caa383ddc0cdebeb1dbc312405c8c871ad (patch) | |
tree | 70de643261bb96fd2350b9129d281a780bdbe6b6 /src/tools | |
parent | f437fb2934e56c293039dc3b00410c53596f9c3e (diff) |
moc: Allow NOTIFY signals defined in parent classes
Limitation is that the signal needs to be parameter-less
[ChangeLog][moc] moc now supports NOTIFY signals of parent classes in Q_PROPERTY
Change-Id: Iad64c96c3ec65d4be8ad9ff1a9f889938ab9bf45
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Brett Stottlemyer <bstottle@ford.com>
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/moc/generator.cpp | 33 | ||||
-rw-r--r-- | src/tools/moc/generator.h | 1 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 10 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 3 |
4 files changed, 40 insertions, 7 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index c4184929ef..0b45776b88 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -218,6 +218,7 @@ void Generator::generateCode() registerFunctionStrings(cdef->slotList); registerFunctionStrings(cdef->methodList); registerFunctionStrings(cdef->constructorList); + registerByteArrayVector(cdef->nonClassSignalList); registerPropertyStrings(); registerEnumStrings(); @@ -603,6 +604,19 @@ void Generator::generateCode() // Generate plugin meta data // generatePluginMetaData(); + +// +// Generate function to make sure the non-class signals exist in the parent classes +// + if (!cdef->nonClassSignalList.isEmpty()) { + fprintf(out, "// If you get a compile error in this function it can be because either\n"); + fprintf(out, "// a) You are using a NOTIFY signal that does not exist. Fix it.\n"); + fprintf(out, "// b) You are using a NOTIFY signal that does exist (in a parent class) but has a non-empty parameter list. This is a moc limitation.\n"); + fprintf(out, "Q_DECL_UNUSED static void checkNotifySignalValidity_%s(%s *t) {\n", qualifiedClassNameIdentifier.constData(), cdef->qualified.constData()); + for (const QByteArray &nonClassSignal : cdef->nonClassSignalList) + fprintf(out, " t->%s();\n", nonClassSignal.constData()); + fprintf(out, "}\n"); + } } @@ -648,6 +662,12 @@ void Generator::registerFunctionStrings(const QVector<FunctionDef>& list) } } +void Generator::registerByteArrayVector(const QVector<QByteArray> &list) +{ + for (const QByteArray &ba : list) + strreg(ba); +} + void Generator::generateFunctions(const QVector<FunctionDef>& list, const char *functype, int type, int ¶msIndex) { if (list.isEmpty()) @@ -841,12 +861,17 @@ void Generator::generateProperties() fprintf(out, "\n // properties: notify_signal_id\n"); for (int i = 0; i < cdef->propertyList.count(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); - if(p.notifyId == -1) + if (p.notifyId == -1) { fprintf(out, " %4d,\n", 0); - else + } else if (p.notifyId > -1) { fprintf(out, " %4d,\n", p.notifyId); + } else { + const int indexInStrings = strings.indexOf(p.notify); + fprintf(out, " %4d,\n", + indexInStrings | IsUnresolvedSignal); + } } } if (cdef->revisionedProperties) { @@ -1401,13 +1426,15 @@ void Generator::generateStaticMetacall() 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) { + if (!p.notify.isEmpty() && p.notifyId > -1) { const FunctionDef &f = cdef->signalList.at(p.notifyId); if (f.arguments.size() == 0) fprintf(out, " Q_EMIT _t->%s();\n", p.notify.constData()); else if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type) fprintf(out, " Q_EMIT _t->%s(%s%s);\n", p.notify.constData(), prefix.constData(), p.member.constData()); + } else if (!p.notify.isEmpty() && p.notifyId < -1) { + fprintf(out, " Q_EMIT _t->%s();\n", p.notify.constData()); } fprintf(out, " }\n"); fprintf(out, " break;\n"); diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index 3833148fb3..8b80138302 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -46,6 +46,7 @@ private: void registerClassInfoStrings(); void generateClassInfos(); void registerFunctionStrings(const QVector<FunctionDef> &list); + void registerByteArrayVector(const QVector<QByteArray> &list); void generateFunctions(const QVector<FunctionDef> &list, const char *functype, int type, int ¶msIndex); void generateFunctionRevisions(const QVector<FunctionDef> &list, const char *functype); void generateFunctionParameters(const QVector<FunctionDef> &list, const char *functype); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 36d84a61d8..f7de57fae3 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -1727,9 +1727,13 @@ void Moc::checkProperties(ClassDef *cdef) } p.notifyId = notifyId; if (notifyId == -1) { - QByteArray msg = "NOTIFY signal '" + p.notify + "' of property '" + p.name - + "' does not exist in class " + cdef->classname + "."; - error(msg.constData()); + int index = cdef->nonClassSignalList.indexOf(p.notify); + if (index == -1) { + cdef->nonClassSignalList << p.notify; + p.notifyId = -1 - cdef->nonClassSignalList.count(); + } else { + p.notifyId = -2 - index; + } } } } diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 6040f944f3..5f8cdfcf2c 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -121,7 +121,7 @@ struct PropertyDef { PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){} QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass; - int notifyId; + int notifyId; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class bool constant; bool final; enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; @@ -179,6 +179,7 @@ struct ClassDef : BaseDef { QVector<FunctionDef> constructorList; QVector<FunctionDef> signalList, slotList, methodList, publicList; + QVector<QByteArray> nonClassSignalList; int notifyableProperties = 0; QVector<PropertyDef> propertyList; int revisionedMethods = 0; |