/* Copyright (C) 2009 Arno Rehn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TYPE_H #define TYPE_H #include #include #include #include #include "generator_export.h" class Class; class Typedef; class Enum; class GlobalVar; class Function; class Type; extern GENERATOR_EXPORT QHash classes; extern GENERATOR_EXPORT QHash typedefs; extern GENERATOR_EXPORT QHash enums; extern GENERATOR_EXPORT QHash functions; extern GENERATOR_EXPORT QHash globals; extern GENERATOR_EXPORT QHash types; class Method; class Field; enum Access { Access_public, Access_protected, Access_private }; class Class; class GENERATOR_EXPORT BasicTypeDeclaration { public: BasicTypeDeclaration() : m_access(Access_public) {} virtual ~BasicTypeDeclaration() {} virtual bool isValid() const { return !m_name.isEmpty(); } void setName(const QString& name) { m_name = name; } QString name() const { return m_name; } void setNameSpace(const QString& nspace) { m_nspace = nspace; } QString nameSpace() const { return m_nspace; } void setParent(Class* parent) { m_parent = parent; } Class* parent() const { return m_parent; } void setAccess(Access access) { m_access = access; } Access access() const { return m_access; } void setFileName(const QString& fileName) { m_file = fileName; } QString fileName() const { return m_file; } QString toString() const; protected: BasicTypeDeclaration(const QString& name, const QString& nspace = QString(), Class* parent = 0) : m_name(name), m_nspace(nspace), m_parent(parent) {} QString m_name; QString m_nspace; Class* m_parent; QString m_file; Access m_access; }; class GENERATOR_EXPORT Class : public BasicTypeDeclaration { public: enum Kind { Kind_Class, Kind_Struct, Kind_Union }; struct BaseClassSpecifier { Class *baseClass; Access access; bool isVirtual; }; Class(const QString& name = QString(), const QString nspace = QString(), Class* parent = 0, Kind kind = Kind_Class, bool isForward = true) : BasicTypeDeclaration(name, nspace, parent), m_kind(kind), m_forward(isForward), m_isNamespace(false), m_isTemplate(false) {} virtual ~Class() {} void setKind(Kind kind) { m_kind = kind; } Kind kind() const { return m_kind; } void setIsForwardDecl(bool forward) { m_forward = forward; } bool isForwardDecl() const { return m_forward; } void setIsNameSpace(bool isNamespace) { m_isNamespace = isNamespace; } bool isNameSpace() const { return m_isNamespace; } const QList& methods() const { return m_methods; } QList& methodsRef() { return m_methods; } void appendMethod(const Method& method) { m_methods.append(method); } const QList& fields() const { return m_fields; } QList& fieldsRef() { return m_fields; } void appendField(const Field& field) { m_fields.append(field); } const QList& baseClasses() const { return m_bases; } void appendBaseClass(const BaseClassSpecifier& baseClass) { m_bases.append(baseClass); } const QList& children() const { return m_children; } void appendChild(BasicTypeDeclaration* child) { m_children.append(child); } bool isTemplate() const { return m_isTemplate; } void setIsTemplate(bool isTemplate) { m_isTemplate = isTemplate; } private: Kind m_kind; bool m_forward; bool m_isNamespace; bool m_isTemplate; QList m_methods; QList m_fields; QList m_bases; QList m_children; }; class GENERATOR_EXPORT Typedef : public BasicTypeDeclaration { public: Typedef(Type* type = 0, const QString& name = QString(), const QString nspace = QString(), Class* parent = 0) : BasicTypeDeclaration(name, nspace, parent), m_type(type) {} virtual ~Typedef() {} virtual bool isValid() const { return (!m_name.isEmpty() && m_type); } void setType(Type* type) { m_type = type; } Type* type() const { return m_type; } Type resolve() const; private: Type* m_type; }; class EnumMember; class GENERATOR_EXPORT Enum : public BasicTypeDeclaration { public: Enum(const QString& name = QString(), const QString nspace = QString(), Class* parent = 0) : BasicTypeDeclaration(name, nspace, parent) {} virtual ~Enum() {} const QList& members() const { return m_members; } QList& membersRef() { return m_members; } void appendMember(const EnumMember& member) { m_members.append(member); } private: QList m_members; }; class GENERATOR_EXPORT Member { public: enum Flag { Virtual = 0x1, PureVirtual = 0x2, Static = 0x4, DynamicDispatch = 0x8, Explicit = 0x10, }; Q_DECLARE_FLAGS(Flags, Flag) Member(BasicTypeDeclaration* typeDecl = 0, const QString& name = QString(), Type* type = 0, Access access = Access_public) : m_typeDecl(typeDecl), m_name(name), m_type(type), m_access(access) {} virtual ~Member() {} bool isValid() const { return (!m_name.isEmpty() && m_type && m_typeDecl); } void setDeclaringType(Class* klass) { m_typeDecl = klass; } BasicTypeDeclaration* declaringType() const { return m_typeDecl; } void setName(const QString& name) { m_name = name; } QString name() const { return m_name; } void setType(Type* type) { m_type = type; } Type* type() const { return m_type; } void setAccess(Access access) { m_access = access; } Access access() const { return m_access; } void setFlag(Flag flag) { m_flags |= flag; } void removeFlag(Flag flag) { m_flags &= ~flag; } Flags flags() const { return m_flags; } virtual QString toString(bool withAccess = false, bool withClass = false) const; protected: BasicTypeDeclaration* m_typeDecl; QString m_name; Type* m_type; Access m_access; Flags m_flags; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Member::Flags) class GENERATOR_EXPORT EnumMember : public Member { public: EnumMember(Enum* e = 0, const QString& name = QString(), const QString& value = QString(), Type* type = 0) : Member(e, name, type), m_value(value) {} Enum* getEnum() const { return static_cast(m_typeDecl); } void setValue(const QString& value) { m_value = value; } QString value() const { return m_value; } QString toString() const; protected: QString m_value; }; class GENERATOR_EXPORT Parameter { public: Parameter(const QString& name = QString(), Type* type = 0, const QString& defaultValue = QString()) : m_name(name), m_type(type), m_defaultValue(defaultValue) {} virtual ~Parameter() {} bool isValid() const { return m_type; } void setName(const QString& name) { m_name = name; } QString name() const { return m_name; } void setType(Type* type) { m_type = type; } Type* type() const { return m_type; } bool isDefault() const { return !m_defaultValue.isEmpty(); } QString defaultValue() const { return m_defaultValue; } void setDefaultValue(const QString& value) { m_defaultValue = value; } QString toString() const; protected: QString m_name; Type* m_type; QString m_defaultValue; }; typedef QList ParameterList; class GENERATOR_EXPORT Method : public Member { public: Method(Class* klass = 0, const QString& name = QString(), Type* type = 0, Access access = Access_public, ParameterList params = ParameterList()) : Member(klass, name, type, access), m_params(params), m_isConstructor(false), m_isDestructor(false), m_isConst(false), m_is_accessor(false), m_hasExceptionSpec(false), m_isSignal(false), m_isSlot(false) {} virtual ~Method() {} Class* getClass() const { return static_cast(m_typeDecl); } const ParameterList& parameters() const { return m_params; } void appendParameter(const Parameter& param) { m_params.append(param); } void setParameterList(const ParameterList& params) { m_params = params; } void setIsConstructor(bool isCtor) { m_isConstructor = isCtor; } bool isConstructor() const { return m_isConstructor; } void setIsDestructor(bool isDtor) { m_isDestructor = isDtor; } bool isDestructor() const { return m_isDestructor; } void setIsConst(bool isConst) { m_isConst = isConst; } bool isConst() const { return m_isConst; } void setIsQPropertyAccessor(bool isAccessor) { m_is_accessor = isAccessor; } bool isQPropertyAccessor() const { return m_is_accessor; } void setIsSignal(bool isSignal) { m_isSignal = isSignal; } bool isSignal() const { return m_isSignal; } void setIsSlot(bool isSlot) { m_isSlot = isSlot; } bool isSlot() const { return m_isSlot; } // TODO: This actually doesn't belong here. Better add a dynamic property system to Member subclasses. // Then we can also get rid of the various method => foo maps in the 'Util' struct. const QStringList& remainingDefaultValues() const { return m_remainingValues; } void setRemainingDefaultValues(const QStringList& params) { m_remainingValues = params; } void setHasExceptionSpec(bool hasSpec) { m_hasExceptionSpec = hasSpec; } bool hasExceptionSpec() const { return m_hasExceptionSpec; } void appendExceptionType(const Type& type) { m_exceptionTypes.append(type); } const QList& exceptionTypes() const { return m_exceptionTypes; } virtual QString toString(bool withAccess = false, bool withClass = false, bool withInitializer = true) const; protected: ParameterList m_params; bool m_isConstructor; bool m_isDestructor; bool m_isConst; bool m_is_accessor; bool m_hasExceptionSpec; bool m_isSignal; bool m_isSlot; QList m_exceptionTypes; QStringList m_remainingValues; }; class GENERATOR_EXPORT Field : public Member { public: Field(Class* klass = 0, const QString& name = QString(), Type* type = 0, Access access = Access_public) : Member(klass, name, type, access) {} virtual ~Field() {} Class* getClass() const { return static_cast(m_typeDecl); } }; class GENERATOR_EXPORT GlobalVar { public: GlobalVar(const QString& name = QString(), const QString nspace = QString(), Type* type = 0) : m_name(name), m_nspace(nspace), m_type(type) {} virtual ~GlobalVar() {} bool isValid() const { return (!m_name.isEmpty() && m_type); } void setName(const QString& name) { m_name = name; } QString name() const { return m_name; } QString qualifiedName() const { QString ret = m_nspace; if (!ret.isEmpty()) ret += "::"; ret += m_name; return ret; } void setNameSpace(const QString& nspace) { m_nspace = nspace; } QString nameSpace() const { return m_nspace; } void setType(Type* type) { m_type = type; } Type* type() const { return m_type; } void setFileName(const QString& fileName) { m_file = fileName; } QString fileName() const { return m_file; } virtual QString toString() const; protected: QString m_name; QString m_nspace; Type* m_type; QString m_file; }; class GENERATOR_EXPORT Function : public GlobalVar { public: Function(const QString& name = QString(), const QString nspace = QString(), Type* type = 0, ParameterList params = ParameterList()) : GlobalVar(name, nspace, type), m_params(params) {} const ParameterList& parameters() const { return m_params; } void appendParameter(const Parameter& param) { m_params.append(param); } virtual QString toString() const; protected: ParameterList m_params; }; class GENERATOR_EXPORT Type { public: Type(Class* klass = 0, bool isConst = false, bool isVolatile = false, int pointerDepth = 0, bool isRef = false) : m_class(klass), m_typedef(0), m_enum(0), m_isConst(isConst), m_isVolatile(isVolatile), m_pointerDepth(pointerDepth), m_isRef(isRef), m_isIntegral(false), m_isFunctionPointer(false) {} Type(Typedef* tdef, bool isConst = false, bool isVolatile = false, int pointerDepth = 0, bool isRef = false) : m_class(0), m_typedef(tdef), m_enum(0), m_isConst(isConst), m_isVolatile(isVolatile), m_pointerDepth(pointerDepth), m_isRef(isRef), m_isIntegral(false), m_isFunctionPointer(false) {} Type(Enum* e, bool isConst = false, bool isVolatile = false, int pointerDepth = 0, bool isRef = false) : m_class(0), m_typedef(0), m_enum(e), m_isConst(isConst), m_isVolatile(isVolatile), m_pointerDepth(pointerDepth), m_isRef(isRef), m_isIntegral(false), m_isFunctionPointer(false) {} Type(const QString& name, bool isConst = false, bool isVolatile = false, int pointerDepth = 0, bool isRef = false) : m_class(0), m_typedef(0), m_enum(0), m_name(name), m_isConst(isConst), m_isVolatile(isVolatile), m_pointerDepth(pointerDepth), m_isRef(isRef), m_isIntegral(false), m_isFunctionPointer(false) {} void setClass(Class* klass) { m_class = klass; m_typedef = 0; m_enum = 0; } Class* getClass() const { return m_class; } void setTypedef(Typedef* tdef) { m_typedef = tdef; m_class = 0; m_enum = 0; } Typedef* getTypedef() const { return m_typedef; } void setEnum(Enum* e) { m_enum = e; m_class = 0; m_typedef = 0; } Enum* getEnum() const { return m_enum; } void setName(const QString& name) { m_name = name; } QString name() const { if (m_class) { return m_class->toString(); } else if (m_typedef) { return m_typedef->toString(); } else if (m_enum) { return m_enum->toString(); } else { return m_name; } } bool isValid() const { return (m_class || m_typedef || !m_name.isEmpty()); } void setIsConst(bool isConst) { m_isConst = isConst; } bool isConst() const { return m_isConst; } void setIsVolatile(bool isVolatile) { m_isVolatile = isVolatile; } bool isVolatile() const { return m_isVolatile; } void setPointerDepth(int depth) { m_pointerDepth = depth; } int pointerDepth() const { return m_pointerDepth; } void setIsConstPointer(int depth, bool isConst) { m_constPointer[depth] = isConst; } bool isConstPointer(int depth) const { return m_constPointer.value(depth, false); } void setIsRef(bool isRef) { m_isRef = isRef; } bool isRef() const { return m_isRef; } void setIsIntegral(bool isIntegral) { m_isIntegral = isIntegral; } bool isIntegral() const { return m_isIntegral; } void setArrayDimensions(int dim) { m_arrayLengths.resize(dim); } int arrayDimensions() const { return m_arrayLengths.size(); } bool isArray() const { return m_arrayLengths.size(); } void setArrayLength(int dim, int length) { m_arrayLengths[dim] = length; } int arrayLength(int dim) const { return m_arrayLengths[dim]; } const QList& templateArguments() const { return m_templateArgs; } void appendTemplateArgument(const Type& type) { m_templateArgs.append(type); } void setTemplateArguments(const QList& types) { m_templateArgs = types; } void setIsFunctionPointer(bool isPtr) { m_isFunctionPointer = isPtr; } bool isFunctionPointer() const { return m_isFunctionPointer; } const ParameterList& parameters() const { return m_params; } void appendParameter(const Parameter& param) { m_params.append(param); } QString toString(const QString& fnPtrName = QString()) const; // on windows, we can't reference 'types' here, because it's marked __declspec(dllexport) above. static Type* registerType(const Type& type) #ifndef Q_OS_WIN { QString typeString = type.toString(); QHash::iterator iter = types.insert(typeString, type); return &iter.value(); } #else ; #endif static const Type* Void; protected: Class* m_class; Typedef* m_typedef; Enum* m_enum; QString m_name; bool m_isConst, m_isVolatile; int m_pointerDepth; QHash m_constPointer; bool m_isRef; bool m_isIntegral; QList m_templateArgs; bool m_isFunctionPointer; ParameterList m_params; QVector m_arrayLengths; }; #endif // TYPE_H