Mercurial > projects > qtd
diff generator/typesystem.h @ 1:e78566595089
initial import
author | mandel |
---|---|
date | Mon, 11 May 2009 16:01:50 +0000 |
parents | |
children | 0a29ce1ae854 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generator/typesystem.h Mon May 11 16:01:50 2009 +0000 @@ -0,0 +1,1246 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Nokia. All rights reserved. +** +** This file is part of Qt Jambi. +** +** * Commercial Usage +* Licensees holding valid Qt Commercial licenses may use this file in +* accordance with the Qt Commercial License Agreement provided with the +* Software or, alternatively, in accordance with the terms contained in +* a written agreement between you and Nokia. +* +* +* GNU General Public License Usage +* Alternatively, this file may be used under the terms of the GNU +* General Public License versions 2.0 or 3.0 as published by the Free +* Software Foundation and appearing in the file LICENSE.GPL included in +* the packaging of this file. Please review the following information +* to ensure GNU General Public Licensing requirements will be met: +* http://www.fsf.org/licensing/licenses/info/GPLv2.html and +* http://www.gnu.org/copyleft/gpl.html. In addition, as a special +* exception, Nokia gives you certain additional rights. These rights +* are described in the Nokia Qt GPL Exception version 1.2, included in +* the file GPL_EXCEPTION.txt in this package. +* +* Qt for Windows(R) Licensees +* As a special exception, Nokia, as the sole copyright holder for Qt +* Designer, grants users of the Qt/Eclipse Integration plug-in the +* right for the Qt/Eclipse Integration to link to functionality +* provided by Qt Designer and its related libraries. +* +* +* If you are unsure which license is appropriate for your use, please +* contact the sales department at qt-sales@nokia.com. + +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef TYPESYSTEM_H +#define TYPESYSTEM_H + +#include <QtCore/QHash> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QMap> +#include <QDebug> + +class Indentor; + +class AbstractMetaType; +class QTextStream; + +class EnumTypeEntry; +class FlagsTypeEntry; + +extern QString strings_Object; +extern QString strings_String; +extern QString strings_Thread; +extern QString strings_char; +extern QString strings_java_lang; +extern QString strings_jchar; +extern QString strings_jobject; + +struct Include +{ + enum IncludeType { + IncludePath, + LocalPath, + TargetLangImport + }; + + Include() : type(IncludePath) { } + Include(IncludeType t, const QString &nam) : type(t), name(nam) { }; + + bool isValid() { return !name.isEmpty(); } + + IncludeType type; + QString name; + + QString toString() const; + + bool operator<(const Include &other) const { return name < other.name; } +}; +typedef QList<Include> IncludeList; + +typedef QMap<int, QString> ArgumentMap; + +class TemplateInstance; + +namespace TypeSystem { + enum Language { + NoLanguage = 0x0000, + TargetLangCode = 0x0001, + NativeCode = 0x0002, + ShellCode = 0x0004, + ShellDeclaration = 0x0008, + PackageInitializer = 0x0010, + DestructorFunction = 0x0020, + Constructors = 0x0040, + Interface = 0x0080, + + // masks + All = TargetLangCode + | NativeCode + | ShellCode + | ShellDeclaration + | PackageInitializer + | Constructors + | Interface + | DestructorFunction, + + JavaAndNativeCode = TargetLangCode | NativeCode, + TargetLangAndNativeCode = TargetLangCode | NativeCode + }; + + enum Ownership { + InvalidOwnership, + DefaultOwnership, + TargetLangOwnership, + CppOwnership + }; +}; + +struct ReferenceCount +{ + ReferenceCount() : threadSafe(false), access(Public) { } + enum Action { // 0x01 - 0xff + Invalid = 0x00, + Add = 0x01, + AddAll = 0x02, + Remove = 0x04, + Set = 0x08, + Ignore = 0x10, + + ActionsMask = 0xff, + + Padding = 0xffffffff + }; + + enum Flag { // 0x100 - 0xf00 + ThreadSafe = 0x100, + Static = 0x200, + DeclareVariable = 0x400, + + FlagsMask = 0xf00 + }; + + enum Access { // 0x1000 - 0xf000 + Private = 0x1000, + Protected = 0x2000, + Friendly = 0x3000, + Public = 0x4000, + + AccessMask = 0xf000 + }; + + Action action; + QString variableName; + QString conditional; + QString declareVariable; + + uint threadSafe : 1; + + uint access; +}; + +class CodeSnipFragment{ + private: + const QString m_code; + TemplateInstance *m_instance; + + public: + CodeSnipFragment(const QString &code) + : m_code(code), + m_instance(0) + {} + + CodeSnipFragment(TemplateInstance *instance) + : m_instance(instance) + {} + + QString code() const; +}; + +class CodeSnipAbstract{ +public: + QString code() const; + + void addCode(const QString &code){ + codeList.append(new CodeSnipFragment(code)); + } + + void addTemplateInstance(TemplateInstance *ti){ + codeList.append(new CodeSnipFragment(ti)); + } + + QList<CodeSnipFragment*> codeList; +}; + +class CustomFunction : public CodeSnipAbstract +{ + public: + CustomFunction(const QString &n = QString()) : name(n) { } + + QString name; + QString param_name; +}; + +class TemplateEntry : public CodeSnipAbstract +{ +public: + TemplateEntry(const QString &name) + : m_name(name) + { + }; + + QString name() const { + return m_name; + }; + +private: + QString m_name; +}; + +typedef QHash<QString, TemplateEntry *> TemplateEntryHash; + +class TemplateInstance +{ + public: + TemplateInstance(const QString &name) + : m_name(name) + {} + + void addReplaceRule(const QString &name, const QString &value){ + replaceRules[name]=value; + } + + QString expandCode() const; + + QString name() const { + return m_name; + } + + private: + const QString m_name; + QHash<QString, QString> replaceRules; +}; + + +class CodeSnip : public CodeSnipAbstract +{ + public: + enum Position { + Beginning, + End, + AfterThis + }; + + CodeSnip() : language(TypeSystem::TargetLangCode) { } + CodeSnip(TypeSystem::Language lang) : language(lang) { } + + // Very simple, easy to make code ugly if you try + QTextStream &formattedCode(QTextStream &s, Indentor &indentor) const; + + TypeSystem::Language language; + Position position; + ArgumentMap argumentMap; +}; +typedef QList<CodeSnip> CodeSnipList; + +struct ArgumentModification +{ + ArgumentModification(int idx) : removed_default_expression(false), removed(false), no_null_pointers(false), index(idx) + {} + + // Should the default expression be removed? + uint removed_default_expression : 1; + uint removed : 1; + uint no_null_pointers : 1; + uint reset_after_use : 1; + + // The index of this argument + int index; + + // Reference count flags for this argument + QList<ReferenceCount> referenceCounts; + + // The text given for the new type of the argument + QString modified_type; + + QString replace_value; + + // The code to be used to construct a return value when no_null_pointers is true and + // the returned value is null. If no_null_pointers is true and this string is + // empty, then the base class implementation will be used (or a default construction + // if there is no implementation) + QString null_pointer_default_value; + + // The text of the new default expression of the argument + QString replaced_default_expression; + + // The new definition of ownership for a specific argument + QHash<TypeSystem::Language, TypeSystem::Ownership> ownerships; + + // Different conversion rules + CodeSnipList conversion_rules; +}; + +struct Modification { + enum Modifiers { + Private = 0x0001, + Protected = 0x0002, + Public = 0x0003, + Friendly = 0x0004, + AccessModifierMask = 0x000f, + + Final = 0x0010, + NonFinal = 0x0020, + FinalMask = Final | NonFinal, + + Readable = 0x0100, + Writable = 0x0200, + + CodeInjection = 0x1000, + Rename = 0x2000, + Deprecated = 0x4000, + ReplaceExpression = 0x8000, + VirtualSlot = 0x10000 | NonFinal + }; + + Modification() : modifiers(0) { } + + bool isAccessModifier() const { return modifiers & AccessModifierMask; } + Modifiers accessModifier() const { return Modifiers(modifiers & AccessModifierMask); } + bool isPrivate() const { return accessModifier() == Private; } + bool isProtected() const { return accessModifier() == Protected; } + bool isPublic() const { return accessModifier() == Public; } + bool isFriendly() const { return accessModifier() == Friendly; } + bool isFinal() const { return modifiers & Final; } + bool isNonFinal() const { return modifiers & NonFinal; } + bool isVirtualSlot() const { return (modifiers & VirtualSlot) == VirtualSlot; } + QString accessModifierString() const; + + bool isDeprecated() const { return modifiers & Deprecated; } + + void setRenamedTo(const QString &name) { renamedToName = name; } + QString renamedTo() const { return renamedToName; } + bool isRenameModifier() const { return modifiers & Rename; } + + uint modifiers; + QString renamedToName; +}; + +struct FunctionModification: public Modification +{ + FunctionModification() : removal(TypeSystem::NoLanguage), store_result(false) { } + + bool isCodeInjection() const { return modifiers & CodeInjection; } + bool isRemoveModifier() const { return removal != TypeSystem::NoLanguage; } + + QString toString() const; + + QString signature; + QString association; + CodeSnipList snips; + TypeSystem::Language removal; + bool store_result; + + QList<ArgumentModification> argument_mods; +}; +typedef QList<FunctionModification> FunctionModificationList; + +struct FieldModification: public Modification +{ + bool isReadable() const { return modifiers & Readable; } + bool isWritable() const { return modifiers & Writable; } + + QString name; +}; +typedef QList<FieldModification> FieldModificationList; + +struct ExpensePolicy { + ExpensePolicy() : limit(-1) { } + int limit; + QString cost; + bool isValid() const { return limit >= 0; } +}; + +class InterfaceTypeEntry; +class ObjectTypeEntry; + +class TypeEntry +{ +public: + enum Type { + PrimitiveType, + VoidType, + FlagsType, + EnumType, + TemplateArgumentType, + ThreadType, + BasicValueType, + StringType, + ContainerType, + InterfaceType, + ObjectType, + NamespaceType, + VariantType, + JObjectWrapperType, + CharType, + ArrayType, + TypeSystemType, + CustomType, + }; + + enum CodeGeneration { + GenerateTargetLang = 0x0001, + GenerateCpp = 0x0002, + GenerateForSubclass = 0x0004, + + GenerateNothing = 0, + GenerateAll = 0xffff, + GenerateCode = GenerateTargetLang | GenerateCpp + }; + + TypeEntry(const QString &name, Type t) + : m_name(name), + m_type(t), + m_code_generation(GenerateAll), + m_preferred_conversion(true) + { + }; + + virtual ~TypeEntry() { } + + Type type() const { return m_type; } + bool isPrimitive() const { return m_type == PrimitiveType; } + bool isEnum() const { return m_type == EnumType; } + bool isFlags() const { return m_type == FlagsType; } + bool isInterface() const { return m_type == InterfaceType; } + bool isObject() const { return m_type == ObjectType; } + bool isString() const { return m_type == StringType; } + bool isChar() const { return m_type == CharType; } + bool isNamespace() const { return m_type == NamespaceType; } + bool isContainer() const { return m_type == ContainerType; } + bool isVariant() const { return m_type == VariantType; } + bool isJObjectWrapper() const { return m_type == JObjectWrapperType; } + bool isArray() const { return m_type == ArrayType; } + bool isTemplateArgument() const { return m_type == TemplateArgumentType; } + bool isVoid() const { return m_type == VoidType; } + bool isThread() const { return m_type == ThreadType; } + bool isCustom() const { return m_type == CustomType; } + bool isBasicValue() const { return m_type == BasicValueType; } + bool isTypeSystem() const { return m_type == TypeSystemType; } + + virtual bool preferredConversion() const { return m_preferred_conversion; } + virtual void setPreferredConversion(bool b) { m_preferred_conversion = b; } + + virtual QString javaQualifier() const { return QString(); } + + // The type's name in C++, fully qualified + QString name() const { return m_name; } + + uint codeGeneration() const { return m_code_generation; } + void setCodeGeneration(uint cg) { m_code_generation = cg; } + + virtual QString qualifiedCppName() const { return m_name; } + + // Its type's name in JNI + virtual QString jniName() const { return m_name; } + + // The type's name in TargetLang + virtual QString targetLangName() const { return m_name; } + + // The type to lookup when converting to TargetLang + virtual QString lookupName() const { return targetLangName(); } + + // The package + virtual QString javaPackage() const { return QString(); } + + virtual QString qualifiedTargetLangName() const { +// QString pkg = javaPackage(); +/* if (pkg.isEmpty())*/ return targetLangName(); +// return pkg + '.' + targetLangName(); + } + + virtual InterfaceTypeEntry *designatedInterface() const { return 0; } + + void setCustomConstructor(const CustomFunction &func) { m_customConstructor = func; } + CustomFunction customConstructor() const { return m_customConstructor; } + + void setCustomDestructor(const CustomFunction &func) { m_customDestructor = func; } + CustomFunction customDestructor() const { return m_customDestructor; } + + virtual bool isValue() const { return false; } + virtual bool isComplex() const { return false; } + + virtual bool isNativeIdBased() const { return false; } + + // qtd + virtual bool isStructInD() const { return false; } + +private: + QString m_name; + Type m_type; + uint m_code_generation; + CustomFunction m_customConstructor; + CustomFunction m_customDestructor; + bool m_preferred_conversion; +}; +typedef QHash<QString, QList<TypeEntry *> > TypeEntryHash; +typedef QHash<QString, TypeEntry *> SingleTypeEntryHash; + + +class TypeSystemTypeEntry : public TypeEntry +{ +public: + TypeSystemTypeEntry(const QString &name) + : TypeEntry(name, TypeSystemType) + { + }; + + QList<CodeSnip> snips; +}; + + +class ThreadTypeEntry : public TypeEntry +{ +public: + ThreadTypeEntry() : TypeEntry("QThread", ThreadType) { setCodeGeneration(GenerateNothing); } + + QString jniName() const { return strings_jobject; } + QString targetLangName() const { return strings_Thread; } + QString javaPackage() const { return strings_java_lang; } +}; + +class VoidTypeEntry : public TypeEntry +{ +public: + VoidTypeEntry() : TypeEntry("void", VoidType) { } +}; + +class TemplateArgumentEntry : public TypeEntry +{ +public: + TemplateArgumentEntry(const QString &name) + : TypeEntry(name, TemplateArgumentType), m_ordinal(0) + { + } + + int ordinal() const { return m_ordinal; } + void setOrdinal(int o) { m_ordinal = o; } + +private: + int m_ordinal; +}; + +class ArrayTypeEntry : public TypeEntry +{ +public: + ArrayTypeEntry(const TypeEntry *nested_type) : TypeEntry("Array", ArrayType), m_nested_type(nested_type) + { + Q_ASSERT(m_nested_type); + } + + void setNestedTypeEntry(TypeEntry *nested) { m_nested_type = nested; } + const TypeEntry *nestedTypeEntry() const { return m_nested_type; } + + QString targetLangName() const { return m_nested_type->targetLangName() + "[]"; } + QString jniName() const + { + if (m_nested_type->isPrimitive()) + return m_nested_type->jniName() + "Array"; + else + return "jobjectArray"; + } + +private: + const TypeEntry *m_nested_type; +}; + + +class PrimitiveTypeEntry : public TypeEntry +{ +public: + PrimitiveTypeEntry(const QString &name) + : TypeEntry(name, PrimitiveType), m_preferred_conversion(true), m_preferred_java_type(true) + { + } + + QString targetLangName() const { return m_java_name; } + void setTargetLangName(const QString &targetLangName) { m_java_name = targetLangName; } + + QString jniName() const { return m_jni_name; } + void setJniName(const QString &jniName) { m_jni_name = jniName; } + + QString javaObjectFullName() const { return javaObjectPackage() + "." + javaObjectName(); } + QString javaObjectName() const; + QString javaObjectPackage() const { return strings_java_lang; } + + virtual bool preferredConversion() const { return m_preferred_conversion; } + virtual void setPreferredConversion(bool b) { m_preferred_conversion = b; } + + virtual bool preferredTargetLangType() const { return m_preferred_java_type; } + virtual void setPreferredTargetLangType(bool b) { m_preferred_java_type = b; } + +private: + QString m_java_name; + QString m_jni_name; + uint m_preferred_conversion : 1; + uint m_preferred_java_type : 1; +}; + + + + +struct EnumValueRedirection +{ + EnumValueRedirection(const QString &rej, const QString &us) + : rejected(rej), + used(us) + { + } + QString rejected; + QString used; +}; + +class EnumTypeEntry : public TypeEntry +{ +public: + EnumTypeEntry(const QString &nspace, const QString &enumName) + : TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName, + EnumType), + m_flags(0), + m_extensible(false) + { + m_qualifier = nspace; + m_java_name = enumName; + } + + QString javaPackage() const { return m_package_name; } + void setTargetLangPackage(const QString &package) { m_package_name = package; } + + QString targetLangName() const { return m_java_name; } + QString javaQualifier() const; + QString qualifiedTargetLangName() const { + return javaQualifier() + '_' + targetLangName(); +// return targetLangName(); + } + + QString jniName() const; + + QString qualifier() const { return m_qualifier; } + void setQualifier(const QString &q) { m_qualifier = q; } + + virtual bool preferredConversion() const { return false; } + + bool isBoundsChecked() const { return m_lower_bound.isEmpty() && m_upper_bound.isEmpty(); } + + QString upperBound() const { return m_upper_bound; } + void setUpperBound(const QString &bound) { m_upper_bound = bound; } + + QString lowerBound() const { return m_lower_bound; } + void setLowerBound(const QString &bound) { m_lower_bound = bound; } + + void setFlags(FlagsTypeEntry *flags) { m_flags = flags; } + FlagsTypeEntry *flags() const { return m_flags; } + + bool isExtensible() const { return m_extensible; } + void setExtensible(bool is) { m_extensible = is; } + + bool isEnumValueRejected(const QString &name) { return m_rejected_enums.contains(name); } + void addEnumValueRejection(const QString &name) { m_rejected_enums << name; } + QStringList enumValueRejections() const { return m_rejected_enums; } + + void addEnumValueRedirection(const QString &rejected, const QString &usedValue); + QString enumValueRedirection(const QString &value) const; + + bool forceInteger() const { return m_force_integer; } + void setForceInteger(bool force) { m_force_integer = force; } + +private: + QString m_package_name; + QString m_qualifier; + QString m_java_name; + + QString m_lower_bound; + QString m_upper_bound; + + QStringList m_rejected_enums; + QList<EnumValueRedirection> m_enum_redirections; + + FlagsTypeEntry *m_flags; + + bool m_extensible; + bool m_force_integer; +}; + +class FlagsTypeEntry : public TypeEntry +{ +public: + FlagsTypeEntry(const QString &name) : TypeEntry(name, FlagsType), m_enum(0) + { + } + + QString qualifiedTargetLangName() const; + QString targetLangName() const { return m_java_name; } + QString jniName() const; + virtual bool preferredConversion() const { return false; } + + QString originalName() const { return m_original_name; } + void setOriginalName(const QString &s) { m_original_name = s; } + + QString flagsName() const { return m_java_name; } + void setFlagsName(const QString &name) { m_java_name = name; } + + bool forceInteger() const { return m_enum->forceInteger(); } + + EnumTypeEntry *originator() const { return m_enum; } + void setOriginator(EnumTypeEntry *e) { m_enum = e; } + + QString javaPackage() const { return m_enum->javaPackage(); } + QString javaQualifier() const { return m_enum->javaQualifier(); } + QString qualifier() const { return m_enum->qualifier(); } + +private: + QString m_original_name; + QString m_java_name; + EnumTypeEntry *m_enum; +}; + + +class ComplexTypeEntry : public TypeEntry +{ +public: + enum TypeFlag { + ForceAbstract = 0x1, + DeleteInMainThread = 0x2, + Deprecated = 0x4 + }; + typedef QFlags<TypeFlag> TypeFlags; + + ComplexTypeEntry(const QString &name, Type t) + : TypeEntry(QString(name).replace("::", "_"), t), + m_qualified_cpp_name(name), + m_qobject(false), + m_polymorphic_base(false), + m_generic_class(false), + m_type_flags(0), + m_isStructInD(false), + m_isAbstract(false) + { + Include inc; + inc.name = "QVariant"; + inc.type = Include::IncludePath; + + addExtraInclude(inc); + } + + bool isComplex() const { return true; } + + IncludeList extraIncludes() const { return m_extra_includes; } + void setExtraIncludes(const IncludeList &includes) { m_extra_includes = includes; } + void addExtraInclude(const Include &include) + { + if (!m_includes_used.value(include.name, false)) { + m_extra_includes << include; + m_includes_used[include.name] = true; + } + } + + ComplexTypeEntry *copy() const + { + ComplexTypeEntry *centry = new ComplexTypeEntry(name(), type()); + centry->setInclude(include()); + centry->setExtraIncludes(extraIncludes()); + centry->setFunctionModifications(functionModifications()); + centry->setFieldModifications(fieldModifications()); + centry->setQObject(isQObject()); + centry->setDefaultSuperclass(defaultSuperclass()); + centry->setCodeSnips(codeSnips()); + centry->setTargetLangPackage(javaPackage()); + + return centry; + } + + void setLookupName(const QString &name) + { + m_lookup_name = name; + } + + virtual QString lookupName() const + { + return m_lookup_name.isEmpty() ? targetLangName() : m_lookup_name; + } + + QString jniName() const { return strings_jobject; } + + + Include include() const { return m_include; } + void setInclude(const Include &inc) { m_include = inc; } + + void setTypeFlags(TypeFlags flags) + { + m_type_flags = flags; + } + + TypeFlags typeFlags() const + { + return m_type_flags; + } + + CodeSnipList codeSnips() const { return m_code_snips; } + void setCodeSnips(const CodeSnipList &codeSnips) { m_code_snips = codeSnips; } + void addCodeSnip(const CodeSnip &codeSnip) { m_code_snips << codeSnip; } + + FunctionModificationList functionModifications() const { return m_function_mods; } + void setFunctionModifications(const FunctionModificationList &functionModifications) { + m_function_mods = functionModifications; + } + void addFunctionModification(const FunctionModification &functionModification) { + m_function_mods << functionModification; + } + FunctionModificationList functionModifications(const QString &signature) const; + + FieldModification fieldModification(const QString &name) const; + void setFieldModifications(const FieldModificationList &mods) { m_field_mods = mods; } + FieldModificationList fieldModifications() const { return m_field_mods; } + + QString javaPackage() const { return m_package; } + void setTargetLangPackage(const QString &package) { m_package = package; } + + bool isQObject() const { return m_qobject; } + void setQObject(bool qobject) { m_qobject = qobject; } + + QString defaultSuperclass() const { return m_default_superclass; } + void setDefaultSuperclass(const QString &sc) { m_default_superclass = sc; } + + virtual QString qualifiedCppName() const { return m_qualified_cpp_name; } + + + void setIsPolymorphicBase(bool on) + { + m_polymorphic_base = on; + } + bool isPolymorphicBase() const { return m_polymorphic_base; } + + void setPolymorphicIdValue(const QString &value) + { + m_polymorphic_id_value = value; + } + QString polymorphicIdValue() const { return m_polymorphic_id_value; } + + void setExpensePolicy(const ExpensePolicy &policy) { m_expense_policy = policy; } + const ExpensePolicy &expensePolicy() const { return m_expense_policy; } + + QString targetType() const { return m_target_type; } + void setTargetType(const QString &code) { m_target_type = code; } + + QString targetLangName() const { return m_java_name.isEmpty() + ? TypeEntry::targetLangName() + : m_java_name; + } + void setTargetLangName(const QString &name) { m_java_name = name; } + + bool isGenericClass() const { return m_generic_class; } + void setGenericClass(bool isGeneric) { m_generic_class = isGeneric; } + + QString injectedImports; + + // qtd + bool isStructInD() const { return m_isStructInD; } + void setStructInD(bool isStruct) { m_isStructInD = isStruct; } + + bool isAbstract() const { return m_isAbstract; } + void setAbstract(bool isAbstract) { m_isAbstract = isAbstract; } + + QString addedTo; + QStringList includedClasses; + + +private: + IncludeList m_extra_includes; + Include m_include; + QHash<QString, bool> m_includes_used; + FunctionModificationList m_function_mods; + FieldModificationList m_field_mods; + CodeSnipList m_code_snips; + QString m_package; + QString m_default_superclass; + QString m_qualified_cpp_name; + QString m_java_name; + + uint m_qobject : 1; + uint m_polymorphic_base : 1; + uint m_generic_class : 1; + + QString m_polymorphic_id_value; + QString m_lookup_name; + QString m_target_type; + ExpensePolicy m_expense_policy; + TypeFlags m_type_flags; + + // qtd + bool m_isStructInD; + bool m_isAbstract; +}; + +class ContainerTypeEntry : public ComplexTypeEntry +{ +public: + enum Type { + NoContainer, + ListContainer, + StringListContainer, + LinkedListContainer, + VectorContainer, + StackContainer, + QueueContainer, + SetContainer, + MapContainer, + MultiMapContainer, + HashContainer, + MultiHashContainer, + PairContainer, + }; + + ContainerTypeEntry(const QString &name, Type type) + : ComplexTypeEntry(name, ContainerType) + { + m_type = type; + setCodeGeneration(GenerateForSubclass); + } + + Type type() const { return m_type; } + QString targetLangName() const; + QString javaPackage() const; + QString qualifiedCppName() const; + +private: + Type m_type; +}; + + +class NamespaceTypeEntry : public ComplexTypeEntry +{ +public: + NamespaceTypeEntry(const QString &name) : ComplexTypeEntry(name, NamespaceType) { } +}; + + +class ValueTypeEntry : public ComplexTypeEntry +{ +public: + ValueTypeEntry(const QString &name) : ComplexTypeEntry(name, BasicValueType) { } + + bool isValue() const { return true; } + + virtual bool isNativeIdBased() const { return true; } + +protected: + ValueTypeEntry(const QString &name, Type t) : ComplexTypeEntry(name, t) { } +}; + + +class StringTypeEntry : public ValueTypeEntry +{ +public: + StringTypeEntry(const QString &name) + : ValueTypeEntry(name, StringType) + { + setCodeGeneration(GenerateNothing); + } + + QString jniName() const { return strings_jobject; } + QString targetLangName() const { return strings_String; } + QString javaPackage() const { return strings_java_lang; } + + virtual bool isNativeIdBased() const { return false; } +}; + +class CharTypeEntry : public ValueTypeEntry +{ +public: + CharTypeEntry(const QString &name) : ValueTypeEntry(name, CharType) + { + setCodeGeneration(GenerateNothing); + } + + QString jniName() const { return strings_jchar; } + QString targetLangName() const { return strings_char; } + QString javaPackage() const { return QString(); } + + virtual bool isNativeIdBased() const { return false; } +}; + +class JObjectWrapperTypeEntry: public ValueTypeEntry +{ +public: + JObjectWrapperTypeEntry(const QString &name) : ValueTypeEntry(name, JObjectWrapperType) { } + + QString jniName() const { return strings_jobject; } + QString targetLangName() const { return strings_Object; } + QString javaPackage() const { return strings_java_lang; } + + bool isNativeIdBased() const { return false; } +}; + +class VariantTypeEntry: public ValueTypeEntry +{ +public: + VariantTypeEntry(const QString &name) : ValueTypeEntry(name, VariantType) { } + + QString jniName() const { return strings_jobject; } + QString targetLangName() const { return "QVariant"; } + QString javaPackage() const { return "qt.core"; } + virtual bool isNativeIdBased() const { return false; } +}; + + +class InterfaceTypeEntry : public ComplexTypeEntry +{ +public: + InterfaceTypeEntry(const QString &name) + : ComplexTypeEntry(name, InterfaceType) + { + } + + static QString interfaceName(const QString &name) { + return "I" + name; + } + + ObjectTypeEntry *origin() const { return m_origin; } + void setOrigin(ObjectTypeEntry *origin) { m_origin = origin; } + + virtual bool isNativeIdBased() const { return true; } + virtual QString qualifiedCppName() const { + return ComplexTypeEntry::qualifiedCppName().right(ComplexTypeEntry::qualifiedCppName().length() - interfaceName("").length()); + } + +private: + ObjectTypeEntry *m_origin; +}; + + +class ObjectTypeEntry : public ComplexTypeEntry +{ +public: + ObjectTypeEntry(const QString &name) + : ComplexTypeEntry(name, ObjectType), m_interface(0) + { + } + + InterfaceTypeEntry *designatedInterface() const { return m_interface; } + void setDesignatedInterface(InterfaceTypeEntry *entry) { m_interface = entry; } + + virtual bool isNativeIdBased() const { return true; } + +private: + InterfaceTypeEntry *m_interface; +}; + +class CustomTypeEntry : public ComplexTypeEntry +{ +public: + CustomTypeEntry(const QString &name) : ComplexTypeEntry(name, CustomType) { } + + virtual void generateCppJavaToQt(QTextStream &s, + const AbstractMetaType *java_type, + const QString &env_name, + const QString &qt_name, + const QString &java_name) const = 0; + + virtual void generateCppQtToJava(QTextStream &s, + const AbstractMetaType *java_type, + const QString &env_name, + const QString &qt_name, + const QString &java_name) const = 0; +}; + +struct TypeRejection +{ + QString class_name; + QString function_name; + QString field_name; + QString enum_name; +}; + +class TypeDatabase +{ +public: + TypeDatabase(); + + static TypeDatabase *instance(); + + QList<Include> 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); + + TypeEntry *findType(const QString &name) const { + QList<TypeEntry *> entries = findTypes(name); + foreach (TypeEntry *entry, entries) { + if (entry != 0 && + (!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 &java_name); + + 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_flags_entries; } + FlagsTypeEntry *findFlagsType(const QString &name) const; + void addFlagsType(FlagsTypeEntry *fte) { m_flags_entries[fte->originalName()] = fte; } + + TemplateEntry *findTemplate(const QString &name) { return m_templates[name]; } + void addTemplate(TemplateEntry *t) { m_templates[t->name()] = t; } + + void setIncludeEclipseWarnings(bool on) { m_includeEclipseWarnings = on; } + bool includeEclipseWarnings() const { return m_includeEclipseWarnings; } + + 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() == 0) + 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_rebuild_classes = cls; } + + static QString globalNamespaceClassName(const TypeEntry *te); + QString filename() const { return "typesystem.txt"; } + + bool parseFile(const QString &filename, bool generate = true); + +private: + uint m_suppressWarnings : 1; + uint m_includeEclipseWarnings : 1; + uint m_reserved : 30; + + TypeEntryHash m_entries; + SingleTypeEntryHash m_flags_entries; + TemplateEntryHash m_templates; + QStringList m_suppressedWarnings; + + QList<TypeRejection> m_rejections; + QStringList m_rebuild_classes; +}; + +inline PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name) +{ + QList<TypeEntry *> entries = findTypes(name); + + foreach (TypeEntry *entry, entries) { + if (entry != 0 && 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 != 0 && entry->isComplex()) + return static_cast<ComplexTypeEntry *>(entry); + else + return 0; +} + +inline ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name) +{ + TypeEntry *entry = findType(name); + if (entry != 0 && entry->isObject()) + return static_cast<ObjectTypeEntry *>(entry); + else + return 0; +} + +inline NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name) +{ + TypeEntry *entry = findType(name); + if (entry != 0 && entry->isNamespace()) + return static_cast<NamespaceTypeEntry *>(entry); + else + return 0; +} + +QString fixCppTypeName(const QString &name); + +#endif // TYPESYSTEM_H