Debugger: Adapt QMap and QMultiMap dumper to Qt6

Chicken out of the QStringList == QList<QString> in Qt 6 dilemma
by using QList<QString> everywhere, that's not important for the
QMap test. value/key vs first/second nevertheless needs adaptation.

Task-number: QTCREATORBUG-24098
Task-number: QTCREATORBUG-23806
Change-Id: I4bdb8222978de7e7f1596be380e0fedc8f9d1a06
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2020-11-11 08:34:28 +01:00
parent f99e46c148
commit 92cd7f3c06
2 changed files with 115 additions and 52 deletions

View File

@@ -1213,6 +1213,16 @@ def qdumpHelper_Qt5_QMap(d, value, keyType, valueType):
d.putPairItem(i, pair, 'key', 'value') d.putPairItem(i, pair, 'key', 'value')
def qdumpHelper_Qt6_QMap(d, value, keyType, valueType):
d_ptr = d.extractPointer(value)
if d_ptr == 0:
d.putItemCount(0)
return
m = value['d']['d']['m']
d.putItem(m)
d.putBetterType('QMap<%s, %s>' % (keyType.name, valueType.name))
def qform__QMap(): def qform__QMap():
return [DisplayFormat.CompactMap] return [DisplayFormat.CompactMap]
@@ -1222,17 +1232,31 @@ def qdump__QMap(d, value):
def qdumpHelper_QMap(d, value, keyType, valueType): def qdumpHelper_QMap(d, value, keyType, valueType):
if d.qtVersion() < 0x50000: if d.qtVersion() >= 0x60000:
qdumpHelper_Qt4_QMap(d, value, keyType, valueType) qdumpHelper_Qt6_QMap(d, value, keyType, valueType)
else: elif d.qtVersion() >= 0x50000:
qdumpHelper_Qt5_QMap(d, value, keyType, valueType) qdumpHelper_Qt5_QMap(d, value, keyType, valueType)
else:
qdumpHelper_Qt4_QMap(d, value, keyType, valueType)
def qform__QMultiMap(): def qform__QMultiMap():
return [DisplayFormat.CompactMap] return [DisplayFormat.CompactMap]
def qdumpHelper_Qt6_QMultiMap(d, value, keyType, valueType):
d_ptr = d.extractPointer(value)
if d_ptr == 0:
d.putItemCount(0)
return
m = value['d']['d']['m']
d.putItem(m)
d.putBetterType('QMultiMap<%s, %s>' % (keyType.name, valueType.name))
def qdump__QMultiMap(d, value): def qdump__QMultiMap(d, value):
if d.qtVersion() >= 0x60000:
qdumpHelper_Qt6_QMultiMap(d, value, value.type[0], value.type[1])
else:
qdump__QMap(d, value) qdump__QMap(d, value)

View File

