diff options
author | Robert Griebl <robert.griebl@pelagicore.com> | 2019-01-30 14:48:39 +0100 |
---|---|---|
committer | Dominik Holland <dominik.holland@pelagicore.com> | 2019-02-04 16:27:47 +0000 |
commit | a563101f4627c777070dfe0eedbbc17e220ab648 (patch) | |
tree | d094f2e853417d3e68c92c883147902f966174d8 | |
parent | 5e849a7cd5a15dc2ab0a76a8851c1e7b01f16f88 (diff) |
Add support for isSingleton and isCreatable in the qmltypes type information
Extended the AM-QmlType class info to support trailing tags: at the moment
SINGLETON and UNCREATABLE are supported.
Also added rules to ignore functions and properties starting with '_', since
these are considered to be private in the QML world.
Improved the error handling/dealing with invalid class infos while at it.
Change-Id: Ia68136fe30404e58d808be3a6a04d5f3b9c974c9
Reviewed-by: Dominik Holland <dominik.holland@pelagicore.com>
-rw-r--r-- | src/installer-lib/applicationinstaller.h | 2 | ||||
-rw-r--r-- | src/intent-client-lib/intentclient.h | 2 | ||||
-rw-r--r-- | src/intent-client-lib/intentclientrequest.h | 2 | ||||
-rw-r--r-- | src/intent-server-lib/intent.h | 2 | ||||
-rw-r--r-- | src/intent-server-lib/intentserver.h | 2 | ||||
-rw-r--r-- | src/launcher-lib/qmlapplicationinterface.h | 2 | ||||
-rw-r--r-- | src/manager-lib/abstractcontainer.h | 2 | ||||
-rw-r--r-- | src/manager-lib/abstractruntime.h | 2 | ||||
-rw-r--r-- | src/manager-lib/amnamespace.h | 2 | ||||
-rw-r--r-- | src/manager-lib/application.h | 2 | ||||
-rw-r--r-- | src/manager-lib/applicationipcmanager.h | 2 | ||||
-rw-r--r-- | src/manager-lib/applicationmanager.h | 2 | ||||
-rw-r--r-- | src/manager-lib/notificationmanager.h | 2 | ||||
-rw-r--r-- | src/tools/dumpqmltypes/dumpqmltypes.cpp | 129 | ||||
-rw-r--r-- | src/window-lib/window.h | 2 | ||||
-rw-r--r-- | src/window-lib/windowmanager.h | 2 |
16 files changed, 95 insertions, 64 deletions
diff --git a/src/installer-lib/applicationinstaller.h b/src/installer-lib/applicationinstaller.h index 8f3e85cc..62c8b774 100644 --- a/src/installer-lib/applicationinstaller.h +++ b/src/installer-lib/applicationinstaller.h @@ -65,7 +65,7 @@ class ApplicationInstaller : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "io.qt.ApplicationInstaller") - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationInstaller 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationInstaller 2.0 SINGLETON") // both are const on purpose - these should never change in a running system Q_PROPERTY(bool allowInstallationOfUnsignedPackages READ allowInstallationOfUnsignedPackages CONSTANT) diff --git a/src/intent-client-lib/intentclient.h b/src/intent-client-lib/intentclient.h index 6e1e7314..aa4ed95a 100644 --- a/src/intent-client-lib/intentclient.h +++ b/src/intent-client-lib/intentclient.h @@ -62,7 +62,7 @@ class IntentClientSystemInterface; class IntentClient : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentClient 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentClient 2.0 SINGLETON") public: ~IntentClient() override; diff --git a/src/intent-client-lib/intentclientrequest.h b/src/intent-client-lib/intentclientrequest.h index 41e579d8..ce004c97 100644 --- a/src/intent-client-lib/intentclientrequest.h +++ b/src/intent-client-lib/intentclientrequest.h @@ -56,7 +56,7 @@ class IntentClient; class IntentClientRequest : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentRequest 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager/IntentRequest 2.0 UNCREATABLE") Q_PROPERTY(QUuid requestId READ requestId NOTIFY requestIdChanged) Q_PROPERTY(Direction direction READ direction CONSTANT) diff --git a/src/intent-server-lib/intent.h b/src/intent-server-lib/intent.h index f2c5901b..0de7f4f1 100644 --- a/src/intent-server-lib/intent.h +++ b/src/intent-server-lib/intent.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE_AM class Intent { Q_GADGET - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Intent 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Intent 2.0 UNCREATABLE") Q_PROPERTY(bool valid READ (operator bool)) Q_PROPERTY(QString intentId READ intentId) diff --git a/src/intent-server-lib/intentserver.h b/src/intent-server-lib/intentserver.h index 3f43700a..1bf62ade 100644 --- a/src/intent-server-lib/intentserver.h +++ b/src/intent-server-lib/intentserver.h @@ -64,7 +64,7 @@ typedef QVariantList IntentList; class IntentServer : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/IntentServer 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/IntentServer 2.0 SINGLETON") Q_PROPERTY(IntentList intentList READ intentList NOTIFY intentListChanged) diff --git a/src/launcher-lib/qmlapplicationinterface.h b/src/launcher-lib/qmlapplicationinterface.h index 54fef658..467c3069 100644 --- a/src/launcher-lib/qmlapplicationinterface.h +++ b/src/launcher-lib/qmlapplicationinterface.h @@ -64,7 +64,7 @@ class QmlApplicationInterfaceExtension; class QmlApplicationInterface : public ApplicationInterface { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.Application/ApplicationInterface 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.Application/ApplicationInterface 2.0 UNCREATABLE") public: explicit QmlApplicationInterface(const QString &dbusConnectionName, diff --git a/src/manager-lib/abstractcontainer.h b/src/manager-lib/abstractcontainer.h index 1e198ba8..15e7d1f1 100644 --- a/src/manager-lib/abstractcontainer.h +++ b/src/manager-lib/abstractcontainer.h @@ -100,7 +100,7 @@ signals: class AbstractContainer : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Container 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Container 2.0 UNCREATABLE") Q_PROPERTY(QString controlGroup READ controlGroup WRITE setControlGroup) diff --git a/src/manager-lib/abstractruntime.h b/src/manager-lib/abstractruntime.h index 38089430..8276be47 100644 --- a/src/manager-lib/abstractruntime.h +++ b/src/manager-lib/abstractruntime.h @@ -105,7 +105,7 @@ private: class AbstractRuntime : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Runtime 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Runtime 2.0 UNCREATABLE") Q_PROPERTY(AbstractContainer *container READ container) diff --git a/src/manager-lib/amnamespace.h b/src/manager-lib/amnamespace.h index ae13ef7f..f407da90 100644 --- a/src/manager-lib/amnamespace.h +++ b/src/manager-lib/amnamespace.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE_AM class Am : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Am 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Am 2.0 UNCREATABLE") public: // we cannot use QProcess enums directly, since some supported platforms might diff --git a/src/manager-lib/application.h b/src/manager-lib/application.h index 9d10267d..2ae3b8c9 100644 --- a/src/manager-lib/application.h +++ b/src/manager-lib/application.h @@ -68,7 +68,7 @@ signals: class AbstractApplication : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationObject 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationObject 2.0 UNCREATABLE") Q_PROPERTY(QString id READ id CONSTANT) Q_PROPERTY(QString runtimeName READ runtimeName NOTIFY bulkChange) diff --git a/src/manager-lib/applicationipcmanager.h b/src/manager-lib/applicationipcmanager.h index f2bbdb16..427a6fef 100644 --- a/src/manager-lib/applicationipcmanager.h +++ b/src/manager-lib/applicationipcmanager.h @@ -65,7 +65,7 @@ class Application; class ApplicationIPCManager : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationIPCManager 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationIPCManager 2.0 SINGLETON") public: ~ApplicationIPCManager(); diff --git a/src/manager-lib/applicationmanager.h b/src/manager-lib/applicationmanager.h index 72e60c85..bf620fa6 100644 --- a/src/manager-lib/applicationmanager.h +++ b/src/manager-lib/applicationmanager.h @@ -75,7 +75,7 @@ class ApplicationManager : public QAbstractListModel { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "io.qt.ApplicationManager") - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationManager 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationManager 2.0 SINGLETON") Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool singleProcess READ isSingleProcess CONSTANT) diff --git a/src/manager-lib/notificationmanager.h b/src/manager-lib/notificationmanager.h index 34db90ed..b97d4fa5 100644 --- a/src/manager-lib/notificationmanager.h +++ b/src/manager-lib/notificationmanager.h @@ -57,7 +57,7 @@ class NotificationManager : public QAbstractListModel { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Notifications") - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/NotificationManager 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/NotificationManager 2.0 SINGLETON") Q_PROPERTY(int count READ count NOTIFY countChanged) diff --git a/src/tools/dumpqmltypes/dumpqmltypes.cpp b/src/tools/dumpqmltypes/dumpqmltypes.cpp index e767b7c2..69ddde30 100644 --- a/src/tools/dumpqmltypes/dumpqmltypes.cpp +++ b/src/tools/dumpqmltypes/dumpqmltypes.cpp @@ -133,6 +133,42 @@ static QByteArray qmlTypeForMetaObect(const QMetaObject *mo, int level, bool ind } }; + // parse the AM-QmlType Q_CLASSINFO + QByteArray type; + int revMajor = -1; + int revMinor = -1; + bool isUncreatable = false; + bool isSingleton = false; + + QMetaClassInfo c = mo->classInfo(mo->indexOfClassInfo("AM-QmlType")); + QList<QByteArray> qmlType = QByteArray(c.value()).split(' '); + if (qmlType.size() >= 2) { + type = qmlType.at(0); + QList<QByteArray> rev = qmlType.at(1).split('.'); + if (rev.size() == 2) { + bool ok; + revMajor = rev.at(0).toInt(&ok); + if (!ok) + revMajor = -1; + revMinor = rev.at(1).toInt(&ok); + if (!ok) + revMinor = -1; + } + for (int j = 2; j < qmlType.size(); ++j) { + const QByteArray &tag = qmlType.at(j); + if (tag == "UNCREATABLE") { + isUncreatable = true; + } else if (tag == "SINGLETON") { + isSingleton = true; + } else { + throw Exception("Unknown tag %1 found in AM-QmlType class info in class %2") + .arg(tag).arg(mo->className()); + } + } + } + if (type.isEmpty() || revMajor < 0 || revMinor < 0) + throw Exception("Class %1 has an invalid AM-QmlType class info").arg(mo->className()); + QByteArray str; QByteArray indent1 = QByteArray(level * 4, ' '); QByteArray indent2 = QByteArray((level + 1) * 4, ' '); @@ -141,35 +177,24 @@ static QByteArray qmlTypeForMetaObect(const QMetaObject *mo, int level, bool ind if (indentFirstLine) str.append(indent1); - str = str + "Component {\n"; str = str - + indent2 - + "name: \"" - + stripNamespace(mo->className()) - + "\"\n"; - - if (mo->superClass()) { - str = str - + indent2 - + "prototype: \"" - + stripNamespace(mo->superClass()->className()) - + "\"\n"; - } - - for (int i = mo->classInfoOffset(); i < mo->classInfoCount(); ++i) { - QMetaClassInfo c = mo->classInfo(i); - if (qstrcmp(c.name(), "AM-QmlType") == 0) { - QByteArray type = c.value(); - int rev = type.mid(type.lastIndexOf('.')).toInt(); - - str = str + indent2 + "exports: [ \"" + type + "\" ]\n"; - str = str + indent2 + "exportMetaObjectRevisions: [ " + QByteArray::number(rev) + " ]\n"; - break; - } - } + + "Component {\n" + + indent2 + "name: \"" + stripNamespace(mo->className()) + "\"\n" + + indent2 + "exports: [ \"" + type + " " + + QByteArray::number(revMajor) + "." + QByteArray::number(revMinor) + "\" ]\n" + + indent2 + "exportMetaObjectRevisions: [ 0 ]\n"; + if (mo->superClass()) + str = str + indent2 + "prototype: \"" + stripNamespace(mo->superClass()->className()) + "\"\n"; + if (isSingleton) + str = str + indent2 + "isSingleton: true\n"; + if (isUncreatable) + str = str + indent2 + "isCreatable: false\n"; for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) { QMetaProperty p = mo->property(i); + if (QByteArray(p.name()).startsWith('_')) // ignore "private" + continue; + str = str + indent2 + "Property { name: \"" + p.name() @@ -183,9 +208,9 @@ static QByteArray qmlTypeForMetaObect(const QMetaObject *mo, int level, bool ind for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) { QMetaMethod m = mo->method(i); - - // suppress D-Bus interfaces - if (isupper(m.name().at(0))) + if (m.name().startsWith('_')) // ignore "private" + continue; + if (isupper(m.name().at(0))) // ignore D-Bus interfaces continue; QByteArray methodtype; @@ -199,16 +224,15 @@ static QByteArray qmlTypeForMetaObect(const QMetaObject *mo, int level, bool ind methodtype = "Method"; } - str = str - + indent2 - + methodtype + " {\n" + indent3 + "name: \"" + m.name() + "\"\n"; + str = str + indent2 + methodtype + " {\n" + indent3 + "name: \"" + m.name() + "\"\n"; if (qstrcmp(m.typeName(), "void") != 0) str = str + indent3 + "type: \"" + mapTypeName(m.typeName(), false) + "\"\n"; for (int j = 0; j < m.parameterCount(); ++j) { str = str + indent3 + "Parameter { name: \"" - + m.parameterNames().at(j) + "\"; type: \"" + mapTypeName(m.parameterTypes().at(j), true) + "\";"; + + m.parameterNames().at(j) + "\"; type: \"" + + mapTypeName(m.parameterTypes().at(j), true) + "\";"; if (m.parameterTypes().at(j).endsWith('*')) str += " isPointer: true;"; str = str + " }\n"; @@ -272,29 +296,35 @@ int main(int argc, char **argv) } + // group all metaobjects by import namespace and sanity check the Q_CLASSINFOs QMultiMap<QString, const QMetaObject *> imports; - QVector<QByteArray> sanityCheck; // check for copy&paste errors + QVector<QString> sanityCheck; // check for copy&paste errors for (const auto &mo : all) { - bool foundType = false; - for (int i = mo->classInfoOffset(); (i < mo->classInfoCount()) && !foundType; ++i) { + bool foundClassInfo = false; + for (int i = mo->classInfoOffset(); (i < mo->classInfoCount()); ++i) { QMetaClassInfo c = mo->classInfo(i); if (qstrcmp(c.name(), "AM-QmlType") == 0) { - QByteArray type = c.value(); - QByteArray import = type.left(type.indexOf('/')); - - imports.insert(QString::fromLatin1(import), mo); - foundType = true; - - if (sanityCheck.contains(type)) - throw Exception("Q_CLASSINFO(\"AM-QmlType\", \"%1\") was found multiple times").arg(type); - sanityCheck << type; + if (foundClassInfo) + throw Exception("Class %1 has multiple AM-QmlType class infos").arg(mo->className()); + foundClassInfo = true; + + QString qmlType = qL1S(c.value()); + imports.insert(qmlType.section(qL1C('/'), 0, 0), mo); + + QString typeCheck = qmlType.section(qL1C(' '), 0, 1); + if (sanityCheck.contains(typeCheck)) { + throw Exception("Class %1 duplicates the type %2 already found in another class") + .arg(mo->className()).arg(typeCheck); + } + sanityCheck << typeCheck; } } - if (!foundType) - throw Exception("Missing Q_CLASSINFO(\"AM-QmlType\", \"...\") on class %1").arg(mo->className()); + if (!foundClassInfo) + throw Exception("Class %1 is missing the AM-QmlType class info").arg(mo->className()); } + // go over the import namespaces and dump the metaobjects of each one for (auto it = imports.keyBegin(); it != imports.keyEnd(); ++it) { QString importPath = *it; importPath.replace(qL1C('.'), qL1C('/')); @@ -327,10 +357,11 @@ int main(int argc, char **argv) "// appman-dumpqmltypes\n" "\n" "Module {\n" - " dependencies: []\n"; + " dependencies: [ \"QtQuick.Window 2.${QT_MINOR_VERSION}\", \"QtQuick 2.${QT_MINOR_VERSION}\" ]\n"; const char *footer = "}\n"; - typesOut << header; + typesOut << QByteArray(header).replace("${QT_MINOR_VERSION}", + QByteArray::number(QLibraryInfo::version().minorVersion())); auto mos = imports.values(*it); for (const auto &mo : qAsConst(mos)) @@ -339,7 +370,7 @@ int main(int argc, char **argv) typesOut << footer; } } catch (const Exception &e) { - fprintf(stderr, "%s\n", qPrintable(e.errorString())); + fprintf(stderr, "ERROR: %s\n", qPrintable(e.errorString())); return 1; } return 0; diff --git a/src/window-lib/window.h b/src/window-lib/window.h index a67338e6..a856b4d3 100644 --- a/src/window-lib/window.h +++ b/src/window-lib/window.h @@ -62,7 +62,7 @@ class WindowItem; class Window : public QObject { Q_OBJECT - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Window 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/Window 2.0 UNCREATABLE") Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) Q_PROPERTY(ContentState contentState READ contentState NOTIFY contentStateChanged) diff --git a/src/window-lib/windowmanager.h b/src/window-lib/windowmanager.h index 8cdcc9cd..fbc7f07a 100644 --- a/src/window-lib/windowmanager.h +++ b/src/window-lib/windowmanager.h @@ -70,7 +70,7 @@ class WindowManager : public QAbstractListModel { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "io.qt.WindowManager") - Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/WindowManager 2.0") + Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/WindowManager 2.0 SINGLETON") Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool runningOnDesktop READ isRunningOnDesktop CONSTANT) |