aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2017-02-28 16:44:21 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2017-03-02 12:49:30 +0000
commit8d77d61eef45ccb3200f54e24c057da255edfc63 (patch)
tree20bcb5e0cff198e2bbcb3bbe7b3231f31276937e
parent8ea1045330964d71211ac8e9580858b2b4aac5c7 (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.cpp42
-rw-r--r--ApiExtractor/tests/testtemplates.cpp33
-rw-r--r--ApiExtractor/tests/testtemplates.h1
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();