From 26d6ef0c8f359b3bc29e2f68238e28f86e9448c5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Aug 2018 14:18:11 +0200 Subject: shiboken: Implement template inheritance for fields Add the fields to the typedef'ed class specializing the type similar to the functions. Task-number: PYSIDE-725 Change-Id: I2daae9bd3c8a73fbd868f495cfc3a2dfba703103 Reviewed-by: Christian Tismer --- .../shiboken2/ApiExtractor/tests/testtemplates.cpp | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'sources/shiboken2/ApiExtractor/tests/testtemplates.cpp') diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index 8d869e3f9..d32e24379 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -28,6 +28,7 @@ #include "testtemplates.h" #include +#include #include #include "testutil.h" #include @@ -438,4 +439,101 @@ typedef Vector IntVector; QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector")); } +// Perform checks on template inheritance; a typedef of a template class +// should result in rewritten types. +void TestTemplates::testTemplateTypeDefs_data() +{ + QTest::addColumn("cpp"); + QTest::addColumn("xml"); + + const char optionalClassDef[] = R"CPP( +template // Some value type similar to std::optional +class Optional { +public: + T value() const { return m_value; } + operator bool() const { return m_success; } + + T m_value; + bool m_success = false; +}; +)CPP"; + + const char xmlPrefix[] = R"XML( + + + +)XML"; + + const char xmlOptionalDecl[] = "\n"; + const char xmlOptionalIntDecl[] = "\n"; + const char xmlPostFix[] = "\n"; + + // Flat, global namespace + QString cpp; + QTextStream(&cpp) << optionalClassDef + << "typedef Optional IntOptional;\n"; + QString xml; + QTextStream(&xml) << xmlPrefix << xmlOptionalDecl << xmlOptionalIntDecl + << xmlPostFix; + QTest::newRow("global-namespace") + << cpp << xml; + + // Typedef from namespace Std + cpp.clear(); + QTextStream(&cpp) << "namespace Std {\n" << optionalClassDef << "}\n" + << "typedef Std::Optional IntOptional;\n"; + xml.clear(); + QTextStream(&xml) << xmlPrefix + << "\n" << xmlOptionalDecl + << "\n" << xmlOptionalIntDecl + << xmlPostFix; + QTest::newRow("namespace-Std") + << cpp << xml; + + // Typedef from nested class + cpp.clear(); + QTextStream(&cpp) << "class Outer {\npublic:\n" << optionalClassDef << "\n};\n" + << "typedef Outer::Optional IntOptional;\n"; + xml.clear(); + QTextStream(&xml) << xmlPrefix + << "\n" << xmlOptionalDecl + << "\n" << xmlOptionalIntDecl + << xmlPostFix; + QTest::newRow("nested-class") + << cpp << xml; +} + +void TestTemplates::testTemplateTypeDefs() +{ + QFETCH(QString, cpp); + QFETCH(QString, xml); + + const QByteArray cppBa = cpp.toLocal8Bit(); + const QByteArray xmlBa = xml.toLocal8Bit(); + QScopedPointer builder(TestUtil::parse(cppBa.constData(), xmlBa.constData(), true)); + QVERIFY(!builder.isNull()); + AbstractMetaClassList classes = builder->classes(); + + const AbstractMetaClass *optional = AbstractMetaClass::findClass(classes, QLatin1String("Optional")); + QVERIFY(optional); + + // Find the typedef'ed class + const AbstractMetaClass *optionalInt = + AbstractMetaClass::findClass(classes, QLatin1String("IntOptional")); + QVERIFY(optionalInt); + QCOMPARE(optionalInt->templateBaseClass(), optional); + + // Check whether the value() method now has an 'int' return + const AbstractMetaFunction *valueMethod = + optionalInt->findFunction(QLatin1String("value")); + QVERIFY(valueMethod); + QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int")); + + // Check whether the m_value field is of type 'int' + const AbstractMetaField *valueField = + optionalInt->findField(QLatin1String("m_value")); + QVERIFY(valueField); + QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int")); +} + QTEST_APPLESS_MAIN(TestTemplates) -- cgit v1.2.3