summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIevgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>2023-06-30 17:02:37 +0200
committerIevgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>2023-07-06 21:51:15 +0200
commit2e8a48c1cdc8547ec47f097a41dd53c641715b77 (patch)
treea02f7aaaf06318600e5d96f7f52b2a5f948ef1e0
parentd625b9bc47c05a83e2fd52e70ba0ee26b20bdb26 (diff)
QDBusIntrospection: Add Annotation struct
Add a structure for annotation data containing name, value and location information. This is done to be able to emit diagnostics related to annotations that include source location. Task-number: QTBUG-2597 Change-Id: Ie990bcd0a16752b5f44f4314f8d730dd1b1a30b4 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/dbus/qdbusintrospection_p.h15
-rw-r--r--src/dbus/qdbusmetaobject.cpp8
-rw-r--r--src/dbus/qdbusxmlparser.cpp16
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp47
-rw-r--r--tests/auto/dbus/qdbusmarshall/common.h6
-rw-r--r--tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp20
6 files changed, 70 insertions, 42 deletions
diff --git a/src/dbus/qdbusintrospection_p.h b/src/dbus/qdbusintrospection_p.h
index 209d1386ae..38a7d5cc66 100644
--- a/src/dbus/qdbusintrospection_p.h
+++ b/src/dbus/qdbusintrospection_p.h
@@ -38,9 +38,10 @@ public:
struct Interface;
struct Object;
struct ObjectTree;
+ struct Annotation;
// typedefs
- typedef QMap<QString, QString> Annotations;
+ typedef QMap<QString, Annotation> Annotations;
typedef QList<Argument> Arguments;
typedef QMultiMap<QString, Method> Methods;
typedef QMultiMap<QString, Signal> Signals;
@@ -116,6 +117,18 @@ public:
annotations == other.annotations && type == other.type; }
};
+ struct Annotation
+ {
+ SourceLocation location;
+ QString name;
+ QString value;
+
+ inline bool operator==(const Annotation &other) const
+ {
+ return name == other.name && value == other.value;
+ }
+ };
+
struct Interface: public QSharedData
{
SourceLocation location;
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index 2e367e63ac..543b185df9 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -148,7 +148,8 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
.arg(id);
// extract from annotations:
- QByteArray typeName = annotations.value(annotationName).toLatin1();
+ auto annotation = annotations.value(annotationName);
+ QByteArray typeName = annotation.value.toLatin1();
// verify that it's a valid one
if (typeName.isEmpty()) {
@@ -158,7 +159,8 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
annotationName += QString::fromLatin1(".%1%2")
.arg(QLatin1StringView(direction))
.arg(id);
- typeName = annotations.value(annotationName).toLatin1();
+ annotation = annotations.value(annotationName);
+ typeName = annotation.value.toLatin1();
}
if (!typeName.isEmpty()) {
@@ -269,7 +271,7 @@ void QDBusMetaObjectGenerator::parseMethods()
prototype.append(')');
// check the async tag
- if (m.annotations.value(ANNOTATION_NO_WAIT ""_L1) == "true"_L1)
+ if (m.annotations.value(ANNOTATION_NO_WAIT ""_L1).value == "true"_L1)
mm.tag = "Q_NOREPLY";
// meta method flags
diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp
index 8769e0ae5e..7636ba365a 100644
--- a/src/dbus/qdbusxmlparser.cpp
+++ b/src/dbus/qdbusxmlparser.cpp
@@ -68,19 +68,23 @@ bool QDBusXmlParser::parseAnnotation(QDBusIntrospection::Annotations &annotation
Q_ASSERT(m_currentInterface);
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "annotation"_L1);
+ QDBusIntrospection::Annotation annotation;
+ annotation.location = m_currentLocation;
+
const QXmlStreamAttributes attributes = m_xml.attributes();
- const QString name = attributes.value("name"_L1).toString();
+ annotation.name = attributes.value("name"_L1).toString();
- if (!QDBusUtil::isValidInterfaceName(name)) {
+ if (!QDBusUtil::isValidInterfaceName(annotation.name)) {
qDBusParserError("Invalid D-Bus annotation '%s' found while parsing introspection",
- qPrintable(name));
+ qPrintable(annotation.name));
return false;
}
- const QString value = attributes.value("value"_L1).toString();
- annotations.insert(name, value);
+ annotation.value = attributes.value("value"_L1).toString();
+ annotations.insert(annotation.name, annotation);
if (!interfaceAnnotation)
m_currentInterface->introspection += " "_L1;
- m_currentInterface->introspection += " <annotation value=\""_L1 + value.toHtmlEscaped() + "\" name=\""_L1 + name + "\"/>\n"_L1;
+ m_currentInterface->introspection += " <annotation value=\""_L1
+ + annotation.value.toHtmlEscaped() + "\" name=\""_L1 + annotation.name + "\"/>\n"_L1;
return true;
}
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index 2c4fe3652a..171491dfbd 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -235,14 +235,16 @@ static QByteArray qtTypeName(const QString &where, const QString &signature,
QString annotationName = u"org.qtproject.QtDBus.QtTypeName"_s;
if (paramId >= 0)
annotationName += ".%1%2"_L1.arg(QLatin1StringView(direction)).arg(paramId);
- QString qttype = annotations.value(annotationName);
+ auto annotation = annotations.value(annotationName);
+ QString qttype = annotation.value;
if (!qttype.isEmpty())
return std::move(qttype).toLatin1();
QString oldAnnotationName = u"com.trolltech.QtDBus.QtTypeName"_s;
if (paramId >= 0)
oldAnnotationName += ".%1%2"_L1.arg(QLatin1StringView(direction)).arg(paramId);
- qttype = annotations.value(oldAnnotationName);
+ annotation = annotations.value(oldAnnotationName);
+ qttype = annotation.value;
if (qttype.isEmpty()) {
fprintf(stderr, "%s: Got unknown type `%s' processing '%s'\n",
@@ -372,47 +374,47 @@ static void writeSignalArgList(QTextStream &ts, const QStringList &argNames,
static QString propertyGetter(const QDBusIntrospection::Property &property)
{
- QString getter = property.annotations.value("org.qtproject.QtDBus.PropertyGetter"_L1);
- if (!getter.isEmpty())
- return getter;
+ auto annotation = property.annotations.value("org.qtproject.QtDBus.PropertyGetter"_L1);
+ if (!annotation.value.isEmpty())
+ return annotation.value;
- getter = property.annotations.value("com.trolltech.QtDBus.propertyGetter"_L1);
- if (!getter.isEmpty()) {
+ annotation = property.annotations.value("com.trolltech.QtDBus.propertyGetter"_L1);
+ if (!annotation.value.isEmpty()) {
fprintf(stderr, "%s: Warning: deprecated annotation 'com.trolltech.QtDBus.propertyGetter' found"
" while processing '%s';"
" suggest updating to 'org.qtproject.QtDBus.PropertyGetter'\n",
PROGRAMNAME, qPrintable(inputFile));
- return getter;
+ return annotation.value;
}
- getter = property.name;
+ QString getter = property.name;
getter[0] = getter[0].toLower();
return getter;
}
static QString propertySetter(const QDBusIntrospection::Property &property)
{
- QString setter = property.annotations.value("org.qtproject.QtDBus.PropertySetter"_L1);
- if (!setter.isEmpty())
- return setter;
+ auto annotation = property.annotations.value("org.qtproject.QtDBus.PropertySetter"_L1);
+ if (!annotation.value.isEmpty())
+ return annotation.value;
- setter = property.annotations.value("com.trolltech.QtDBus.propertySetter"_L1);
- if (!setter.isEmpty()) {
+ annotation = property.annotations.value("com.trolltech.QtDBus.propertySetter"_L1);
+ if (!annotation.value.isEmpty()) {
fprintf(stderr, "%s: Warning: deprecated annotation 'com.trolltech.QtDBus.propertySetter' found"
" while processing '%s';"
" suggest updating to 'org.qtproject.QtDBus.PropertySetter'\n",
PROGRAMNAME, qPrintable(inputFile));
- return setter;
+ return annotation.value;
}
- setter = "set"_L1 + property.name;
+ QString setter = "set"_L1 + property.name;
setter[3] = setter[3].toUpper();
return setter;
}
static QString methodName(const QDBusIntrospection::Method &method)
{
- QString name = method.annotations.value(u"org.qtproject.QtDBus.MethodName"_s);
+ QString name = method.annotations.value(u"org.qtproject.QtDBus.MethodName"_s).value;
if (!name.isEmpty())
return name;
@@ -588,9 +590,9 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// methods:
hs << "public Q_SLOTS: // METHODS\n";
for (const QDBusIntrospection::Method &method : interface->methods) {
- bool isDeprecated = method.annotations.value("org.freedesktop.DBus.Deprecated"_L1) == "true"_L1;
- bool isNoReply =
- method.annotations.value(ANNOTATION_NO_WAIT ""_L1) == "true"_L1;
+ bool isDeprecated = method.annotations.value("org.freedesktop.DBus.Deprecated"_L1).value
+ == "true"_L1;
+ bool isNoReply = method.annotations.value(ANNOTATION_NO_WAIT ""_L1).value == "true"_L1;
if (isNoReply && !method.outputArgs.isEmpty()) {
fprintf(stderr, "%s: warning while processing '%s': method %s in interface %s is marked 'no-reply' but has output arguments.\n",
PROGRAMNAME, qPrintable(inputFile), qPrintable(method.name),
@@ -687,7 +689,7 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
hs << "Q_SIGNALS: // SIGNALS\n";
for (const QDBusIntrospection::Signal &signal : interface->signals_) {
hs << " ";
- if (signal.annotations.value("org.freedesktop.DBus.Deprecated"_L1) == "true"_L1)
+ if (signal.annotations.value("org.freedesktop.DBus.Deprecated"_L1).value == "true"_L1)
hs << "Q_DECL_DEPRECATED ";
hs << "void " << signal.name << "(";
@@ -921,8 +923,7 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
hs << "public Q_SLOTS: // METHODS\n";
for (const QDBusIntrospection::Method &method : interface->methods) {
- bool isNoReply =
- method.annotations.value(ANNOTATION_NO_WAIT ""_L1) == "true"_L1;
+ bool isNoReply = method.annotations.value(ANNOTATION_NO_WAIT ""_L1).value == "true"_L1;
if (isNoReply && !method.outputArgs.isEmpty()) {
fprintf(stderr, "%s: warning while processing '%s': method %s in interface %s is marked 'no-reply' but has output arguments.\n",
PROGRAMNAME, qPrintable(inputFile), qPrintable(method.name), qPrintable(interface->name));
diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h
index 916370c377..e972ca21a1 100644
--- a/tests/auto/dbus/qdbusmarshall/common.h
+++ b/tests/auto/dbus/qdbusmarshall/common.h
@@ -214,7 +214,7 @@ QString printable(const QDBusIntrospection::Method& m)
.arg(arg.type, arg.name);
AnnotationsMap::const_iterator it = m.annotations.begin();
for ( ; it != m.annotations.end(); ++it)
- result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value());
+ result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value().value);
result += ")";
return result;
@@ -228,7 +228,7 @@ QString printable(const QDBusIntrospection::Signal& s)
.arg(arg.type, arg.name);
AnnotationsMap::const_iterator it = s.annotations.begin();
for ( ; it != s.annotations.end(); ++it)
- result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value());
+ result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value().value);
result += ")";
return result;
@@ -247,7 +247,7 @@ QString printable(const QDBusIntrospection::Property& p)
AnnotationsMap::const_iterator it = p.annotations.begin();
for ( ; it != p.annotations.end(); ++it)
- result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value());
+ result += QString("%1 \"%2\", ").arg(it.key()).arg(it.value().value);
return result;
}
diff --git a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
index 5e1ff9e5b7..01f174c3e8 100644
--- a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
+++ b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
@@ -32,6 +32,14 @@ private slots:
void properties();
};
+static void addAnnotation(QDBusIntrospection::Annotations &annotations, const QString &name,
+ const QString &value)
+{
+ annotations.insert(
+ name,
+ QDBusIntrospection::Annotation{ QDBusIntrospection::SourceLocation{}, name, value });
+}
+
void tst_QDBusXmlParser::initTestCase()
{
// Always initialize the hash seed with a known value to get reliable test results
@@ -191,7 +199,7 @@ void tst_QDBusXmlParser::methods_data()
// add a third, with annotations
method.name = "Baz";
- method.annotations.insert("foo.testing", "nothing to see here");
+ addAnnotation(method.annotations, "foo.testing", "nothing to see here");
map << method;
QTest::newRow("method-with-annotation") <<
"<method name=\"Foo\"/>"
@@ -290,7 +298,7 @@ void tst_QDBusXmlParser::methods_data()
method = QDBusIntrospection::Method();
method.inputArgs << arg("a{sv}", "variantMap") << arg("u", "index");
method.outputArgs << arg("s", "key") << arg("v", "value");
- method.annotations.insert("foo.equivalent", "QVariantMap");
+ addAnnotation(method.annotations, "foo.equivalent", "QVariantMap");
method.name = "Method2";
map << method;
@@ -359,7 +367,7 @@ void tst_QDBusXmlParser::signals__data()
// add a third, with annotations
signal.name = "Baz";
- signal.annotations.insert("foo.testing", "nothing to see here");
+ addAnnotation(signal.annotations, "foo.testing", "nothing to see here");
map << signal;
QTest::newRow("signal-with-annotation") <<
"<signal name=\"Foo\"/>"
@@ -408,7 +416,7 @@ void tst_QDBusXmlParser::signals__data()
// with annotation "foo.equivalent":"QVariantMap"
signal = QDBusIntrospection::Signal();
signal.outputArgs << arg("s", "key") << arg("v", "value");
- signal.annotations.insert("foo.equivalent", "QVariantMap");
+ addAnnotation(signal.annotations, "foo.equivalent", "QVariantMap");
signal.name = "Signal2";
map << signal;
@@ -492,8 +500,8 @@ void tst_QDBusXmlParser::properties_data()
prop.name = "baz";
prop.type = "as";
prop.access = QDBusIntrospection::Property::Write;
- prop.annotations.insert("foo.annotation", "Hello, World");
- prop.annotations.insert("foo.annotation2", "Goodbye, World");
+ addAnnotation(prop.annotations, "foo.annotation", "Hello, World");
+ addAnnotation(prop.annotations, "foo.annotation2", "Goodbye, World");
map << prop;
QTest::newRow("complex") <<
"<property access=\"read\" type=\"i\" name=\"bar\"/>"