qdbusxml2cpp: remove the old "In"-for-signal compatibility code

This led to an infinite recursion in case the annotation was completely
missing. Instead of trying to fix that, I'm simply implementing the
"### Qt6" request from c62f717226 .

[ChangeLog][qdbusxml2cpp] Removed the old compatibility code that
accepted "In" annotations for signal argument names, introduced in Qt
5.8.

Pick-to: 6.4
Fixes: QTBUG-104722
Change-Id: Ie4bb662dcb274440ab8bfffd1709bfc3daf0846d
Reviewed-by: David Faure <david.faure@kdab.com>
bb10
Thiago Macieira 2022-08-09 11:13:05 -07:00
parent 478b1afbe1
commit e163c49435
3 changed files with 113 additions and 47 deletions

View File

@ -175,12 +175,9 @@ static QString classNameForInterface(const QString &interface, ClassType classTy
return retval;
}
// ### Qt6 Remove the two isSignal ifs
// They are only here because before signal arguments where previously searched as "In" so to maintain compatibility
// we first search for "Out" and if not found we search for "In"
static QByteArray qtTypeName(const QString &where, const QString &signature,
const QDBusIntrospection::Annotations &annotations, qsizetype paramId = -1,
const char *direction = "Out", bool isSignal = false)
const char *direction = "Out")
{
int type = QDBusMetaType::signatureToMetaType(signature.toLatin1()).id();
if (type == QMetaType::UnknownType) {
@ -197,17 +194,12 @@ static QByteArray qtTypeName(const QString &where, const QString &signature,
qttype = annotations.value(oldAnnotationName);
if (qttype.isEmpty()) {
if (!isSignal || qstrcmp(direction, "Out") == 0) {
fprintf(stderr, "%s: Got unknown type `%s' processing '%s'\n",
PROGRAMNAME, qPrintable(signature), qPrintable(inputFile));
fprintf(stderr,
"You should add <annotation name=\"%s\" value=\"<type>\"/> to the XML "
"description for '%s'\n",
qPrintable(annotationName), qPrintable(where));
}
if (isSignal)
return qtTypeName(where, signature, annotations, paramId, "In", isSignal);
fprintf(stderr, "%s: Got unknown type `%s' processing '%s'\n",
PROGRAMNAME, qPrintable(signature), qPrintable(inputFile));
fprintf(stderr,
"You should add <annotation name=\"%s\" value=\"<type>\"/> to the XML "
"description for '%s'\n",
qPrintable(annotationName), qPrintable(where));
exit(1);
}
@ -318,7 +310,7 @@ static void writeSignalArgList(QTextStream &ts, const QStringList &argNames,
for (qsizetype i = 0; i < outputArgs.size(); ++i) {
const QDBusIntrospection::Argument &arg = outputArgs.at(i);
QString type = constRefArg(
qtTypeName(arg.name, arg.type, annotations, i, "Out", true /* isSignal */));
qtTypeName(arg.name, arg.type, annotations, i, "Out"));
if (!first)
ts << ", ";

View File

@ -12,7 +12,7 @@
</signal>
<signal name="complexSignal">
<arg name="" type="(s)"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="RegisteredType"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RegisteredType"/>
</signal>
<method name="voidMethod" />
<method name="sleepMethod">

View File

@ -21,6 +21,8 @@ private slots:
void process();
void includeStyle_data();
void includeStyle();
void missingAnnotation_data();
void missingAnnotation();
};
struct BasicTypeList {
@ -57,6 +59,44 @@ static QString stripHeader(QString output)
return output.remove(header);
}
static void runTool(QProcess &process, const QByteArray &data)
{
// test both interface and adaptor generation
QFETCH_GLOBAL(QString, commandLineArg);
// Run the tool
const QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath);
QStringList arguments = { commandLineArg, "-", "-N" };
process.setArguments(arguments);
process.setProgram(binpath + QLatin1String("/qdbusxml2cpp"));
process.start(QIODevice::Text | QIODevice::ReadWrite);
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
// feed it our XML data
static const char xmlHeader[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE // \n is included
"<node>\n"
" <interface name=\"local.name.is.not.important\">\n"
" <!-- begin data -->\n";
static const char xmlFooter[] = "\n"
" <!-- end data -->\n"
" </interface>\n"
"</node>\n";
process.write(xmlHeader, sizeof(xmlHeader) - 1);
process.write(data);
process.write(xmlFooter, sizeof(xmlFooter) - 1);
while (process.bytesToWrite())
QVERIFY2(process.waitForBytesWritten(), qPrintable(process.errorString()));
// fprintf(stderr, "%s%s%s", xmlHeader, xmlSnippet.toLatin1().constData(), xmlFooter);
process.closeWriteChannel();
QVERIFY2(process.waitForFinished(), qPrintable(process.errorString()));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
}
void tst_qdbusxml2cpp::initTestCase_data()
{
QTest::addColumn<int>("outputMode");
@ -181,6 +221,15 @@ void tst_qdbusxml2cpp::process_data()
.arg(basicTypeList[i].dbusType)
<< rx << rx;
}
QRegularExpression rx(R"(Q_SIGNALS:.*\b\Qvoid Signal(const QVariantMap &map);\E)",
QRegularExpression::DotMatchesEverythingOption);
QTest::newRow("signal-complex")
<< R"(<signal name="Signal">
<arg type="a{sv}" name="map"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>"
</signal>)"
<< rx << rx;
}
void tst_qdbusxml2cpp::process()
@ -191,38 +240,10 @@ void tst_qdbusxml2cpp::process()
QVERIFY2(interfaceSearch.isValid(), qPrintable(interfaceSearch.errorString()));
QVERIFY2(adaptorSearch.isValid(), qPrintable(adaptorSearch.errorString()));
// test both interface and adaptor generation
QFETCH_GLOBAL(int, outputMode);
QFETCH_GLOBAL(QString, commandLineArg);
// Run the tool
const QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath);
const QString command = binpath + QLatin1String("/qdbusxml2cpp");
QProcess process;
process.start(command, QStringList() << commandLineArg << "-" << "-N");
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
// feed it our XML data
static const char xmlHeader[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE // \n is included
"<node>\n"
" <interface name=\"local.name.is.not.important\">\n"
" <!-- begin data -->\n";
static const char xmlFooter[] = "\n"
" <!-- end data -->\n"
" </interface>\n"
"</node>\n";
process.write(xmlHeader, int(sizeof xmlHeader) - 1);
process.write(xmlSnippet.toLatin1());
process.write(xmlFooter, int(sizeof xmlFooter) - 1);
while (process.bytesToWrite())
QVERIFY2(process.waitForBytesWritten(), qPrintable(process.errorString()));
// fprintf(stderr, "%s%s%s", xmlHeader, xmlSnippet.toLatin1().constData(), xmlFooter);
process.closeWriteChannel();
QVERIFY2(process.waitForFinished(), qPrintable(process.errorString()));
runTool(process, xmlSnippet.toLatin1());
if (QTest::currentTestFailed()) return;
QByteArray errOutput = process.readAllStandardError();
QVERIFY2(errOutput.isEmpty(), errOutput);
@ -284,6 +305,59 @@ void tst_qdbusxml2cpp::includeStyle()
QVERIFY(fullOutput.contains(expected));
}
void tst_qdbusxml2cpp::missingAnnotation_data()
{
QTest::addColumn<QString>("xmlSnippet");
QTest::addColumn<QString>("annotationName");
QTest::newRow("property")
<< R"(<property type="%1" name="name" access="readwrite"/>)"
<< "org.qtproject.QtDBus.QtTypeName";
QTest::newRow("method-in")
<< R"(<method name="Method">
<arg type="%1" name="name" direction="in"/>
</method>)"
<< "org.qtproject.QtDBus.QtTypeName.In0";
QTest::newRow("method-out")
<< R"(<method name="Method">
<arg type="%1" name="name" direction="out"/>
</method>)"
<< "org.qtproject.QtDBus.QtTypeName.Out0";
QTest::newRow("signal")
<< R"(<signal name="Signal">
<arg type="%1" name="name"/>
</signal>)"
<< "org.qtproject.QtDBus.QtTypeName.Out0";
QTest::newRow("signal-out")
<< R"(<signal name="Signal">
<arg type="%1" name="name" direction="out"/>
</signal>)"
<< "org.qtproject.QtDBus.QtTypeName.Out0";
}
void tst_qdbusxml2cpp::missingAnnotation()
{
QFETCH(QString, xmlSnippet);
QFETCH(QString, annotationName);
QString type = "(ii)";
QProcess process;
runTool(process, xmlSnippet.arg(type).toLatin1());
if (QTest::currentTestFailed()) return;
// it must have failed
QString errOutput = QString::fromLatin1(process.readAllStandardError().trimmed());
QCOMPARE(process.exitCode(), 1);
QCOMPARE(process.readAllStandardOutput(), QByteArray());
QVERIFY(!errOutput.isEmpty());
// check it did suggest the right annotation
QString expected = R"(qdbusxml2cpp: Got unknown type `%1' processing ''
You should add <annotation name="%2" value="<type>"/> to the XML description for 'name')";
expected = expected.arg(type, annotationName);
QCOMPARE(errOutput, expected);
}
QTEST_MAIN(tst_qdbusxml2cpp)
#include "tst_qdbusxml2cpp.moc"