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
parent
478b1afbe1
commit
e163c49435
|
|
@ -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 << ", ";
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue