/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef TYPESYSTEM_H #define TYPESYSTEM_H #include #include #include #include #include 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 IncludeList; typedef QMap 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, PyWrapperCode = 0x0100, PyWrapperDeclaration = 0x0200, PyWrapperOperators = 0x0400, PyShellDeclaration = 0x0800, PyInheritShellDeclaration = 0x1000, PyInitSource = 0x2000, PySetWrapperFunc = 0x4000, PyInheritShellConstructorCode = 0x8000, // 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 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 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 replaceRules; }; class CodeSnip : public CodeSnipAbstract { public: enum Position { Beginning, End, AfterThis, // QtScript PrototypeInitialization, ConstructorInitialization, Constructor }; 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 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 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 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) { } 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; QList argument_mods; }; typedef QList FunctionModificationList; struct FieldModification: public Modification { bool isReadable() const { return modifiers & Readable; } bool isWritable() const { return modifiers & Writable; } QString name; }; typedef QList 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; } // 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; } private: QString m_name; Type m_type; uint m_code_generation; CustomFunction m_customConstructor; CustomFunction m_customDestructor; bool m_preferred_conversion; }; typedef QHash > TypeEntryHash; typedef QHash SingleTypeEntryHash; class TypeSystemTypeEntry : public TypeEntry { public: TypeSystemTypeEntry(const QString &name) : TypeEntry(name, TypeSystemType) { }; QList 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 { QString pkg = javaPackage(); if (pkg.isEmpty()) return javaQualifier() + '.' + targetLangName(); return pkg + '.' + javaQualifier() + '.' + targetLangName(); } QString jniName() const; Include include() const { return m_include; } void setInclude(const Include &inc) { m_include = inc; } 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: Include m_include; QString m_package_name; QString m_qualifier; QString m_java_name; QString m_lower_bound; QString m_upper_bound; QStringList m_rejected_enums; QList 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(); } 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 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_createShell(false), m_createPromoter(false), m_type_flags(0) { 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 setCreateShell(bool on) { m_createShell = on; } bool shouldCreateShell() const { return m_createShell; } void setCreatePromoter(bool on) { m_createPromoter = on; } bool shouldCreatePromoter() const { return m_createPromoter; } 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; } private: IncludeList m_extra_includes; Include m_include; QHash 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; uint m_createShell : 1; uint m_createPromoter : 1; QString m_polymorphic_id_value; QString m_lookup_name; QString m_target_type; ExpensePolicy m_expense_policy; TypeFlags m_type_flags; }; 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 strings_Object; } QString javaPackage() const { return strings_java_lang; } 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 name + "Interface"; } 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().left(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) { } }; struct TypeRejection { QString class_name; QString function_name; QString field_name; QString enum_name; }; class TypeDatabase { public: TypeDatabase(); static TypeDatabase *instance(); QList 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 entries = findTypes(name); foreach (TypeEntry *entry, entries) { if (entry != 0 && (!entry->isPrimitive() || static_cast(entry)->preferredTargetLangType())) { return entry; } } return 0; } QList findTypes(const QString &name) const { return m_entries.value(name); } TypeEntryHash allEntries() { return m_entries; } SingleTypeEntryHash entries() { TypeEntryHash entries = allEntries(); SingleTypeEntryHash returned; QList 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 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: bool m_suppressWarnings; TypeEntryHash m_entries; SingleTypeEntryHash m_flags_entries; TemplateEntryHash m_templates; QStringList m_suppressedWarnings; QList m_rejections; QStringList m_rebuild_classes; }; inline PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name) { QList entries = findTypes(name); foreach (TypeEntry *entry, entries) { if (entry != 0 && entry->isPrimitive() && static_cast(entry)->preferredTargetLangType()) return static_cast(entry); } return 0; } inline ComplexTypeEntry *TypeDatabase::findComplexType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isComplex()) return static_cast(entry); else return 0; } inline ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isObject()) return static_cast(entry); else return 0; } inline NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isNamespace()) return static_cast(entry); else return 0; } QString fixCppTypeName(const QString &name); #endif // TYPESYSTEM_H