summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@pelagicore.com>2019-01-30 14:48:39 +0100
committerDominik Holland <dominik.holland@pelagicore.com>2019-02-04 16:27:47 +0000
commita563101f4627c777070dfe0eedbbc17e220ab648 (patch)
treed094f2e853417d3e68c92c883147902f966174d8
parent5e849a7cd5a15dc2ab0a76a8851c1e7b01f16f88 (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.h2
-rw-r--r--src/intent-client-lib/intentclient.h2
-rw-r--r--src/intent-client-lib/intentclientrequest.h2
-rw-r--r--src/intent-server-lib/intent.h2
-rw-r--r--src/intent-server-lib/intentserver.h2
-rw-r--r--src/launcher-lib/qmlapplicationinterface.h2
-rw-r--r--src/manager-lib/abstractcontainer.h2
-rw-r--r--src/manager-lib/abstractruntime.h2
-rw-r--r--src/manager-lib/amnamespace.h2
-rw-r--r--src/manager-lib/application.h2
-rw-r--r--src/manager-lib/applicationipcmanager.h2
-rw-r--r--src/manager-lib/applicationmanager.h2
-rw-r--r--src/manager-lib/notificationmanager.h2
-rw-r--r--src/tools/dumpqmltypes/dumpqmltypes.cpp129
-rw-r--r--src/window-lib/window.h2
-rw-r--r--src/window-lib/windowmanager.h2
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)