summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-01-16 11:33:41 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-02-07 21:23:55 +0100
commitf64694647a9a3d54fa5ecdaf2570e8c7404271a6 (patch)
tree18a98362d72b210c7672084687b052888faeb053 /src
parent0eb922a4e99da83f5600d36510668dfa002a17aa (diff)
moc: Extend revision markers to allow for major and minor version
As we want Qt's own revisions to follow the Qt versioning scheme, we need to allow for the minor version to reset to 0 now. In order to facilitate this, we interpret the argument passed the current Q_REVISION macro as major version and allow for an optional minor version. Both are encoded it into the resulting revision number. Change-Id: I3519fe20233d473f34a24ec9589d045cdd162a12 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/snippets/code/doc_src_properties.cpp2
-rw-r--r--src/corelib/doc/snippets/qmetaobject-revision/window.h4
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc4
-rw-r--r--src/corelib/kernel/qobject.cpp11
-rw-r--r--src/corelib/kernel/qtmetamacros.h4
-rw-r--r--src/tools/moc/moc.cpp88
-rw-r--r--src/tools/moc/moc.h2
7 files changed, 69 insertions, 46 deletions
diff --git a/src/corelib/doc/snippets/code/doc_src_properties.cpp b/src/corelib/doc/snippets/code/doc_src_properties.cpp
index a67945bbcf..e026a47e23 100644
--- a/src/corelib/doc/snippets/code/doc_src_properties.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_properties.cpp
@@ -54,7 +54,7 @@ Q_PROPERTY(type name
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
- [REVISION int]
+ [REVISION int | REVISION(int[, int])]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
diff --git a/src/corelib/doc/snippets/qmetaobject-revision/window.h b/src/corelib/doc/snippets/qmetaobject-revision/window.h
index f93d253b6b..f519a6f2dc 100644
--- a/src/corelib/doc/snippets/qmetaobject-revision/window.h
+++ b/src/corelib/doc/snippets/qmetaobject-revision/window.h
@@ -58,7 +58,7 @@ class Window : public QWidget
{
Q_OBJECT
Q_PROPERTY(int normalProperty READ normalProperty)
- Q_PROPERTY(int newProperty READ newProperty REVISION 1)
+ Q_PROPERTY(int newProperty READ newProperty REVISION(2, 1))
public:
Window();
@@ -66,7 +66,7 @@ public:
int newProperty();
public slots:
void normalMethod();
- Q_REVISION(1) void newMethod();
+ Q_REVISION(2, 1) void newMethod();
};
//! [Window class with revision]
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index 680e5598f0..abeb9b7a54 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -102,8 +102,8 @@
re-evaluated in QML, for example. Qt emits automatically that signal when
needed for MEMBER properties that do not have an explicit setter.
- \li A \c REVISION number is optional. If included, it defines
- the property and its notifier signal to be used in a particular
+ \li A \c REVISION number or \c REVISION() macro is optional. If included,
+ it defines the property and its notifier signal to be used in a particular
revision of the API (usually for exposure to QML). If not included, it
defaults to 0.
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index c72383ff4a..d452b43ff6 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4674,10 +4674,15 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Using the same Window class as the previous example, the newProperty and
newMethod would only be exposed in this code when the expected version is
- 1 or greater.
+ \c{2.1} or greater.
- Since all methods are considered to be in revision 0 if untagged, a tag
- of Q_REVISION(0) is invalid and ignored.
+ Since all methods are considered to be in revision \c{0} if untagged, a tag
+ of \c{Q_REVISION(0)}, or \c{Q_REVISION(0, 0)} is invalid and ignored.
+
+ You can pass one or two integer parameters to \c{Q_REVISION}. If you pass
+ one, the parameter denotes the minor version and major version is
+ unspecified. If you pass two, the first parameter is the major version and
+ the second parameter is the minor version.
This tag is not used by the meta-object system itself. Currently this is only
used by the QtQml module.
diff --git a/src/corelib/kernel/qtmetamacros.h b/src/corelib/kernel/qtmetamacros.h
index 1d095c0d7c..2dcd6948aa 100644
--- a/src/corelib/kernel/qtmetamacros.h
+++ b/src/corelib/kernel/qtmetamacros.h
@@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
#define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
#ifndef Q_REVISION
-# define Q_REVISION(v)
+# define Q_REVISION(...)
#endif
#define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
#define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
@@ -211,7 +211,7 @@ private: \
#define Q_INTERFACES(x) Q_INTERFACES(x)
#define Q_PROPERTY(text) Q_PROPERTY(text)
#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
-#define Q_REVISION(v) Q_REVISION(v)
+#define Q_REVISION(...) Q_REVISION(__VA_ARGS__)
#define Q_OVERRIDE(text) Q_OVERRIDE(text)
#define Q_ENUMS(x) Q_ENUMS(x)
#define Q_FLAGS(x) Q_FLAGS(x)
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 625725e5a1..5e2e492f94 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -376,17 +376,42 @@ bool Moc::skipCxxAttributes()
return false;
}
-bool Moc::testFunctionRevision(FunctionDef *def)
+QTypeRevision Moc::parseRevision()
{
- if (test(Q_REVISION_TOKEN)) {
- next(LPAREN);
- QByteArray revision = lexemUntil(RPAREN);
- revision.remove(0, 1);
- revision.chop(1);
+ next(LPAREN);
+ QByteArray revisionString = lexemUntil(RPAREN);
+ revisionString.remove(0, 1);
+ revisionString.chop(1);
+ const QList<QByteArray> majorMinor = revisionString.split(',');
+ switch (majorMinor.length()) {
+ case 1: {
bool ok = false;
- def->revision = revision.toInt(&ok);
- if (!ok || def->revision < 0)
+ const int revision = revisionString.toInt(&ok);
+ if (!ok || !QTypeRevision::isValidSegment(revision))
error("Invalid revision");
+ return QTypeRevision::fromMinorVersion(revision);
+ }
+ case 2: { // major.minor
+ bool ok = false;
+ const int major = majorMinor[0].toInt(&ok);
+ if (!ok || !QTypeRevision::isValidSegment(major))
+ error("Invalid major version");
+ const int minor = majorMinor[1].toInt(&ok);
+ if (!ok || !QTypeRevision::isValidSegment(minor))
+ error("Invalid minor version");
+ return QTypeRevision::fromVersion(major, minor);
+ }
+ default:
+ error("Invalid revision");
+ return QTypeRevision();
+ }
+}
+
+bool Moc::testFunctionRevision(FunctionDef *def)
+{
+
+ if (test(Q_REVISION_TOKEN)) {
+ def->revision = parseRevision().toEncodedVersion<int>();
return true;
}
@@ -1100,17 +1125,9 @@ void Moc::generate(FILE *out, FILE *jsonOutput)
void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
{
- int defaultRevision = -1;
- if (test(Q_REVISION_TOKEN)) {
- next(LPAREN);
- QByteArray revision = lexemUntil(RPAREN);
- revision.remove(0, 1);
- revision.chop(1);
- bool ok = false;
- defaultRevision = revision.toInt(&ok);
- if (!ok || defaultRevision < 0)
- error("Invalid revision");
- }
+ QTypeRevision defaultRevision;
+ if (test(Q_REVISION_TOKEN))
+ defaultRevision = parseRevision();
next(COLON);
while (inClass(def) && hasNext()) {
@@ -1139,8 +1156,8 @@ void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
continue;
if (funcDef.revision > 0) {
++def->revisionedMethods;
- } else if (defaultRevision != -1) {
- funcDef.revision = defaultRevision;
+ } else if (defaultRevision.isValid()) {
+ funcDef.revision = defaultRevision.toEncodedVersion<int>();
++def->revisionedMethods;
}
def->slotList += funcDef;
@@ -1154,17 +1171,9 @@ void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
void Moc::parseSignals(ClassDef *def)
{
- int defaultRevision = -1;
- if (test(Q_REVISION_TOKEN)) {
- next(LPAREN);
- QByteArray revision = lexemUntil(RPAREN);
- revision.remove(0, 1);
- revision.chop(1);
- bool ok = false;
- defaultRevision = revision.toInt(&ok);
- if (!ok || defaultRevision < 0)
- error("Invalid revision");
- }
+ QTypeRevision defaultRevision;
+ if (test(Q_REVISION_TOKEN))
+ defaultRevision = parseRevision();
next(COLON);
while (inClass(def) && hasNext()) {
@@ -1195,8 +1204,8 @@ void Moc::parseSignals(ClassDef *def)
error("Not a signal declaration");
if (funcDef.revision > 0) {
++def->revisionedMethods;
- } else if (defaultRevision != -1) {
- funcDef.revision = defaultRevision;
+ } else if (defaultRevision.isValid()) {
+ funcDef.revision = defaultRevision.toEncodedVersion<int>();
++def->revisionedMethods;
}
def->signalList += funcDef;
@@ -1257,6 +1266,10 @@ void Moc::createPropertyDef(PropertyDef &propDef)
} else if (l[0] == 'R' && l == "REQUIRED") {
propDef.required = true;
continue;
+ } else if (l[0] == 'R' && l == "REVISION" && test(LPAREN)) {
+ prev();
+ propDef.revision = parseRevision().toEncodedVersion<int>();
+ continue;
}
QByteArray v, v2;
@@ -1289,9 +1302,10 @@ void Moc::createPropertyDef(PropertyDef &propDef)
propDef.reset = v + v2;
else if (l == "REVISION") {
bool ok = false;
- propDef.revision = v.toInt(&ok);
- if (!ok || propDef.revision < 0)
+ const int minor = v.toInt(&ok);
+ if (!ok || !QTypeRevision::isValidSegment(minor))
error(1);
+ propDef.revision = QTypeRevision::fromMinorVersion(minor).toEncodedVersion<int>();
} else
error(2);
break;
@@ -1499,6 +1513,8 @@ void Moc::parseClassInfo(BaseDef *def)
next(COMMA);
if (test(STRING_LITERAL)) {
infoDef.value = symbol().unquotedLexem();
+ } else if (test(Q_REVISION_TOKEN)) {
+ infoDef.value = QByteArray::number(parseRevision().toEncodedVersion<quint16>());
} else {
// support Q_CLASSINFO("help", QT_TR_NOOP("blah"))
next(IDENTIFIER);
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 4d3d32a6ac..63caf36d61 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -36,6 +36,7 @@
#include <qjsondocument.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
+#include <qversionnumber.h>
#include <stdio.h>
#include <ctype.h>
@@ -271,6 +272,7 @@ public:
bool testFunctionAttribute(FunctionDef *def);
bool testFunctionAttribute(Token tok, FunctionDef *def);
bool testFunctionRevision(FunctionDef *def);
+ QTypeRevision parseRevision();
bool skipCxxAttributes();