aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abstractmetabuilder.cpp19
-rw-r--r--abstractmetalang.h14
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/testabstractmetatype.cpp3
-rw-r--r--tests/testenum.cpp7
-rw-r--r--tests/testfunctiontag.cpp64
-rw-r--r--tests/testfunctiontag.h36
-rw-r--r--typesystem.cpp39
-rw-r--r--typesystem.h30
9 files changed, 194 insertions, 19 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 182f4456d..4d8a4f1d8 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -503,16 +503,27 @@ bool AbstractMetaBuilder::build(QIODevice* input)
m_currentClass = 0;
+ // Global functions
foreach (FunctionModelItem func, m_dom->functions()) {
if (func->accessPolicy() != CodeModel::Public || func->name().startsWith("operator"))
continue;
+ FunctionTypeEntry* funcEntry = types->findFunctionType(func->name());
+ if (!funcEntry)
+ continue;
+
AbstractMetaFunction* metaFunc = traverseFunction(func);
- if (metaFunc) {
- QFileInfo info(func->fileName());
- metaFunc->setIncludeFile(Include(Include::IncludePath, info.fileName()));
- m_globalFunctions << metaFunc;
+ if (!metaFunc)
+ continue;
+
+ if (!funcEntry->hasSignature(metaFunc->minimalSignature())) {
+ delete metaFunc;
+ continue;
}
+
+ QFileInfo info(func->fileName());
+ funcEntry->setInclude(Include(Include::IncludePath, info.fileName()));
+ m_globalFunctions << metaFunc;
}
// Functions added to the module on the type system.
diff --git a/abstractmetalang.h b/abstractmetalang.h
index d27e1df9e..9cba7e411 100644
--- a/abstractmetalang.h
+++ b/abstractmetalang.h
@@ -758,7 +758,8 @@ public:
};
AbstractMetaFunction()
- : m_functionType(NormalFunction),
+ : m_typeEntry(0),
+ m_functionType(NormalFunction),
m_type(0),
m_class(0),
m_implementingClass(0),
@@ -1089,14 +1090,9 @@ public:
return m_propertySpec;
}
- Include includeFile() const
+ FunctionTypeEntry* typeEntry() const
{
- return m_includeFile;
- }
-
- void setIncludeFile(const Include& include)
- {
- m_includeFile = include;
+ return m_typeEntry;
}
private:
QString m_name;
@@ -1104,7 +1100,7 @@ private:
mutable QString m_cachedMinimalSignature;
mutable QString m_cachedModifiedName;
- Include m_includeFile;
+ FunctionTypeEntry* m_typeEntry;
FunctionType m_functionType;
AbstractMetaType *m_type;
const AbstractMetaClass *m_class;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 61f40ce2e..189ff42a7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -24,3 +24,4 @@ declare_test(testreferencetopointer)
declare_test(testremoveimplconv)
declare_test(testreverseoperators)
declare_test(testtoposort)
+declare_test(testfunctiontag)
diff --git a/tests/testabstractmetatype.cpp b/tests/testabstractmetatype.cpp
index 3e75539fb..81e194fd3 100644
--- a/tests/testabstractmetatype.cpp
+++ b/tests/testabstractmetatype.cpp
@@ -30,6 +30,7 @@ void TestAbstractMetaType::testConstCharPtrType()
const char* cppCode ="const char* justAtest();";
const char* xmlCode = "<typesystem package=\"Foo\">\
<primitive-type name='char'/>\
+ <function signature='justAtest()' />\
</typesystem>";
TestUtil t(cppCode, xmlCode);
QCOMPARE(t.builder()->globalFunctions().size(), 1);
@@ -57,6 +58,7 @@ void TestAbstractMetaType::testCharType()
const char* xmlCode = "<typesystem package=\"Foo\">\
<primitive-type name='char'/>\
<value-type name='A' />\
+ <function signature='justAtest()' />\
</typesystem>";
TestUtil t(cppCode, xmlCode);
@@ -118,6 +120,7 @@ void TestAbstractMetaType::testTypedefWithTemplates()
const char* xmlCode = "<typesystem package=\"Foo\">\
<container-type name='A' type='list'/>\
<value-type name='B' />\
+ <function signature='func(A&lt;B&gt;)' />\
</typesystem>";
TestUtil t(cppCode, xmlCode);
diff --git a/tests/testenum.cpp b/tests/testenum.cpp
index 93a678e73..24cb4d963 100644
--- a/tests/testenum.cpp
+++ b/tests/testenum.cpp
@@ -41,12 +41,13 @@ void TestEnum::testEnumCppSignature()
<value-type name='A'/> \
<enum-type name='GlobalEnum' />\
<enum-type name='A::ClassEnum' />\
+ <function signature='func(A::ClassEnum)' />\
</typesystem>";
TestUtil t(cppCode, xmlCode);
AbstractMetaClassList classes = t.builder()->classes();
QCOMPARE(classes.count(), 1);
-
+
AbstractMetaEnumList globalEnums = t.builder()->globalEnums();
QCOMPARE(globalEnums.count(), 1);
QCOMPARE(globalEnums.first()->name(), QString("GlobalEnum"));
@@ -56,7 +57,7 @@ void TestEnum::testEnumCppSignature()
QCOMPARE(functions.count(), 1);
QCOMPARE(functions.first()->arguments().count(), 1);
QCOMPARE(functions.first()->arguments().first()->type()->cppSignature(), QString("A::ClassEnum"));
-
+
// enum as parameter of a method
AbstractMetaClass* classA = classes.findClass("A");
QCOMPARE(classA->enums().count(), 1);
@@ -72,8 +73,6 @@ void TestEnum::testEnumCppSignature()
AbstractMetaEnumList classEnums = classA->enums();
QCOMPARE(classEnums.first()->name(), QString("ClassEnum"));
-
-
}
QTEST_APPLESS_MAIN(TestEnum)
diff --git a/tests/testfunctiontag.cpp b/tests/testfunctiontag.cpp
new file mode 100644
index 000000000..79e3142a5
--- /dev/null
+++ b/tests/testfunctiontag.cpp
@@ -0,0 +1,64 @@
+/*
+* This file is part of the API Extractor project.
+*
+* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+*
+* Contact: PySide team <contact@pyside.org>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#include "testfunctiontag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+
+void TestFunctionTag::testFunctionTagForSpecificSignature()
+{
+ const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy()";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\
+ <primitive-type name='int'/> \
+ <primitive-type name='float'/> \
+ <function signature='globalFunction(int)'/>\
+ </typesystem>";
+ TestUtil t(cppCode, xmlCode, false);
+
+ FunctionTypeEntry* func = (FunctionTypeEntry*) TypeDatabase::instance()->findType("globalFunction");
+ QVERIFY(func);
+ QCOMPARE(t.builder()->globalFunctions().size(), 1);
+}
+
+void TestFunctionTag::testFunctionTagForAllSignatures()
+{
+ const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\
+ <primitive-type name='int'/> \
+ <primitive-type name='float'/> \
+ <function signature='globalFunction(int)'/>\
+ <function signature='globalFunction(float)'/>\
+ </typesystem>";
+ TestUtil t(cppCode, xmlCode, false);
+
+ FunctionTypeEntry* func = (FunctionTypeEntry*) TypeDatabase::instance()->findType("globalFunction");
+ QVERIFY(func);
+ QCOMPARE(t.builder()->globalFunctions().size(), 2);
+}
+
+QTEST_APPLESS_MAIN(TestFunctionTag)
+
+#include "testfunctiontag.moc"
+
diff --git a/tests/testfunctiontag.h b/tests/testfunctiontag.h
new file mode 100644
index 000000000..8f42774c6
--- /dev/null
+++ b/tests/testfunctiontag.h
@@ -0,0 +1,36 @@
+/*
+* This file is part of the API Extractor project.
+*
+* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+*
+* Contact: PySide team <contact@pyside.org>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#ifndef TESTFUNCTIONTAG_H
+#define TESTFUNCTIONTAG_H
+#include <QObject>
+
+class TestFunctionTag : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testFunctionTagForSpecificSignature();
+ void testFunctionTagForAllSignatures();
+};
+
+#endif
diff --git a/typesystem.cpp b/typesystem.cpp
index e1992b867..32da2ca8d 100644
--- a/typesystem.cpp
+++ b/typesystem.cpp
@@ -48,6 +48,7 @@ public:
PrimitiveTypeEntry = 0x8,
EnumTypeEntry = 0x9,
ContainerTypeEntry = 0xa,
+ FunctionTypeEntry = 0xb,
TypeEntryMask = 0xf,
// Documentation tags
@@ -130,6 +131,7 @@ public:
tagNames["interface-type"] = StackElement::InterfaceTypeEntry;
tagNames["namespace-type"] = StackElement::NamespaceTypeEntry;
tagNames["enum-type"] = StackElement::EnumTypeEntry;
+ tagNames["function"] = StackElement::FunctionTypeEntry;
tagNames["extra-includes"] = StackElement::ExtraIncludes;
tagNames["include"] = StackElement::Include;
tagNames["inject-code"] = StackElement::InjectCode;
@@ -519,6 +521,9 @@ bool Handler::startElement(const QString &, const QString &n,
attributes["target-type"] = QString();
attributes["generic-class"] = QString("no");
break;
+ case StackElement::FunctionTypeEntry:
+ attributes["signature"] = QString();
+ break;
default:
{ } // nada
};
@@ -526,11 +531,18 @@ bool Handler::startElement(const QString &, const QString &n,
fetchAttributeValues(tagName, atts, &attributes);
QString name = attributes["name"];
+ // The top level tag 'function' has only the 'signature' tag
+ // and we should extract the 'name' value from it.
+ if (element->type == StackElement::FunctionTypeEntry) {
+ QString signature = attributes["signature"];
+ name = signature.left(signature.indexOf('(')).trimmed();
+ }
// We need to be able to have duplicate primitive type entries,
// or it's not possible to cover all primitive target language
// types (which we need to do in order to support fake meta objects)
- if (element->type != StackElement::PrimitiveTypeEntry) {
+ if (element->type != StackElement::PrimitiveTypeEntry
+ && element->type != StackElement::FunctionTypeEntry) {
TypeEntry *tmp = m_database->findType(name);
if (tmp)
ReportHandler::warning(QString("Duplicate type entry: '%1'").arg(name));
@@ -728,6 +740,22 @@ bool Handler::startElement(const QString &, const QString &n,
}
break;
+ case StackElement::FunctionTypeEntry: {
+ QString signature = attributes["signature"];
+ signature = TypeDatabase::normalizedSignature(signature.toLatin1().constData());
+ element->entry = m_database->findType(name);
+ if (element->entry) {
+ if (element->entry->type() == TypeEntry::FunctionType) {
+ reinterpret_cast<FunctionTypeEntry*>(element->entry)->addSignature(signature);
+ } else {
+ m_error = QString("%1 expected to be a function, but isn't! Maybe it was already declared as a class or something else.").arg(name);
+ return false;
+ }
+ } else {
+ element->entry = new FunctionTypeEntry(name, signature);
+ }
+ }
+ break;
default:
Q_ASSERT(false);
};
@@ -1768,6 +1796,15 @@ ContainerTypeEntry *TypeDatabase::findContainerType(const QString &name)
return 0;
}
+FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name)
+{
+ TypeEntry* entry = findType(name);
+ if (entry && entry->type() == TypeEntry::FunctionType)
+ return static_cast<FunctionTypeEntry*>(entry);
+ return 0;
+}
+
+
PrimitiveTypeEntry *TypeDatabase::findTargetLangPrimitiveType(const QString &targetLangName)
{
foreach (QList<TypeEntry *> entries, m_entries.values()) {
diff --git a/typesystem.h b/typesystem.h
index 1c1c08299..662cb53e1 100644
--- a/typesystem.h
+++ b/typesystem.h
@@ -583,7 +583,8 @@ public:
ArrayType,
TypeSystemType,
CustomType,
- TargetLangType
+ TargetLangType,
+ FunctionType
};
enum CodeGeneration {
@@ -1699,6 +1700,32 @@ private:
};
+class APIEXTRACTOR_API FunctionTypeEntry : public TypeEntry
+{
+public:
+ FunctionTypeEntry(const QString& name, const QString& signature)
+ : TypeEntry(name, FunctionType)
+ {
+ addSignature(signature);
+ }
+ void addSignature(const QString& signature)
+ {
+ m_signatures << signature;
+ }
+
+ QStringList signatures()
+ {
+ return m_signatures;
+ }
+
+ inline bool hasSignature(const QString& signature)
+ {
+ return m_signatures.contains(signature);
+ }
+private:
+ QStringList m_signatures;
+};
+
class APIEXTRACTOR_API ObjectTypeEntry : public ComplexTypeEntry
{
public:
@@ -1779,6 +1806,7 @@ public:
inline ObjectTypeEntry *findObjectType(const QString &name);
inline NamespaceTypeEntry *findNamespaceType(const QString &name);
ContainerTypeEntry *findContainerType(const QString &name);
+ FunctionTypeEntry* findFunctionType(const QString& name);
TypeEntry *findType(const QString &name) const
{