diff options
-rw-r--r-- | src/corelib/doc/snippets/code/doc_src_properties.cpp | 2 | ||||
-rw-r--r-- | src/corelib/doc/snippets/qmetaobject-revision/window.h | 4 | ||||
-rw-r--r-- | src/corelib/doc/src/objectmodel/properties.qdoc | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 11 | ||||
-rw-r--r-- | src/corelib/kernel/qtmetamacros.h | 4 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 88 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 2 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 63 |
8 files changed, 124 insertions, 54 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(); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index a4ee6795c4..be86fc8e21 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -32,6 +32,7 @@ #include <qobject.h> #include <qmetaobject.h> #include <qjsondocument.h> +#include <qversionnumber.h> #include "using-namespaces.h" #include "assign-namespace.h" @@ -1895,12 +1896,14 @@ class VersionTest : public QObject Q_OBJECT Q_PROPERTY(int prop1 READ foo) Q_PROPERTY(int prop2 READ foo REVISION 2) + Q_PROPERTY(int prop514 READ foo REVISION(5, 14)) public: int foo() const { return 0; } Q_INVOKABLE void method1() {} Q_INVOKABLE Q_REVISION(4) void method2() {} + Q_INVOKABLE Q_REVISION(6, 0) void method60() {} enum TestEnum { One, Two }; Q_ENUM(TestEnum); @@ -1909,18 +1912,26 @@ public: public slots: void slot1() {} Q_REVISION(3) void slot2() {} + Q_REVISION(6, 1) void slot61() {} signals: void signal1(); Q_REVISION(5) void signal2(); + Q_REVISION(6, 2) void signal62(); public slots Q_REVISION(6): void slot3() {} void slot4() {} +public slots Q_REVISION(5, 12): + void slot512() {} + signals Q_REVISION(7): void signal3(); void signal4(); + +signals Q_REVISION(5, 15): + void signal515(); }; // If changed, update VersionTest above @@ -1929,12 +1940,14 @@ class VersionTestNotify : public QObject Q_OBJECT Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged) Q_PROPERTY(int prop2 READ foo REVISION 2) + Q_PROPERTY(int prop514 READ foo REVISION(5, 14)) public: int foo() const { return 0; } Q_INVOKABLE void method1() {} Q_INVOKABLE Q_REVISION(4) void method2() {} + Q_INVOKABLE Q_REVISION(6, 0) void method60() {} enum TestEnum { One, Two }; Q_ENUM(TestEnum); @@ -1942,19 +1955,27 @@ public: public slots: void slot1() {} Q_REVISION(3) void slot2() {} + Q_REVISION(6, 1) void slot61() {} signals: void fooChanged(); void signal1(); Q_REVISION(5) void signal2(); + Q_REVISION(6, 2) void signal62(); public slots Q_REVISION(6): void slot3() {} void slot4() {} +public slots Q_REVISION(5, 12): + void slot512() {} + signals Q_REVISION(7): void signal3(); void signal4(); + +signals Q_REVISION(5, 15): + void signal515(); }; template <class T> @@ -1963,32 +1984,58 @@ void tst_Moc::revisions_T() int idx = T::staticMetaObject.indexOfProperty("prop1"); QCOMPARE(T::staticMetaObject.property(idx).revision(), 0); idx = T::staticMetaObject.indexOfProperty("prop2"); - QCOMPARE(T::staticMetaObject.property(idx).revision(), 2); + QCOMPARE(T::staticMetaObject.property(idx).revision(), + QTypeRevision::fromMinorVersion(2).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfProperty("prop514"); + QCOMPARE(T::staticMetaObject.property(idx).revision(), + QTypeRevision::fromVersion(5, 14).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfMethod("method1()"); QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfMethod("method2()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 4); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(4).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfMethod("method60()"); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromVersion(6, 0).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSlot("slot1()"); QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfSlot("slot2()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 3); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(3).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfSlot("slot61()"); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromVersion(6, 1).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSlot("slot3()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 6); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(6).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSlot("slot4()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 6); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(6).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfSlot("slot512()"); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromVersion(5, 12).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSignal("signal1()"); QCOMPARE(T::staticMetaObject.method(idx).revision(), 0); idx = T::staticMetaObject.indexOfSignal("signal2()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 5); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(5).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfSignal("signal62()"); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromVersion(6, 2).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSignal("signal3()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 7); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(7).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfSignal("signal4()"); - QCOMPARE(T::staticMetaObject.method(idx).revision(), 7); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromMinorVersion(7).toEncodedVersion<int>()); + idx = T::staticMetaObject.indexOfSignal("signal515()"); + QCOMPARE(T::staticMetaObject.method(idx).revision(), + QTypeRevision::fromVersion(5, 15).toEncodedVersion<int>()); idx = T::staticMetaObject.indexOfEnumerator("TestEnum"); QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2); |