@@ -675,7 +675,6 @@ struct Check5 : Check
Check5(const QByteArray &iname, const Name &name, const Value &value, const Type &type) Check5(const QByteArray &iname, const Name &name, const Value &value, const Type &type)
: Check(QString::fromUtf8(iname), name, value, type) : Check(QString::fromUtf8(iname), name, value, type)
{ qtVersionForCheck = Qt5; } { qtVersionForCheck = Qt5; }
}; };
struct Check6 : Check struct Check6 : Check
@@ -687,8 +686,30 @@ struct Check6 : Check
Check6(const QByteArray &iname, const Name &name, const Value &value, const Type &type) Check6(const QByteArray &iname, const Name &name, const Value &value, const Type &type)
: Check(QString::fromUtf8(iname), name, value, type) : Check(QString::fromUtf8(iname), name, value, type)
{ qtVersionForCheck = Qt6; } { qtVersionForCheck = Qt6; }
}; };
// To brush over uses of 'key'/'value' vs 'first'/'second' in inames
struct CheckPairish : Check
{
using Check::Check;
};
QDebug operator<<(QDebug os, const QtVersion &version)
{
return os << Qt::hex << version.min << '-' << Qt::hex << version.max;
}
QDebug operator<<(QDebug os, const Check &check)
{
return os
<< check.iname
<< check.expectedName.name
<< check.expectedValue.value
<< check.expectedType.type
<< check.qtVersionForCheck;
}
struct Profile struct Profile
{ {
Profile(const QByteArray &contents) : contents(contents + '\n') {} Profile(const QByteArray &contents) : contents(contents + '\n') {}
@@ -779,6 +800,23 @@ public:
return *this; return *this;
} }
const Data &operator+(const CheckPairish &check) const
{
Check check5 = check;
check5.qtVersionForCheck = QtVersion(0, 0x5ffff);
checks.append(check5);
Check check6 = check;
check6.qtVersionForCheck = QtVersion(0x60000, 0x6ffff);
check6.iname.replace("key", "first");
check6.iname.replace("value", "second");
check6.expectedName.name.replace("key", "first");
check6.expectedName.name.replace("value", "second");
checks.append(check6);
return *this;
}
const Data &operator+(const CheckSet &checkset) const const Data &operator+(const CheckSet &checkset) const
{ {
checksets.append(checkset); checksets.append(checkset);
@@ -1900,7 +1938,7 @@ void tst_Dumpers::dumper()
auto test = [&](const Check &check, bool *removeIt, bool single) { auto test = [&](const Check &check, bool *removeIt, bool single) {
if (!check.matches(m_debuggerEngine, m_debuggerVersion, context)) { if (!check.matches(m_debuggerEngine, m_debuggerVersion, context)) {
if (single) if (single)
qDebug() << "SKIPPING NON-MATCHING TEST FOR " << check.iname; qDebug() << "SKIPPING NON-MATCHING TEST " << check;
return true; // we have not failed return true; // we have not failed
} }
@@ -1983,9 +2021,9 @@ void tst_Dumpers::dumper()
qDebug() << "SOME TESTS NOT EXECUTED: "; qDebug() << "SOME TESTS NOT EXECUTED: ";
for (const Check &check : qAsConst(data.checks)) { for (const Check &check : qAsConst(data.checks)) {
if (check.optionallyPresent) { if (check.optionallyPresent) {
qDebug() << " OPTIONAL TEST NOT FOUND FOR INAME: " << check.iname << " IGNORED."; qDebug() << " OPTIONAL TEST NOT FOUND: " << check << " IGNORED.";
} else { } else {
qDebug() << " COMPULSORY TEST NOT FOUND FOR INAME: " << check.iname; qDebug() << " COMPULSORY TEST NOT FOUND: " << check;
ok = false; ok = false;
} }
} }
@@ -2767,22 +2805,22 @@ void tst_Dumpers::dumper_data()
<< Data("#include <QMap>\n" << Data("#include <QMap>\n"
"#include <QObject>\n" "#include <QObject>\n"
"#include <QPointer>\n" "#include <QPointer>\n"
"#include <QStringList>\n" + fooData + nsData, "#include <QList>\n" + fooData + nsData,
"QMap<uint, QStringList> m0;\n" "QMap<uint, QList<QString>> m0;\n"
"QMap<uint, QStringList> m1;\n" "QMap<uint, QList<QString>> m1;\n"
"m1[11] = QStringList() << \"11\";\n" "m1[11] = QList<QString>() << \"11\";\n"
"m1[22] = QStringList() << \"22\";\n\n" "m1[22] = QList<QString>() << \"22\";\n\n"
"QMap<uint, float> m2;\n" "QMap<uint, float> m2;\n"
"m2[11] = 31.0;\n" "m2[11] = 31.0;\n"
"m2[22] = 32.0;\n\n" "m2[22] = 32.0;\n\n"
"typedef QMap<uint, QStringList> T;\n" "typedef QMap<uint, QList<QString>> T;\n"
"T m3;\n" "T m3;\n"
"m3[11] = QStringList() << \"11\";\n" "m3[11] = QList<QString>() << \"11\";\n"
"m3[22] = QStringList() << \"22\";\n\n" "m3[22] = QList<QString>() << \"22\";\n\n"
"QMap<QString, float> m4;\n" "QMap<QString, float> m4;\n"
"m4[\"22.0\"] = 22.0;\n\n" "m4[\"22.0\"] = 22.0;\n\n"
@@ -2814,59 +2852,60 @@ void tst_Dumpers::dumper_data()
+ CoreProfile() + CoreProfile()
+ Check("m0", "<0 items>", "@QMap<unsigned int, @QStringList>") + Check("m0", "<0 items>", "@QMap<unsigned int, @QList<QString>>")
+ Check("m1", "<2 items>", "@QMap<unsigned int, @QStringList>") + Check("m1", "<2 items>", "@QMap<unsigned int, @QList<QString>>")
+ Check("m1.0.key", "11", "unsigned int") + CheckPairish("m1.0.key", "11", "unsigned int")
+ Check("m1.0.value", "<1 items>", "@QStringList") + CheckPairish("m1.0.value", "<1 items>", "@QList<QString>")
+ Check("m1.0.value.0", "[0]", "\"11\"", "@QString") + CheckPairish("m1.0.value.0", "[0]", "\"11\"", "@QString")
+ Check("m1.1.key", "22", "unsigned int") + CheckPairish("m1.1.key", "22", "unsigned int")
+ Check("m1.1.value", "<1 items>", "@QStringList") + CheckPairish("m1.1.value", "<1 items>", "@QList<QString>")
+ Check("m1.1.value.0", "[0]", "\"22\"", "@QString") + CheckPairish("m1.1.value.0", "[0]", "\"22\"", "@QString")
+ Check("m2", "<2 items>", "@QMap<unsigned int, float>") + Check("m2", "<2 items>", "@QMap<unsigned int, float>")
+ Check("m2.0", "[0] 11", FloatValue("31.0"), "") + Check("m2.0", "[0] 11", FloatValue("31.0"), "")
+ Check("m2.1", "[1] 22", FloatValue("32.0"), "") + Check("m2.1", "[1] 22", FloatValue("32.0"), "")
+ Check("m3", "<2 items>", TypeDef("@QMap<unsigned int,@QStringList>", "T")) + Check("m3", "<2 items>", TypeDef("@QMap<unsigned int,@QList<QString>>", "T"))
+ Check("m4", "<1 items>", "@QMap<@QString, float>") + Check("m4", "<1 items>", "@QMap<@QString, float>")
+ Check("m4.0.key", "\"22.0\"", "@QString") + CheckPairish("m4.0.key", "\"22.0\"", "@QString")
+ Check("m4.0.value", FloatValue("22"), "float") + CheckPairish("m4.0.value", FloatValue("22"), "float")
+ Check("m5", "<1 items>", "@QMap<int, @QString>") + Check("m5", "<1 items>", "@QMap<int, @QString>")
+ Check("m5.0.key", "22", "int") + CheckPairish("m5.0.key", "22", "int")
+ Check("m5.0.value", "\"22.0\"", "@QString") + CheckPairish("m5.0.value", "\"22.0\"", "@QString")
+ Check("m6", "<2 items>", "@QMap<@QString, Foo>") + Check("m6", "<2 items>", "@QMap<@QString, Foo>")
+ Check("m6.0.key", "\"22.0\"", "@QString") + CheckPairish("m6.0.key", "\"22.0\"", "@QString")
+ Check("m6.0.value", "", "Foo") + CheckPairish("m6.0.value", "", "Foo")
+ Check("m6.0.value.a", "22", "int") + CheckPairish("m6.0.value.a", "22", "int")
+ Check("m6.1.key", "\"33.0\"", "@QString") + CheckPairish("m6.1.key", "\"33.0\"", "@QString")
+ Check("m6.1.value", "", "Foo") + CheckPairish("m6.1.value", "", "Foo")
+ Check("m6.1.value.a", "33", "int") + CheckPairish("m6.1.value.a", "33", "int")
+ Check("m7", "<3 items>", "@QMap<@QString, @QPointer<@QObject>>") + Check("m7", "<3 items>", "@QMap<@QString, @QPointer<@QObject>>")
+ Check("m7.0.key", "\".\"", "@QString") + CheckPairish("m7.0.key", "\".\"", "@QString")
+ Check("m7.0.value", "", "@QPointer<@QObject>") + CheckPairish("m7.0.value", "", "@QPointer<@QObject>")
//+ Check("m7.0.value.o", Pointer(), "@QObject") //+ Check("m7.0.value.o", Pointer(), "@QObject")
// FIXME: it's '.wp' in Qt 5 // FIXME: it's '.wp' in Qt 5
+ Check("m7.1.key", "\"Hallo\"", "@QString") + CheckPairish("m7.1.key", "\"Hallo\"", "@QString")
+ Check("m7.2.key", "\"Welt\"", "@QString") + CheckPairish("m7.2.key", "\"Welt\"", "@QString")
+ Check("m8", "<4 items>", "@QMap<@QString, @QList<nsA::nsB::SomeType*>>") + Check("m8", "<4 items>", "@QMap<@QString, @QList<nsA::nsB::SomeType*>>")
+ Check("m8.0.key", "\"1\"", "@QString") + CheckPairish("m8.0.key", "\"1\"", "@QString")
+ Check("m8.0.value", "<3 items>", "@QList<nsA::nsB::SomeType*>") + CheckPairish("m8.0.value", "<3 items>", "@QList<nsA::nsB::SomeType*>")
+ Check("m8.0.value.0", "[0]", "", "nsA::nsB::SomeType") + CheckPairish("m8.0.value.0", "[0]", "", "nsA::nsB::SomeType")
+ Check("m8.0.value.0.a", "1", "int") + CheckPairish("m8.0.value.0.a", "1", "int")
+ Check("m8.0.value.1", "[1]", "", "nsA::nsB::SomeType") + CheckPairish("m8.0.value.1", "[1]", "", "nsA::nsB::SomeType")
+ Check("m8.0.value.1.a", "2", "int") + CheckPairish("m8.0.value.1.a", "2", "int")
+ Check("m8.0.value.2", "[2]", "", "nsA::nsB::SomeType") + CheckPairish("m8.0.value.2", "[2]", "", "nsA::nsB::SomeType")
+ Check("m8.0.value.2.a", "3", "int") + CheckPairish("m8.0.value.2.a", "3", "int")
+ Check("m8.3.key", "\"foo\"", "@QString") + CheckPairish("m8.3.key", "\"foo\"", "@QString")
+ Check("m8.3.value", "<3 items>", "@QList<nsA::nsB::SomeType*>") + CheckPairish("m8.3.value", "<3 items>", "@QList<nsA::nsB::SomeType*>")
+ Check("m8.3.value.2", "[2]", "", "nsA::nsB::SomeType") + CheckPairish("m8.3.value.2", "[2]", "", "nsA::nsB::SomeType")
+ Check("m8.3.value.2.a", "3", "int") + CheckPairish("m8.3.value.2.a", "3", "int")
+ Check("x", "<3 items>", "@QList<nsA::nsB::SomeType*>"); + Check("x", "<3 items>", "@QList<nsA::nsB::SomeType*>");