diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-02-28 16:44:21 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-03-02 12:49:30 +0000 |
commit | 8d77d61eef45ccb3200f54e24c057da255edfc63 (patch) | |
tree | 20bcb5e0cff198e2bbcb3bbe7b3231f31276937e | |
parent | 8ea1045330964d71211ac8e9580858b2b4aac5c7 (diff) |
Fix and refactor _fixFunctionModelItemTypes()
For template classes, the function was supposed to add the template
parameters to the arguments and return types that take the class
itself, for example:
QList(const QList &) -> QList(const QList<T> &)
In the old implementation, it checked only on the first part
of the type's qualified name, causing
void QList::erase(QList::iterator) -> void QList::erase(QList<T>)
Rewrite the function to operate with QStringLists so that a full
match can be performed.
Task-number: PYSIDE-323
Change-Id: I27900916e864d9451cc588c3ade311fbb033665c
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | ApiExtractor/abstractmetabuilder.cpp | 42 | ||||
-rw-r--r-- | ApiExtractor/tests/testtemplates.cpp | 33 | ||||
-rw-r--r-- | ApiExtractor/tests/testtemplates.h | 1 |
3 files changed, 57 insertions, 19 deletions
diff --git a/ApiExtractor/abstractmetabuilder.cpp b/ApiExtractor/abstractmetabuilder.cpp index 8f7d328..a21faf9 100644 --- a/ApiExtractor/abstractmetabuilder.cpp +++ b/ApiExtractor/abstractmetabuilder.cpp @@ -1527,37 +1527,41 @@ static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, cons return true; } -static bool _fixFunctionModelItemType(TypeInfo& type, const AbstractMetaClass* metaClass) +// Fix the arguments of template classes that take the class itself, for example: +// "QList(const QList &)" to "QList(const QList<T> &)". +static bool _fixFunctionModelItemTypes(FunctionModelItem& function, const AbstractMetaClass* metaClass) { - if (metaClass->templateArguments().isEmpty() - || type.qualifiedName().isEmpty() - || type.qualifiedName().first() != metaClass->typeEntry()->qualifiedCppName()) { + const QList<TypeEntry *> &templateTypes = metaClass->templateArguments(); + if (templateTypes.isEmpty()) return false; + + const QStringList classType = metaClass->typeEntry()->qualifiedCppName().split(colonColon()); + QStringList fixedClassType = classType; + fixedClassType.last().append(QLatin1Char('<')); + for (int i = 0, count = templateTypes.size(); i < count; ++i) { + if (i) + fixedClassType.last().append(QLatin1String(", ")); + fixedClassType.last().append(templateTypes.at(i)->qualifiedCppName()); } - QStringList templateTypes; - foreach (TypeEntry* templateType, metaClass->templateArguments()) - templateTypes << templateType->qualifiedCppName(); - QString fixedTypeName = metaClass->typeEntry()->qualifiedCppName() + QLatin1Char('<') - + templateTypes.join(QLatin1String(", ")) + QLatin1String(" >"); - type.setQualifiedName(QStringList(fixedTypeName)); - return true; -} + fixedClassType.last().append(QLatin1String(" >")); -static bool _fixFunctionModelItemTypes(FunctionModelItem& function, const AbstractMetaClass* metaClass) -{ + bool templateTypeFixed = false; TypeInfo functionType = function->type(); - bool templateTypeFixed = _fixFunctionModelItemType(functionType, metaClass); - if (templateTypeFixed) + if (functionType.qualifiedName() == classType) { + templateTypeFixed = true; + functionType.setQualifiedName(fixedClassType); function->setType(functionType); + } ArgumentList arguments = function->arguments(); for (int i = 0; i < arguments.size(); ++i) { ArgumentModelItem arg = arguments.at(i); TypeInfo type = arg->type(); - bool tmpTypeFixed = _fixFunctionModelItemType(type, metaClass); - if (tmpTypeFixed) + if (type.qualifiedName() == classType) { + type.setQualifiedName(fixedClassType); arg->setType(type); - templateTypeFixed |= tmpTypeFixed; + templateTypeFixed = true; + } } return templateTypeFixed; } diff --git a/ApiExtractor/tests/testtemplates.cpp b/ApiExtractor/tests/testtemplates.cpp index 01cd088..73bf640 100644 --- a/ApiExtractor/tests/testtemplates.cpp +++ b/ApiExtractor/tests/testtemplates.cpp @@ -192,6 +192,39 @@ void TestTemplates::testTemplateReferenceAsArgument() QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int > &")); } +void TestTemplates::testTemplateParameterFixup() +{ + const char cppCode[] = "\n\ + template<typename T>\n\ + struct List {\n\ + struct Iterator {};\n\ + void append(List l);\n\ + void erase(List::Iterator it);\n\ + };\n"; + + const char xmlCode[] = "\n\ + <typesystem package='Package'>\n\ + <container-type name='List' type='list'/>\n\ + <value-type name='List::Iterator'/>\n\ + </typesystem>\n"; + + TestUtil t(cppCode, xmlCode, false); + const AbstractMetaClassList templates = t.builder()->templates(); + + QCOMPARE(templates.count(), 1); + const AbstractMetaClass *list = templates.first(); + // Verify that the parameter of "void append(List l)" gets fixed to "List<T >" + const AbstractMetaFunction *append = list->findFunction(QStringLiteral("append")); + QVERIFY(append); + QCOMPARE(append->arguments().size(), 1); + QCOMPARE(append->arguments().at(0)->type()->cppSignature(), QLatin1String("List<T >")); + // Verify that the parameter of "void erase(Iterator)" is not modified + const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase")); + QVERIFY(erase); + QCOMPARE(erase->arguments().size(), 1); + QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator")); +} + void TestTemplates::testInheritanceFromContainterTemplate() { const char cppCode[] = "\n\ diff --git a/ApiExtractor/tests/testtemplates.h b/ApiExtractor/tests/testtemplates.h index d835e3b..7b0d0f3 100644 --- a/ApiExtractor/tests/testtemplates.h +++ b/ApiExtractor/tests/testtemplates.h @@ -40,6 +40,7 @@ private slots: void testTemplateValueAsArgument(); void testTemplatePointerAsArgument(); void testTemplateReferenceAsArgument(); + void testTemplateParameterFixup(); void testInheritanceFromContainterTemplate(); void testTemplateInheritanceMixedWithForwardDeclaration(); void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration(); |