aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--abstractmetabuilder.cpp1
-rw-r--r--abstractmetabuilder.h5
-rw-r--r--abstractmetalang.cpp1
-rw-r--r--apiextractor.cpp1
-rw-r--r--reporthandler.cpp1
-rw-r--r--tests/testutil.h1
-rw-r--r--typedatabase.cpp390
-rw-r--r--typedatabase.h190
-rw-r--r--typesystem.cpp446
-rw-r--r--typesystem.h266
-rw-r--r--typesystem_p.h159
12 files changed, 797 insertions, 666 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 736e4b62..31ff7e4b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ reporthandler.cpp
typeparser.cpp
typesystem.cpp
include.cpp
+typedatabase.cpp
parser/ast.cpp
parser/binder.cpp
parser/class_compiler.cpp
@@ -116,6 +117,7 @@ fileout.h
docparser.h
qtdocparser.h
include.h
+typedatabase.h
)
if (BUILD_TESTS)
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 4d8a4f1d..994448b9 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -23,6 +23,7 @@
#include "abstractmetabuilder.h"
#include "reporthandler.h"
+#include "typedatabase.h"
#include "parser/ast.h"
#include "parser/binder.h"
diff --git a/abstractmetabuilder.h b/abstractmetabuilder.h
index 525d4d3b..9aef28a5 100644
--- a/abstractmetabuilder.h
+++ b/abstractmetabuilder.h
@@ -31,6 +31,8 @@
#include <QtCore/QSet>
+class TypeDatabase;
+
class APIEXTRACTOR_API AbstractMetaBuilder
{
public:
@@ -160,8 +162,7 @@ public:
bool isQObject(const QString &qualifiedName);
bool isEnum(const QStringList &qualifiedName);
- void fixQObjectForScope(TypeDatabase *types,
- NamespaceModelItem item);
+ void fixQObjectForScope(TypeDatabase* types, NamespaceModelItem item);
// QtScript
QSet<QString> qtMetaTypeDeclaredTypeNames() const
diff --git a/abstractmetalang.cpp b/abstractmetalang.cpp
index c7d0adf4..3ae80e0e 100644
--- a/abstractmetalang.cpp
+++ b/abstractmetalang.cpp
@@ -23,6 +23,7 @@
#include "abstractmetalang.h"
#include "reporthandler.h"
+#include "typedatabase.h"
/*******************************************************************************
* AbstractMetaType
diff --git a/apiextractor.cpp b/apiextractor.cpp
index 38acf46e..2e16b8ec 100644
--- a/apiextractor.cpp
+++ b/apiextractor.cpp
@@ -33,6 +33,7 @@
#include "parser/rpp/pp.h"
#include "abstractmetabuilder.h"
#include "apiextractorversion.h"
+#include "typedatabase.h"
static bool preprocess(const QString& sourceFile,
QFile& targetFile,
diff --git a/reporthandler.cpp b/reporthandler.cpp
index fd41983c..4b012893 100644
--- a/reporthandler.cpp
+++ b/reporthandler.cpp
@@ -23,6 +23,7 @@
#include "reporthandler.h"
#include "typesystem.h"
+#include "typedatabase.h"
#include <QtCore/QSet>
#include <cstring>
#include <cstdarg>
diff --git a/tests/testutil.h b/tests/testutil.h
index b4124e4c..1aed9834 100644
--- a/tests/testutil.h
+++ b/tests/testutil.h
@@ -26,6 +26,7 @@
#include <QtCore/QBuffer>
#include "abstractmetabuilder.h"
#include "reporthandler.h"
+#include "typedatabase.h"
class TestUtil
{
diff --git a/typedatabase.cpp b/typedatabase.cpp
new file mode 100644
index 00000000..57bf2414
--- /dev/null
+++ b/typedatabase.cpp
@@ -0,0 +1,390 @@
+/*
+ * This file is part of the API Extractor project.
+ *
+ * Copyright (C) 2009-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 "typedatabase.h"
+#include "typesystem.h"
+#include "typesystem_p.h"
+
+#include <QFile>
+#include <QXmlInputSource>
+#include "reporthandler.h"
+
+TypeDatabase::TypeDatabase() : m_suppressWarnings(true)
+{
+ StringTypeEntry* e = new StringTypeEntry("QXmlStreamStringRef");
+ e->setPreferredConversion(false);
+ addType(e);
+
+ addType(new VoidTypeEntry());
+ addType(new VarargsTypeEntry());
+}
+
+TypeDatabase* TypeDatabase::instance(bool newInstance)
+{
+ static TypeDatabase* db = 0;
+ if (!db || newInstance) {
+ if (db)
+ delete db;
+ db = new TypeDatabase;
+ }
+ return db;
+}
+
+QString TypeDatabase::normalizedSignature(const char* signature)
+{
+ QString normalized = QMetaObject::normalizedSignature(signature);
+
+ if (!instance() || !QString(signature).contains("unsigned"))
+ return normalized;
+
+ QStringList types;
+ types << "char" << "short" << "int" << "long";
+ foreach (const QString& type, types) {
+ if (instance()->findType(QString("u%1").arg(type)))
+ continue;
+ normalized.replace(QRegExp(QString("\\bu%1\\b").arg(type)), QString("unsigned %1").arg(type));
+ }
+
+ return normalized;
+}
+
+QStringList TypeDatabase::requiredTargetImports()
+{
+ return m_requiredTargetImports;
+}
+
+void TypeDatabase::addRequiredTargetImport(const QString& moduleName)
+{
+ if (!m_requiredTargetImports.contains(moduleName))
+ m_requiredTargetImports << moduleName;
+}
+
+void TypeDatabase::addTypesystemPath(const QString& typesystem_paths)
+{
+ #if defined(Q_OS_WIN32)
+ char* path_splitter = const_cast<char*>(";");
+ #else
+ char* path_splitter = const_cast<char*>(":");
+ #endif
+ m_typesystemPaths += typesystem_paths.split(path_splitter);
+}
+
+IncludeList TypeDatabase::extraIncludes(const QString& className)
+{
+ ComplexTypeEntry* typeEntry = findComplexType(className);
+ if (typeEntry)
+ return typeEntry->extraIncludes();
+ else
+ return IncludeList();
+}
+
+ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name)
+{
+ QString template_name = name;
+
+ int pos = name.indexOf('<');
+ if (pos > 0)
+ template_name = name.left(pos);
+
+ TypeEntry* type_entry = findType(template_name);
+ if (type_entry && type_entry->isContainer())
+ return static_cast<ContainerTypeEntry*>(type_entry);
+ 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()) {
+ foreach (TypeEntry* e, entries) {
+ if (e && e->isPrimitive()) {
+ PrimitiveTypeEntry *pe = static_cast<PrimitiveTypeEntry*>(e);
+ if (pe->targetLangName() == targetLangName && pe->preferredConversion())
+ return pe;
+ }
+ }
+ }
+
+ return 0;
+}
+
+TypeEntry* TypeDatabase::findType(const QString& name) const
+{
+ QList<TypeEntry *> entries = findTypes(name);
+ foreach (TypeEntry *entry, entries) {
+ if (entry &&
+ (!entry->isPrimitive() || static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
+ return entry;
+ }
+ }
+ return 0;
+}
+
+SingleTypeEntryHash TypeDatabase::entries()
+{
+ TypeEntryHash entries = allEntries();
+
+ SingleTypeEntryHash returned;
+ QList<QString> keys = entries.keys();
+
+ foreach (QString key, keys)
+ returned[key] = findType(key);
+
+ return returned;
+}
+
+QList<const PrimitiveTypeEntry*> TypeDatabase::primitiveTypes()
+{
+ TypeEntryHash entries = allEntries();
+ QList<const PrimitiveTypeEntry*> returned;
+ foreach(QString key, entries.keys()) {
+ foreach(const TypeEntry* typeEntry, entries[key]) {
+ if (typeEntry->isPrimitive())
+ returned.append((PrimitiveTypeEntry*) typeEntry);
+ }
+ }
+ return returned;
+}
+
+QList<const ContainerTypeEntry*> TypeDatabase::containerTypes()
+{
+ TypeEntryHash entries = allEntries();
+ QList<const ContainerTypeEntry*> returned;
+ foreach(QString key, entries.keys()) {
+ foreach(const TypeEntry* typeEntry, entries[key]) {
+ if (typeEntry->isContainer())
+ returned.append((ContainerTypeEntry*) typeEntry);
+ }
+ }
+ return returned;
+}
+void TypeDatabase::addRejection(const QString& className, const QString& functionName,
+ const QString& fieldName, const QString& enumName)
+{
+ TypeRejection r;
+ r.class_name = className;
+ r.function_name = functionName;
+ r.field_name = fieldName;
+ r.enum_name = enumName;
+
+ m_rejections << r;
+}
+
+bool TypeDatabase::isClassRejected(const QString& className)
+{
+ if (!m_rebuildClasses.isEmpty())
+ return !m_rebuildClasses.contains(className);
+
+ foreach (const TypeRejection& r, m_rejections)
+ if (r.class_name == className && r.function_name == "*" && r.field_name == "*" && r.enum_name == "*")
+ return true;
+
+ return false;
+}
+
+bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName)
+{
+ foreach (const TypeRejection& r, m_rejections) {
+ if (r.enum_name == enumName
+ && (r.class_name == className || r.class_name == "*")) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName)
+{
+ foreach (const TypeRejection& r, m_rejections)
+ if (r.function_name == functionName &&
+ (r.class_name == className || r.class_name == "*"))
+ return true;
+ return false;
+}
+
+
+bool TypeDatabase::isFieldRejected(const QString& className, const QString& fieldName)
+{
+ foreach (const TypeRejection& r, m_rejections)
+ if (r.field_name == fieldName &&
+ (r.class_name == className || r.class_name == "*"))
+ return true;
+ return false;
+}
+
+FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const
+{
+ FlagsTypeEntry* fte = (FlagsTypeEntry*) findType(name);
+ return fte ? fte : (FlagsTypeEntry*) m_flagsEntries.value(name);
+}
+
+AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
+{
+ AddedFunctionList addedFunctions;
+ foreach (AddedFunction func, m_globalUserFunctions) {
+ if (func.name() == name)
+ addedFunctions.append(func);
+ }
+ return addedFunctions;
+}
+
+
+QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/)
+{
+ return QLatin1String("Global");
+}
+
+FunctionModificationList TypeDatabase::functionModifications(const QString& signature) const
+{
+ FunctionModificationList lst;
+ for (int i = 0; i < m_functionMods.count(); ++i) {
+ const FunctionModification& mod = m_functionMods.at(i);
+ if (mod.signature == signature)
+ lst << mod;
+ }
+
+ return lst;
+}
+
+bool TypeDatabase::isSuppressedWarning(const QString& s)
+{
+ if (!m_suppressWarnings)
+ return false;
+
+ foreach (const QString &_warning, m_suppressedWarnings) {
+ QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;"));
+
+ QStringList segs = warning.split("*", QString::SkipEmptyParts);
+ if (!segs.size())
+ continue;
+
+ int i = 0;
+ int pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"));
+ //qDebug() << "s == " << s << ", warning == " << segs;
+ while (pos != -1) {
+ if (i == segs.size())
+ return true;
+ pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"), pos);
+ }
+ }
+
+ return false;
+}
+
+QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile)
+{
+ if (!QFile::exists(tsFile)) {
+ int idx = tsFile.lastIndexOf('/');
+ QString fileName = idx >= 0 ? tsFile.right(tsFile.length() - idx - 1) : tsFile;
+ foreach (const QString &path, m_typesystemPaths) {
+ QString filepath(path + '/' + fileName);
+ if (QFile::exists(filepath))
+ return filepath;
+ }
+ }
+ return tsFile;
+}
+
+bool TypeDatabase::parseFile(const QString &filename, bool generate)
+{
+ QString filepath = modifiedTypesystemFilepath(filename);
+ if (m_parsedTypesystemFiles.contains(filepath))
+ return m_parsedTypesystemFiles[filepath];
+
+ QFile file(filepath);
+ if (!file.exists()) {
+ ReportHandler::warning("Can't find " + filename+", typesystem paths: "+m_typesystemPaths.join(", "));
+ return false;
+ }
+
+ int count = m_entries.size();
+ bool ok = parseFile(&file, generate);
+ m_parsedTypesystemFiles[filepath] = ok;
+ int newCount = m_entries.size();
+
+ ReportHandler::debugSparse(QString::fromLatin1("Parsed: '%1', %2 new entries")
+ .arg(filename)
+ .arg(newCount - count));
+ return ok;
+}
+
+bool TypeDatabase::parseFile(QIODevice* device, bool generate)
+{
+ QXmlInputSource source(device);
+ QXmlSimpleReader reader;
+ Handler handler(this, generate);
+
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+
+ return reader.parse(&source, false);
+}
+
+PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name)
+{
+ QList<TypeEntry*> entries = findTypes(name);
+
+ foreach (TypeEntry* entry, entries) {
+ if (entry && entry->isPrimitive() && static_cast<PrimitiveTypeEntry*>(entry)->preferredTargetLangType())
+ return static_cast<PrimitiveTypeEntry*>(entry);
+ }
+
+ return 0;
+}
+
+ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name)
+{
+ TypeEntry* entry = findType(name);
+ if (entry && entry->isComplex())
+ return static_cast<ComplexTypeEntry*>(entry);
+ else
+ return 0;
+}
+
+ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name)
+{
+ TypeEntry* entry = findType(name);
+ if (entry && entry->isObject())
+ return static_cast<ObjectTypeEntry*>(entry);
+ else
+ return 0;
+}
+
+NamespaceTypeEntry* TypeDatabase::findNamespaceType(const QString& name)
+{
+ TypeEntry* entry = findType(name);
+ if (entry && entry->isNamespace())
+ return static_cast<NamespaceTypeEntry*>(entry);
+ else
+ return 0;
+}
+
diff --git a/typedatabase.h b/typedatabase.h
new file mode 100644
index 00000000..3e361e73
--- /dev/null
+++ b/typedatabase.h
@@ -0,0 +1,190 @@
+/*
+ * This file is part of the API Extractor project.
+ *
+ * Copyright (C) 2009-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 TYPEDATABASE_H
+#define TYPEDATABASE_H
+
+#include <QStringList>
+#include "typesystem.h"
+
+class ContainerTypeEntry;
+class PrimitiveTypeEntry;
+class APIEXTRACTOR_API TypeDatabase
+{
+ TypeDatabase();
+ TypeDatabase(const TypeDatabase&);
+ TypeDatabase& operator=(const TypeDatabase&);
+public:
+
+ /**
+ * Return the type system instance.
+ * \param newInstance This parameter is usefull just for unit testing, because singletons causes
+ * too many side effects on unit testing.
+ */
+ static TypeDatabase* instance(bool newInstance = false);
+
+ static QString normalizedSignature(const char* signature);
+
+ QStringList requiredTargetImports();
+
+ void addRequiredTargetImport(const QString& moduleName);
+
+ QStringList typesystemPaths()
+ {
+ return m_typesystemPaths;
+ }
+
+ void addTypesystemPath(const QString& typesystem_paths);
+
+ IncludeList extraIncludes(const QString& className);
+
+ PrimitiveTypeEntry* findPrimitiveType(const QString& name);
+ ComplexTypeEntry* findComplexType(const QString& name);
+ ObjectTypeEntry* findObjectType(const QString& name);
+ NamespaceTypeEntry* findNamespaceType(const QString& name);
+ ContainerTypeEntry* findContainerType(const QString& name);
+ FunctionTypeEntry* findFunctionType(const QString& name);
+
+ TypeEntry* findType(const QString& name) const;
+
+ QList<TypeEntry *> findTypes(const QString &name) const
+ {
+ return m_entries.value(name);
+ }
+
+ TypeEntryHash allEntries()
+ {
+ return m_entries;
+ }
+
+ SingleTypeEntryHash entries();
+
+ PrimitiveTypeEntry *findTargetLangPrimitiveType(const QString &targetLangName);
+
+ QList<const PrimitiveTypeEntry*> primitiveTypes();
+
+ QList<const ContainerTypeEntry*> containerTypes();
+
+ void addRejection(const QString& className, const QString& functionName,
+ const QString& fieldName, const QString& enumName);
+ bool isClassRejected(const QString& className);
+ bool isFunctionRejected(const QString& className, const QString& functionName);
+ bool isFieldRejected(const QString& className, const QString& fieldName);
+ bool isEnumRejected(const QString& className, const QString& enumName);
+
+ void addType(TypeEntry* e)
+ {
+ m_entries[e->qualifiedCppName()].append(e);
+ }
+
+ SingleTypeEntryHash flagsEntries() const
+ {
+ return m_flagsEntries;
+ }
+ FlagsTypeEntry* findFlagsType(const QString& name) const;
+ void addFlagsType(FlagsTypeEntry* fte)
+ {
+ m_flagsEntries[fte->originalName()] = fte;
+ }
+
+ TemplateEntry* findTemplate(const QString& name)
+ {
+ return m_templates[name];
+ }
+
+ void addTemplate(TemplateEntry* t)
+ {
+ m_templates[t->name()] = t;
+ }
+
+ AddedFunctionList globalUserFunctions() const
+ {
+ return m_globalUserFunctions;
+ }
+
+ void addGlobalUserFunctions(const AddedFunctionList& functions)
+ {
+ m_globalUserFunctions << functions;
+ }
+
+ AddedFunctionList findGlobalUserFunctions(const QString& name) const;
+
+ void addGlobalUserFunctionModifications(const FunctionModificationList& functionModifications)
+ {
+ m_functionMods << functionModifications;
+ }
+
+ void addGlobalUserFunctionModification(const FunctionModification& functionModification)
+ {
+ m_functionMods << functionModification;
+ }
+
+ FunctionModificationList functionModifications(const QString& signature) const;
+
+ void setSuppressWarnings(bool on)
+ {
+ m_suppressWarnings = on;
+ }
+
+ void addSuppressedWarning(const QString& s)
+ {
+ m_suppressedWarnings.append(s);
+ }
+
+ bool isSuppressedWarning(const QString& s);
+
+ void setRebuildClasses(const QStringList &cls)
+ {
+ m_rebuildClasses = cls;
+ }
+
+ static QString globalNamespaceClassName(const TypeEntry *te);
+ QString filename() const
+ {
+ return "typesystem.txt";
+ }
+
+ QString modifiedTypesystemFilepath(const QString& tsFile);
+ bool parseFile(const QString &filename, bool generate = true);
+ bool parseFile(QIODevice* device, bool generate = true);
+
+private:
+ bool m_suppressWarnings;
+ TypeEntryHash m_entries;
+ SingleTypeEntryHash m_flagsEntries;
+ TemplateEntryHash m_templates;
+ QStringList m_suppressedWarnings;
+
+ AddedFunctionList m_globalUserFunctions;
+ FunctionModificationList m_functionMods;
+
+ QStringList m_requiredTargetImports;
+
+ QStringList m_typesystemPaths;
+ QHash<QString, bool> m_parsedTypesystemFiles;
+
+ QList<TypeRejection> m_rejections;
+ QStringList m_rebuildClasses;
+};
+
+#endif
diff --git a/typesystem.cpp b/typesystem.cpp
index 32da2ca8..26777756 100644
--- a/typesystem.cpp
+++ b/typesystem.cpp
@@ -22,6 +22,8 @@
*/
#include "typesystem.h"
+#include "typesystem_p.h"
+#include "typedatabase.h"
#include "reporthandler.h"
#include <QtXml>
@@ -31,179 +33,53 @@ static QString strings_char = QLatin1String("char");
static QString strings_jchar = QLatin1String("jchar");
static QString strings_jobject = QLatin1String("jobject");
-class StackElement
-{
-public:
- enum ElementType {
- None = 0x0,
-
- // Type tags (0x1, ... , 0xff)
- ObjectTypeEntry = 0x1,
- ValueTypeEntry = 0x2,
- InterfaceTypeEntry = 0x3,
- NamespaceTypeEntry = 0x4,
- ComplexTypeEntryMask = 0x7,
-
- // Non-complex type tags (0x8, 0x9, ... , 0xf)
- PrimitiveTypeEntry = 0x8,
- EnumTypeEntry = 0x9,
- ContainerTypeEntry = 0xa,
- FunctionTypeEntry = 0xb,
- TypeEntryMask = 0xf,
-
- // Documentation tags
- InjectDocumentation = 0x10,
- ModifyDocumentation = 0x20,
- DocumentationMask = 0xf0,
-
- // Simple tags (0x100, 0x200, ... , 0xf00)
- ExtraIncludes = 0x0100,
- Include = 0x0200,
- ModifyFunction = 0x0300,
- ModifyField = 0x0400,
- Root = 0x0500,
- CustomMetaConstructor = 0x0600,
- CustomMetaDestructor = 0x0700,
- ArgumentMap = 0x0800,
- SuppressedWarning = 0x0900,
- Rejection = 0x0a00,
- LoadTypesystem = 0x0b00,
- RejectEnumValue = 0x0c00,
- Template = 0x0d00,
- TemplateInstanceEnum = 0x0e00,
- Replace = 0x0f00,
- AddFunction = 0x1000,
- SimpleMask = 0x3f00,
-
- // Code snip tags (0x1000, 0x2000, ... , 0xf000)
- InjectCode = 0x4000,
- InjectCodeInFunction = 0x8000,
- CodeSnipMask = 0xc000,
-
- // Function modifier tags (0x010000, 0x020000, ... , 0xf00000)
- Access = 0x010000,
- Removal = 0x020000,
- Rename = 0x040000,
- ModifyArgument = 0x080000,
- Thread = 0x100000,
- FunctionModifiers = 0xff0000,
-
- // Argument modifier tags (0x01000000 ... 0xf0000000)
- ConversionRule = 0x01000000,
- ReplaceType = 0x02000000,
- ReplaceDefaultExpression = 0x04000000,
- RemoveArgument = 0x08000000,
- DefineOwnership = 0x10000000,
- RemoveDefaultExpression = 0x20000000,
- NoNullPointers = 0x40000000,
- ReferenceCount = 0x80000000,
- ParentOwner = 0x90000000,
- ArgumentModifiers = 0xff000000
- };
-
- StackElement(StackElement *p) : entry(0), type(None), parent(p) { }
-
- TypeEntry *entry;
- ElementType type;
- StackElement *parent;
-
- union {
- TemplateInstance *templateInstance;
- TemplateEntry *templateEntry;
- CustomFunction *customFunction;
- } value;
-};
-
-class Handler : public QXmlDefaultHandler
-{
-public:
- Handler(TypeDatabase *database, bool generate)
+Handler::Handler(TypeDatabase* database, bool generate)
: m_database(database), m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
- {
- m_currentEnum = 0;
- m_current = 0;
-
- tagNames["rejection"] = StackElement::Rejection;
- tagNames["primitive-type"] = StackElement::PrimitiveTypeEntry;
- tagNames["container-type"] = StackElement::ContainerTypeEntry;
- tagNames["object-type"] = StackElement::ObjectTypeEntry;
- tagNames["value-type"] = StackElement::ValueTypeEntry;
- 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;
- tagNames["modify-function"] = StackElement::ModifyFunction;
- tagNames["modify-field"] = StackElement::ModifyField;
- tagNames["access"] = StackElement::Access;
- tagNames["remove"] = StackElement::Removal;
- tagNames["rename"] = StackElement::Rename;
- tagNames["typesystem"] = StackElement::Root;
- tagNames["custom-constructor"] = StackElement::CustomMetaConstructor;
- tagNames["custom-destructor"] = StackElement::CustomMetaDestructor;
- tagNames["argument-map"] = StackElement::ArgumentMap;
- tagNames["suppress-warning"] = StackElement::SuppressedWarning;
- tagNames["load-typesystem"] = StackElement::LoadTypesystem;
- tagNames["define-ownership"] = StackElement::DefineOwnership;
- tagNames["replace-default-expression"] = StackElement::ReplaceDefaultExpression;
- tagNames["reject-enum-value"] = StackElement::RejectEnumValue;
- tagNames["replace-type"] = StackElement::ReplaceType;
- tagNames["conversion-rule"] = StackElement::ConversionRule;
- tagNames["modify-argument"] = StackElement::ModifyArgument;
- tagNames["remove-argument"] = StackElement::RemoveArgument;
- tagNames["remove-default-expression"] = StackElement::RemoveDefaultExpression;
- tagNames["template"] = StackElement::Template;
- tagNames["insert-template"] = StackElement::TemplateInstanceEnum;
- tagNames["replace"] = StackElement::Replace;
- tagNames["no-null-pointer"] = StackElement::NoNullPointers;
- tagNames["reference-count"] = StackElement::ReferenceCount;
- tagNames["parent"] = StackElement::ParentOwner;
- tagNames["inject-documentation"] = StackElement::InjectDocumentation;
- tagNames["modify-documentation"] = StackElement::ModifyDocumentation;
- tagNames["add-function"] = StackElement::AddFunction;
- }
-
- bool startElement(const QString &namespaceURI, const QString &localName,
- const QString &qName, const QXmlAttributes &atts);
- bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
-
- QString errorString() const
- {
- return m_error;
- }
- bool error(const QXmlParseException &exception);
- bool fatalError(const QXmlParseException &exception);
- bool warning(const QXmlParseException &exception);
-
- bool characters(const QString &ch);
-
-private:
- void fetchAttributeValues(const QString &name, const QXmlAttributes &atts,
- QHash<QString, QString> *acceptedAttributes);
-
- bool importFileElement(const QXmlAttributes &atts);
- bool convertBoolean(const QString &, const QString &, bool);
-
- TypeDatabase *m_database;
- StackElement* m_current;
- QString m_defaultPackage;
- QString m_defaultSuperclass;
- QString m_error;
- TypeEntry::CodeGeneration m_generate;
-
- EnumTypeEntry *m_currentEnum;
-
- CodeSnipList m_codeSnips;
- AddedFunctionList m_addedFunctions;
- FunctionModificationList m_functionMods;
- FieldModificationList m_fieldMods;
- DocModificationList m_docModifications;
-
- QHash<QString, StackElement::ElementType> tagNames;
- QString m_currentSignature;
-};
+{
+ m_currentEnum = 0;
+ m_current = 0;
+
+ tagNames["rejection"] = StackElement::Rejection;
+ tagNames["primitive-type"] = StackElement::PrimitiveTypeEntry;
+ tagNames["container-type"] = StackElement::ContainerTypeEntry;
+ tagNames["object-type"] = StackElement::ObjectTypeEntry;
+ tagNames["value-type"] = StackElement::ValueTypeEntry;
+ 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;
+ tagNames["modify-function"] = StackElement::ModifyFunction;
+ tagNames["modify-field"] = StackElement::ModifyField;
+ tagNames["access"] = StackElement::Access;
+ tagNames["remove"] = StackElement::Removal;
+ tagNames["rename"] = StackElement::Rename;
+ tagNames["typesystem"] = StackElement::Root;
+ tagNames["custom-constructor"] = StackElement::CustomMetaConstructor;
+ tagNames["custom-destructor"] = StackElement::CustomMetaDestructor;
+ tagNames["argument-map"] = StackElement::ArgumentMap;
+ tagNames["suppress-warning"] = StackElement::SuppressedWarning;
+ tagNames["load-typesystem"] = StackElement::LoadTypesystem;
+ tagNames["define-ownership"] = StackElement::DefineOwnership;
+ tagNames["replace-default-expression"] = StackElement::ReplaceDefaultExpression;
+ tagNames["reject-enum-value"] = StackElement::RejectEnumValue;
+ tagNames["replace-type"] = StackElement::ReplaceType;
+ tagNames["conversion-rule"] = StackElement::ConversionRule;
+ tagNames["modify-argument"] = StackElement::ModifyArgument;
+ tagNames["remove-argument"] = StackElement::RemoveArgument;
+ tagNames["remove-default-expression"] = StackElement::RemoveDefaultExpression;
+ tagNames["template"] = StackElement::Template;
+ tagNames["insert-template"] = StackElement::TemplateInstanceEnum;
+ tagNames["replace"] = StackElement::Replace;
+ tagNames["no-null-pointer"] = StackElement::NoNullPointers;
+ tagNames["reference-count"] = StackElement::ReferenceCount;
+ tagNames["parent"] = StackElement::ParentOwner;
+ tagNames["inject-documentation"] = StackElement::InjectDocumentation;
+ tagNames["modify-documentation"] = StackElement::ModifyDocumentation;
+ tagNames["add-function"] = StackElement::AddFunction;
+}
bool Handler::error(const QXmlParseException &e)
{
@@ -1682,94 +1558,6 @@ bool Handler::startElement(const QString &, const QString &n,
return true;
}
-TypeDatabase *TypeDatabase::instance(bool newInstance)
-{
- static TypeDatabase *db = 0;
- if (!db || newInstance) {
- if (db)
- delete db;
- db = new TypeDatabase;
- }
- return db;
-}
-
-QString TypeDatabase::normalizedSignature(const char* signature)
-{
- QString normalized = QMetaObject::normalizedSignature(signature);
-
- if (!instance() || !QString(signature).contains("unsigned"))
- return normalized;
-
- QStringList types;
- types << "char" << "short" << "int" << "long";
- foreach (const QString& type, types) {
- if (instance()->findType(QString("u%1").arg(type)))
- continue;
- normalized.replace(QRegExp(QString("\\bu%1\\b").arg(type)), QString("unsigned %1").arg(type));
- }
-
- return normalized;
-}
-
-TypeDatabase::TypeDatabase() : m_suppressWarnings(true)
-{
- StringTypeEntry* e = new StringTypeEntry("QXmlStreamStringRef");
- e->setPreferredConversion(false);
- addType(e);
-
- addType(new VoidTypeEntry());
- addType(new VarargsTypeEntry());
-}
-
-QString TypeDatabase::modifiedTypesystemFilepath(const QString &ts_file)
-{
- if (!QFile::exists(ts_file)) {
- int idx = ts_file.lastIndexOf('/');
- QString fileName = idx >= 0 ? ts_file.right(ts_file.length() - idx - 1) : ts_file;
- foreach (const QString &path, m_typesystemPaths) {
- QString filepath(path + '/' + fileName);
- if (QFile::exists(filepath))
- return filepath;
- }
- }
- return ts_file;
-}
-
-bool TypeDatabase::parseFile(const QString &filename, bool generate)
-{
- QString filepath = modifiedTypesystemFilepath(filename);
- if (m_parsedTypesystemFiles.contains(filepath))
- return m_parsedTypesystemFiles[filepath];
-
- QFile file(filepath);
- if (!file.exists()) {
- ReportHandler::warning("Can't find " + filename+", typesystem paths: "+m_typesystemPaths.join(", "));
- return false;
- }
-
- int count = m_entries.size();
- bool ok = parseFile(&file, generate);
- m_parsedTypesystemFiles[filepath] = ok;
- int newCount = m_entries.size();
-
- ReportHandler::debugSparse(QString::fromLatin1("Parsed: '%1', %2 new entries")
- .arg(filename)
- .arg(newCount - count));
- return ok;
-}
-
-bool TypeDatabase::parseFile(QIODevice* device, bool generate)
-{
- QXmlInputSource source(device);
- QXmlSimpleReader reader;
- Handler handler(this, generate);
-
- reader.setContentHandler(&handler);
- reader.setErrorHandler(&handler);
-
- return reader.parse(&source, false);
-}
-
PrimitiveTypeEntry* PrimitiveTypeEntry::basicAliasedTypeEntry() const
{
if (!m_aliasedTypeEntry)
@@ -1782,53 +1570,6 @@ PrimitiveTypeEntry* PrimitiveTypeEntry::basicAliasedTypeEntry() const
return m_aliasedTypeEntry;
}
-ContainerTypeEntry *TypeDatabase::findContainerType(const QString &name)
-{
- QString template_name = name;
-
- int pos = name.indexOf('<');
- if (pos > 0)
- template_name = name.left(pos);
-
- TypeEntry *type_entry = findType(template_name);
- if (type_entry && type_entry->isContainer())
- return static_cast<ContainerTypeEntry *>(type_entry);
- 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()) {
- foreach (TypeEntry *e, entries) {
- if (e && e->isPrimitive()) {
- PrimitiveTypeEntry *pe = static_cast<PrimitiveTypeEntry *>(e);
- if (pe->targetLangName() == targetLangName && pe->preferredConversion())
- return pe;
- }
- }
- }
-
- return 0;
-}
-
-IncludeList TypeDatabase::extraIncludes(const QString &className)
-{
- ComplexTypeEntry *typeEntry = findComplexType(className);
- if (typeEntry)
- return typeEntry->extraIncludes();
- else
- return IncludeList();
-}
-
QString Modification::accessModifierString() const
{
if (isPrivate()) return "private";
@@ -1933,97 +1674,6 @@ QString FlagsTypeEntry::qualifiedTargetLangName() const
return targetLangPackage() + "." + m_enum->targetLangQualifier() + "." + targetLangName();
}
-
-void TypeDatabase::addRejection(const QString &class_name, const QString &function_name,
- const QString &field_name, const QString &enum_name)
-{
- TypeRejection r;
- r.class_name = class_name;
- r.function_name = function_name;
- r.field_name = field_name;
- r.enum_name = enum_name;
-
- m_rejections << r;
-}
-
-bool TypeDatabase::isClassRejected(const QString &class_name)
-{
- if (!m_rebuildClasses.isEmpty())
- return !m_rebuildClasses.contains(class_name);
-
- foreach (const TypeRejection &r, m_rejections)
- if (r.class_name == class_name && r.function_name == "*" && r.field_name == "*" && r.enum_name == "*")
- return true;
-
- return false;
-}
-
-bool TypeDatabase::isEnumRejected(const QString &class_name, const QString &enum_name)
-{
- foreach (const TypeRejection &r, m_rejections) {
- if (r.enum_name == enum_name
- && (r.class_name == class_name || r.class_name == "*")) {
- return true;
- }
- }
-
- return false;
-}
-
-bool TypeDatabase::isFunctionRejected(const QString &class_name, const QString &function_name)
-{
- foreach (const TypeRejection &r, m_rejections)
- if (r.function_name == function_name &&
- (r.class_name == class_name || r.class_name == "*"))
- return true;
- return false;
-}
-
-
-bool TypeDatabase::isFieldRejected(const QString &class_name, const QString &field_name)
-{
- foreach (const TypeRejection &r, m_rejections)
- if (r.field_name == field_name &&
- (r.class_name == class_name || r.class_name == "*"))
- return true;
- return false;
-}
-
-FlagsTypeEntry *TypeDatabase::findFlagsType(const QString &name) const
-{
- FlagsTypeEntry *fte = (FlagsTypeEntry *) findType(name);
- return fte ? fte : (FlagsTypeEntry *) m_flagsEntries.value(name);
-}
-
-AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
-{
- AddedFunctionList addedFunctions;
- foreach (AddedFunction func, m_globalUserFunctions) {
- if (func.name() == name)
- addedFunctions.append(func);
- }
- return addedFunctions;
-}
-
-
-QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/)
-{
- return QLatin1String("Global");
-}
-
-FunctionModificationList TypeDatabase::functionModifications(const QString& signature) const
-{
- FunctionModificationList lst;
- for (int i = 0; i < m_functionMods.count(); ++i) {
- const FunctionModification& mod = m_functionMods.at(i);
- if (mod.signature == signature)
- lst << mod;
- }
-
- return lst;
-}
-
-
/*!
* The Visual Studio 2002 compiler doesn't support these symbols,
* which our typedefs unforntuatly expand to.
diff --git a/typesystem.h b/typesystem.h
index 662cb53e..34f60b0d 100644
--- a/typesystem.h
+++ b/typesystem.h
@@ -1758,272 +1758,6 @@ struct TypeRejection
QString enum_name;
};
-class APIEXTRACTOR_API TypeDatabase
-{
- TypeDatabase();
- TypeDatabase(const TypeDatabase&);
- TypeDatabase& operator=(const TypeDatabase&);
-public:
-
- /**
- * Return the type system instance.
- * \param newInstance This parameter is usefull just for unit testing, because singletons causes
- * too many side effects on unit testing.
- */
- static TypeDatabase *instance(bool newInstance = false);
-
- static QString normalizedSignature(const char* signature);
-
- QStringList requiredTargetImports()
- {
- return m_requiredTargetImports;
- }
-
- void addRequiredTargetImport(const QString &moduleName)
- {
- if (!m_requiredTargetImports.contains(moduleName))
- m_requiredTargetImports << moduleName;
- }
-
- QStringList typesystemPaths()
- {
- return m_typesystemPaths;
- }
- void addTypesystemPath(const QString &typesystem_paths)
- {
-#if defined(Q_OS_WIN32)
- char *path_splitter = const_cast<char *>(";");
-#else
- char *path_splitter = const_cast<char *>(":");
-#endif
- m_typesystemPaths += typesystem_paths.split(path_splitter);
- }
-
- IncludeList extraIncludes(const QString &className);
-
- inline PrimitiveTypeEntry *findPrimitiveType(const QString &name);
- inline ComplexTypeEntry *findComplexType(const QString &name);
- 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
- {
- QList<TypeEntry *> entries = findTypes(name);
- foreach (TypeEntry *entry, entries) {
- if (entry &&
- (!entry->isPrimitive() || static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
- return entry;
- }
- }
- return 0;
- }
- QList<TypeEntry *> findTypes(const QString &name) const
- {
- return m_entries.value(name);
- }
- TypeEntryHash allEntries()
- {
- return m_entries;
- }
-
- SingleTypeEntryHash entries()
- {
- TypeEntryHash entries = allEntries();
-
- SingleTypeEntryHash returned;
- QList<QString> keys = entries.keys();
-
- foreach (QString key, keys)
- returned[key] = findType(key);
-
- return returned;
- }
-
- PrimitiveTypeEntry *findTargetLangPrimitiveType(const QString &targetLangName);
-
- QList<const PrimitiveTypeEntry*> primitiveTypes() {
- TypeEntryHash entries = allEntries();
- QList<const PrimitiveTypeEntry*> returned;
- foreach(QString key, entries.keys()) {
- foreach(const TypeEntry* typeEntry, entries[key]) {
- if (typeEntry->isPrimitive())
- returned.append((PrimitiveTypeEntry*) typeEntry);
- }
- }
- return returned;
- }
- QList<const ContainerTypeEntry*> containerTypes() {
- TypeEntryHash entries = allEntries();
- QList<const ContainerTypeEntry*> returned;
- foreach(QString key, entries.keys()) {
- foreach(const TypeEntry* typeEntry, entries[key]) {
- if (typeEntry->isContainer())
- returned.append((ContainerTypeEntry*) typeEntry);
- }
- }
- return returned;
- }
-
- void addRejection(const QString &class_name, const QString &function_name,
- const QString &field_name, const QString &enum_name);
- bool isClassRejected(const QString &class_name);
- bool isFunctionRejected(const QString &class_name, const QString &function_name);
- bool isFieldRejected(const QString &class_name, const QString &field_name);
- bool isEnumRejected(const QString &class_name, const QString &enum_name);
-
- void addType(TypeEntry *e)
- {
- m_entries[e->qualifiedCppName()].append(e);
- }
-
- SingleTypeEntryHash flagsEntries() const
- {
- return m_flagsEntries;
- }
- FlagsTypeEntry *findFlagsType(const QString &name) const;
- void addFlagsType(FlagsTypeEntry *fte)
- {
- m_flagsEntries[fte->originalName()] = fte;
- }
-
- TemplateEntry *findTemplate(const QString &name)
- {
- return m_templates[name];
- }
- void addTemplate(TemplateEntry *t)
- {
- m_templates[t->name()] = t;
- }
-
- AddedFunctionList globalUserFunctions() const
- {
- return m_globalUserFunctions;
- }
- void addGlobalUserFunctions(const AddedFunctionList& functions)
- {
- m_globalUserFunctions << functions;
- }
- AddedFunctionList findGlobalUserFunctions(const QString& name) const;
-
- void addGlobalUserFunctionModifications(const FunctionModificationList& functionModifications)
- {
- m_functionMods << functionModifications;
- }
- void addGlobalUserFunctionModification(const FunctionModification& functionModification)
- {
- m_functionMods << functionModification;
- }
- FunctionModificationList functionModifications(const QString& signature) const;
-
- void setSuppressWarnings(bool on)
- {
- m_suppressWarnings = on;
- }
- void addSuppressedWarning(const QString &s)
- {
- m_suppressedWarnings.append(s);
- }
-
- bool isSuppressedWarning(const QString &s)
- {
- if (!m_suppressWarnings)
- return false;
-
- foreach (const QString &_warning, m_suppressedWarnings) {
- QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;"));
-
- QStringList segs = warning.split("*", QString::SkipEmptyParts);
- if (!segs.size())
- continue;
-
- int i = 0;
- int pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"));
- //qDebug() << "s == " << s << ", warning == " << segs;
- while (pos != -1) {
- if (i == segs.size())
- return true;
- pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"), pos);
- }
- }
-
- return false;
- }
-
- void setRebuildClasses(const QStringList &cls)
- {
- m_rebuildClasses = cls;
- }
-
- static QString globalNamespaceClassName(const TypeEntry *te);
- QString filename() const
- {
- return "typesystem.txt";
- }
-
- QString modifiedTypesystemFilepath(const QString &ts_file);
- bool parseFile(const QString &filename, bool generate = true);
- bool parseFile(QIODevice* device, bool generate = true);
-
-private:
- bool m_suppressWarnings;
- TypeEntryHash m_entries;
- SingleTypeEntryHash m_flagsEntries;
- TemplateEntryHash m_templates;
- QStringList m_suppressedWarnings;
-
- AddedFunctionList m_globalUserFunctions;
- FunctionModificationList m_functionMods;
-
- QStringList m_requiredTargetImports;
-
- QStringList m_typesystemPaths;
- QHash<QString, bool> m_parsedTypesystemFiles;
-
- QList<TypeRejection> m_rejections;
- QStringList m_rebuildClasses;
-};
-
-inline PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name)
-{
- QList<TypeEntry *> entries = findTypes(name);
-
- foreach (TypeEntry *entry, entries) {
- if (entry && entry->isPrimitive() && static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())
- return static_cast<PrimitiveTypeEntry *>(entry);
- }
-
- return 0;
-}
-
-inline ComplexTypeEntry *TypeDatabase::findComplexType(const QString &name)
-{
- TypeEntry *entry = findType(name);
- if (entry && entry->isComplex())
- return static_cast<ComplexTypeEntry *>(entry);
- else
- return 0;
-}
-
-inline ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name)
-{
- TypeEntry *entry = findType(name);
- if (entry && entry->isObject())
- return static_cast<ObjectTypeEntry *>(entry);
- else
- return 0;
-}
-
-inline NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name)
-{
- TypeEntry *entry = findType(name);
- if (entry && entry->isNamespace())
- return static_cast<NamespaceTypeEntry *>(entry);
- else
- return 0;
-}
-
QString fixCppTypeName(const QString &name);
#endif // TYPESYSTEM_H
diff --git a/typesystem_p.h b/typesystem_p.h
new file mode 100644
index 00000000..a62056db
--- /dev/null
+++ b/typesystem_p.h
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the API Extractor project.
+ *
+ * Copyright (C) 2009-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 TYPESYSTEM_P_H
+#define TYPESYSTEM_P_H
+
+#include <QXmlDefaultHandler>
+#include "typesystem.h"
+
+class TypeDatabase;
+class StackElement
+{
+ public:
+ enum ElementType {
+ None = 0x0,
+
+ // Type tags (0x1, ... , 0xff)
+ ObjectTypeEntry = 0x1,
+ ValueTypeEntry = 0x2,
+ InterfaceTypeEntry = 0x3,
+ NamespaceTypeEntry = 0x4,
+ ComplexTypeEntryMask = 0x7,
+
+ // Non-complex type tags (0x8, 0x9, ... , 0xf)
+ PrimitiveTypeEntry = 0x8,
+ EnumTypeEntry = 0x9,
+ ContainerTypeEntry = 0xa,
+ FunctionTypeEntry = 0xb,
+ TypeEntryMask = 0xf,
+
+ // Documentation tags
+ InjectDocumentation = 0x10,
+ ModifyDocumentation = 0x20,
+ DocumentationMask = 0xf0,
+
+ // Simple tags (0x100, 0x200, ... , 0xf00)
+ ExtraIncludes = 0x0100,
+ Include = 0x0200,
+ ModifyFunction = 0x0300,
+ ModifyField = 0x0400,
+ Root = 0x0500,
+ CustomMetaConstructor = 0x0600,
+ CustomMetaDestructor = 0x0700,
+ ArgumentMap = 0x0800,
+ SuppressedWarning = 0x0900,
+ Rejection = 0x0a00,
+ LoadTypesystem = 0x0b00,
+ RejectEnumValue = 0x0c00,
+ Template = 0x0d00,
+ TemplateInstanceEnum = 0x0e00,
+ Replace = 0x0f00,
+ AddFunction = 0x1000,
+ SimpleMask = 0x3f00,
+
+ // Code snip tags (0x1000, 0x2000, ... , 0xf000)
+ InjectCode = 0x4000,
+ InjectCodeInFunction = 0x8000,
+ CodeSnipMask = 0xc000,
+
+ // Function modifier tags (0x010000, 0x020000, ... , 0xf00000)
+ Access = 0x010000,
+ Removal = 0x020000,
+ Rename = 0x040000,
+ ModifyArgument = 0x080000,
+ Thread = 0x100000,
+ FunctionModifiers = 0xff0000,
+
+ // Argument modifier tags (0x01000000 ... 0xf0000000)
+ ConversionRule = 0x01000000,
+ ReplaceType = 0x02000000,
+ ReplaceDefaultExpression = 0x04000000,
+ RemoveArgument = 0x08000000,
+ DefineOwnership = 0x10000000,
+ RemoveDefaultExpression = 0x20000000,
+ NoNullPointers = 0x40000000,
+ ReferenceCount = 0x80000000,
+ ParentOwner = 0x90000000,
+ ArgumentModifiers = 0xff000000
+ };
+
+ StackElement(StackElement *p) : entry(0), type(None), parent(p) { }
+
+ TypeEntry* entry;
+ ElementType type;
+ StackElement *parent;
+
+ union {
+ TemplateInstance* templateInstance;
+ TemplateEntry* templateEntry;
+ CustomFunction* customFunction;
+ } value;
+};
+
+class Handler : public QXmlDefaultHandler
+{
+public:
+ Handler(TypeDatabase* database, bool generate);
+
+ bool startElement(const QString& namespaceURI, const QString& localName,
+ const QString& qName, const QXmlAttributes& atts);
+ bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName);
+
+ QString errorString() const
+ {
+ return m_error;
+ }
+
+ bool error(const QXmlParseException &exception);
+ bool fatalError(const QXmlParseException &exception);
+ bool warning(const QXmlParseException &exception);
+
+ bool characters(const QString &ch);
+
+private:
+ void fetchAttributeValues(const QString &name, const QXmlAttributes &atts,
+ QHash<QString, QString> *acceptedAttributes);
+
+ bool importFileElement(const QXmlAttributes &atts);
+ bool convertBoolean(const QString &, const QString &, bool);
+
+ TypeDatabase *m_database;
+ StackElement* m_current;
+ QString m_defaultPackage;
+ QString m_defaultSuperclass;
+ QString m_error;
+ TypeEntry::CodeGeneration m_generate;
+
+ EnumTypeEntry* m_currentEnum;
+
+ CodeSnipList m_codeSnips;
+ AddedFunctionList m_addedFunctions;
+ FunctionModificationList m_functionMods;
+ FieldModificationList m_fieldMods;
+ DocModificationList m_docModifications;
+
+ QHash<QString, StackElement::ElementType> tagNames;
+ QString m_currentSignature;
+};
+
+#endif